首页 文章

在Codename one中的图形中的给定位置处写一个字符串

提问于
浏览
1

我正在构建一个应用程序,在某些时候我使用带有layeredLayout的表单 . 在这种形式中,我已经有2个标签堆叠在一起,我想在特定区域写一个字符串 .

第一个图像(最深的一个)是来自设备相机的图像,第一个图像位于第一个图像的顶部,是具有透明背景的png文件 . 它们都具有比屏幕分辨率更高的分辨率,这就是我使用以下代码显示它们的原因:

findPhotoBase3().getUnselectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT);
findDecoration3().getUnselectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT);
findPhotoBase3().getUnselectedStyle().setBgImage(montage.getBaseImage());
findDecoration3().getUnselectedStyle().setBgImage(montage.getdecorationImageSelected());

由于2个图像被缩放以适合屏幕尺寸,因此在横向模式下,两个图像都不覆盖整个宽度(由于保持原始图像比率,这是非常正常的) . 因此,堆叠图像的一部分上有空白列 .

我知道我的字符串应该从原始图像宽度(此处为装饰)的xx%和原始高度的yy%开始 . 因此,我首先需要知道(0,0)点的位置 .

因此,如果我向父表单添加一个新组件:

findDecoration3().getParent().add(new Component(){

      @Override
      public void paint(Graphics g) {
          g.drawString(".", 0 , 0 );
      }
}

然后在堆叠图像的左侧绘制点,并且比图像左上角略低一点 . 我已经计算了x和y偏移量,如下所示:

int originalImageWidth = findPhotoBase3().getUnselectedStyle().getBgImage().getWidth();
int originalImageHeight = findPhotoBase3().getUnselectedStyle().getBgImage().getHeight();
float ratioOriginal = (float) originalImageWidth / originalImageHeight;

// L'espace disponible dans le containeur parent
int availableWidth = findPhotoBase3().getParent().getWidth();
int availableHeight = findPhotoBase3().getParent().getHeight();

// Landscaped mode assumed
final int displayedImageWidth = (int) (ratioOriginal * availableHeight) ;
final int displayedImageHeight = availableHeight ;

// L'image débute à (coordonnées par rapport au container parent see chapter 9.10 of https://www.codenameone.com/files/developer-guide.pdf ) 
final int imageStartX0 = (availableWidth - displayedImageWidth) / 2;
// L'image prend toute la hauteur, donc elle commence à 0 dans le container parent
final int imageStartY0 = 0;

但是,显示的0点(imageStartX / Y0)不会位于正确的位置(即完全位于photoBase图像的左上角),但在两个方向上都有正偏移 .

如前所示绘制了这一点:

g.drawString(".", imageStartX0 , imageStartY0 );

这是我得到的结果(私人照片使用,因此只显示了部分内容):

Upper left corner of the screen where the small blue point is the one I try to set on the image corner

请注意,在图片上会出现带圆圈的复选按钮 . 此按钮位于图像顶部的容器上 . 我没有提到它,以尽可能清楚地表达我的问题 .

因此,如果我无法获得正确的0点,我就无法在预期的位置编写我的字符串!

EDIT 1

所以我尝试应用Shai给出的建议,并在图像区域周围绘制一个矩形,如下所示:

@Override
public void paint(Graphics g) {

    int color = 0xFF0000;
    g.setColor(color);
    g.drawRect(imageStartX0 + getX(), imageStartY0 + getY(), displayedImageWidth, displayedImageHeight); // This red rectangle is expected to be around the image just on its border

    color = 0x0000ff;
    g.setColor(color);
    g.drawString(".", getX() ,getY() ); // This blue point is expected to be on the upper left corner of the parent container

}

我得到的是以下图片
Result after using getX and getY methods
. 令我印象深刻的是,蓝点似乎并不完全位于父容器的左上角(我会说它应该更进一步) . 看起来在Y轴上存在导致该偏移的平移 . 但是应用以下内容没有任何区别:

g.drawString(".", getX() - g.getTranslateX() ,getY() - g.getTranslateY() );

让我感到震惊的是,图像从蓝点开始"above"(北方向),预计它位于容器_2588028的容器上? =>参见编辑2(它确实没有从上面开始) .

另一方面,似乎我对displayedImage尺寸的计算有缺陷,因为矩形比图像窄 . 因此,我必须以更清洁的方式计算它 . =>请参见编辑2(计算正常,但看起来像父容器的维度必须计算 inside paint方法) .

EDIT 2

再次阅读Shai的回答我试图绘制一个矩形(而不是写一个点字符):

g.fillRect(getX() - g.getTranslateX(), getY() - g.getTranslateY(), 5, 5);
g.drawRect(getX() - g.getTranslateX() ,getY() - g.getTranslateY(), 5, 5 );

它按预期工作(蓝点位于左上角):

Get parent container dimensions inside paint method

所以这应该与drawString的JavaDoc有关

字体是从顶部位置而不是基线绘制的 .

它解释了为什么这一点不在预期的位置(我的坏!) .

总而言之,虽然我不清楚,但我可以通过在paint方法中移动部分代码(即关于父容器尺寸的部分)而不是外部来获得预期的位置 . 所以我的绘画方法现在看起来像:

@Override
public void paint(Graphics g) {
    // L'espace disponible dans le containeur parent
    // CAUTION : This has to be done in the paint method not outside
    int availableWidth = getWidth();
    int availableHeight = getHeight();

    // On fait l'hypothèse du mode paysage
    int displayedImageWidth = (int) (ratioOriginal * availableHeight) ;
    int displayedImageHeight = availableHeight ;

    // On récupère les coordonnées de l'image
    // L'image débute à (coordonnées par rapport au container parent) 
    int imageStartX0 = (availableWidth - displayedImageWidth) / 2;
    // L'image prend toute la hauteur, donc elle commence à 0 dans le container parent
    int imageStartY0 = 0;


    int colorNom = 0xFF0000;
    g.setColor(colorNom);
    g.drawRect(imageStartX0 + getX(), imageStartY0 + getY(), displayedImageWidth, displayedImageHeight);

    colorNom = 0x0000ff;
    g.setColor(colorNom);   
    g.drawString(nom, syntheStartX0 , syntheStartY0 - g.getTranslateY());
    g.fillRect(getX() - g.getTranslateX(), getY() - g.getTranslateY(), 5, 5);
    g.drawRect(getX() - g.getTranslateX() ,getY() - g.getTranslateY(), 5, 5 );

非常感谢任何可以告诉我为什么我没有得到预期结果(即正好在左上角的点)的人?

问候

1 回答

  • 1

    Codename One中的组件位于其父Container的X / Y中,不会转换为位置 . 所以0,0位置将是 getX(), getY() .

    你显然可以使用 translate 让0,0也适合你 .

    传递给drawRect(x,y,w,h)方法的x和y坐标是相对于组件父级的原点 - 而不是组件本身..它的父级 . 这就是我们x位置是getX()5而不仅仅是5的原因 .

    来自the Codename One Developer Guide Graphics section

相关问题