我正在构建一个应用程序,在某些时候我使用带有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点,我就无法在预期的位置编写我的字符串!
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
}
我得到的是以下图片
. 令我印象深刻的是,蓝点似乎并不完全位于父容器的左上角(我会说它应该更进一步) . 看起来在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 );
它按预期工作(蓝点位于左上角):
所以这应该与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 回答
Codename One中的组件位于其父Container的X / Y中,不会转换为位置 . 所以0,0位置将是
getX(), getY()
.你显然可以使用
translate
让0,0也适合你 .来自the Codename One Developer Guide Graphics section