在代号一的绘图中的给定位置写入字符串
Writing a string at a given position in a drawing in Codename one
我正在构建一个应用程序,有时我会使用带有分层布局的表单。在这个表格中,我已经有 2 个标签堆叠在一起,我想在特定区域写一个字符串。
第一个图像(最深的图像)是来自设备相机的图像,第一个图像之上的第二个图像是具有 transparent 背景的 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) 点所在的位置。
因此,如果我向 parent 表单添加一个新组件:
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 );
这是我得到的结果(使用了私人照片,所以只显示了一部分):
请注意,图片上出现了一个带圆圈的复选按钮。此按钮位于图像顶部的容器上。我没有提到它是为了让我的问题尽可能清楚。
因此,如果我无法获得正确的 0 点,我将无法在预期的位置写入我的字符串!
编辑 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
}
得到的是下面的图片。令我印象深刻的是,蓝点似乎并不完全位于 parent 容器的左上角(我想应该更靠上一点)。看起来 Y-axis 上有一个翻译导致了这个偏移。但是应用以下内容 not 有什么不同:
g.drawString(".", getX() - g.getTranslateX() ,getY() - g.getTranslateY() );
同样让我印象深刻的是,图像从预计位于容器左上角的蓝点开始 "above"(北方向)。那么 child 是否有可能在其 parent 的容器之外绘制? => 参见编辑 2(它确实不是从上面开始的)。
另一方面,我对显示图像尺寸的计算似乎存在缺陷,因为矩形比图像窄。因此,我将不得不以更简洁的方式计算它。 => 请参阅编辑 2(计算正常,但看起来 parent 容器的尺寸必须计算 inside 绘制方法)。
编辑 2
再次阅读 Shai 的回答我尝试画一个矩形(而不是写一个点字符):
g.fillRect(getX() - g.getTranslateX(), getY() - g.getTranslateY(), 5, 5);
g.drawRect(getX() - g.getTranslateX() ,getY() - g.getTranslateY(), 5, 5 );
它按预期工作(蓝点在左上角):
所以这应该与 drawString 的 JavaDoc 有关
The font is drawn from the top position and not the baseline.
它解释了为什么点不在预期位置(我的错!)。
总而言之,虽然我不清楚,但我可以通过移动部分代码(即关于 parent 容器尺寸的部分)inside 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 );
非常感谢任何能告诉我为什么我没有得到预期结果(即恰好在左上角的点)的人?
此致
Codename One 中的组件位于其父 Container 的 X/Y 中,未转换为位置。所以 0, 0 位置将是 getX(), getY()
.
您显然可以使用 translate
让 0,0 也为您工作。
The x and y coordinates that are passed to the drawRect(x,y,w,h)
method are relative to the component’s parent’s origin — not the
component itself .. its parent. This is why we the x position is
getX()+5 and not just 5.
我正在构建一个应用程序,有时我会使用带有分层布局的表单。在这个表格中,我已经有 2 个标签堆叠在一起,我想在特定区域写一个字符串。
第一个图像(最深的图像)是来自设备相机的图像,第一个图像之上的第二个图像是具有 transparent 背景的 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) 点所在的位置。
因此,如果我向 parent 表单添加一个新组件:
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 );
这是我得到的结果(使用了私人照片,所以只显示了一部分):
请注意,图片上出现了一个带圆圈的复选按钮。此按钮位于图像顶部的容器上。我没有提到它是为了让我的问题尽可能清楚。
因此,如果我无法获得正确的 0 点,我将无法在预期的位置写入我的字符串!
编辑 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
}
得到的是下面的图片
g.drawString(".", getX() - g.getTranslateX() ,getY() - g.getTranslateY() );
同样让我印象深刻的是,图像从预计位于容器左上角的蓝点开始 "above"(北方向)。那么 child 是否有可能在其 parent 的容器之外绘制? => 参见编辑 2(它确实不是从上面开始的)。
另一方面,我对显示图像尺寸的计算似乎存在缺陷,因为矩形比图像窄。因此,我将不得不以更简洁的方式计算它。 => 请参阅编辑 2(计算正常,但看起来 parent 容器的尺寸必须计算 inside 绘制方法)。
编辑 2
再次阅读 Shai 的回答我尝试画一个矩形(而不是写一个点字符):
g.fillRect(getX() - g.getTranslateX(), getY() - g.getTranslateY(), 5, 5);
g.drawRect(getX() - g.getTranslateX() ,getY() - g.getTranslateY(), 5, 5 );
它按预期工作(蓝点在左上角):
所以这应该与 drawString 的 JavaDoc 有关
The font is drawn from the top position and not the baseline.
它解释了为什么点不在预期位置(我的错!)。
总而言之,虽然我不清楚,但我可以通过移动部分代码(即关于 parent 容器尺寸的部分)inside 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 );
非常感谢任何能告诉我为什么我没有得到预期结果(即恰好在左上角的点)的人?
此致
Codename One 中的组件位于其父 Container 的 X/Y 中,未转换为位置。所以 0, 0 位置将是 getX(), getY()
.
您显然可以使用 translate
让 0,0 也为您工作。
The x and y coordinates that are passed to the drawRect(x,y,w,h) method are relative to the component’s parent’s origin — not the component itself .. its parent. This is why we the x position is getX()+5 and not just 5.