我正在构建一个应用程序,在某些时候我使用带有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 );
这是我得到的结果(使用私人照片,因此只显示其中的一部分):
请注意,在图片上会出现带圆圈的复选按钮。此按钮位于图像顶部的容器上。我没有提及它以尽可能清楚地表达我的问题。
因此,如果我无法正确获得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
}
我得到的是以下图片。令我印象深刻的是,蓝点似乎并不完全位于父容器的左上角(我会说它应该更进一步)。看起来在Y轴上存在导致该偏移的平移。但是应用以下内容 not 没有任何区别:
g.drawString(".", getX() - g.getTranslateX() ,getY() - g.getTranslateY() );
让我感到震惊的是,图像从蓝点开始“向上”(北方向),该蓝点预计位于容器的左上角。孩子可能会在父母的容器外涂漆吗? =>请参阅编辑2(确实没有从上面开始)。
另一方面,似乎我对displayedImage尺寸的计算有缺陷,因为矩形比图像窄。因此,我必须以更清洁的方式计算它。 =>请参阅编辑2(计算正常,但看起来父容器的尺寸必须计算内部绘制方法)。
编辑2
再次阅读Shai的回答我试图绘制一个矩形(而不是写一个点字符):
g.fillRect(getX() - g.getTranslateX(), getY() - g.getTranslateY(), 5, 5);
g.drawRect(getX() - g.getTranslateX() ,getY() - g.getTranslateY(), 5, 5 );
它按预期工作(蓝点位于左上角):
所以这应该与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 );
非常感谢任何能告诉我为什么我没有得到预期结果的人(即正好在左上角的那一点)?
问候
答案 0 :(得分:1)
Codename One中的组件位于其父Container的X / Y中,并且不会转换为位置。所以0,0位置为getX(), getY()
。
你显然可以使用translate
让0,0也适合你。
传递给drawRect(x,y,w,h)的x和y坐标 方法是相对于组件的父级的来源 - 而不是 组件本身..它的父级。这就是我们x位置的原因 getX()+ 5而不仅仅是5。