JavaFx HBox 删除间距

JavaFx HBox remove spacing

我目前有什么

我试图用 javaFx 实现多行 TextInput,它能够显示表情符号,我使用了 FlowPanes 的 VBox(每行一个 FlowPane),将行按空格拆分为单词,单词显示在 HBox 中,HBox 将包含用于文本的 Text 节点和用于 Emojis 的 ImageView,当前设置如下图所述

以下屏幕截图显示了我目前的情况


问题

我面临的问题是复杂的词,当多个表情符号(ImageViews)显示在一个 HBox 中时,Carret 位置估计对于每个图像都会有半个像素的错误(因为我假设HBox 的宽度将等于其子项的 fitWidths 的总和?,但事实并非如此),就好像 HBox 有某种间距,尽管间距 属性 设置为 0.

如果同时显示很多表情,效果会更差,如下截图所示

它也不是 Padding 或 Borders,如有任何帮助,我们将不胜感激,对于冗长无聊的解释,我深表歉意,我不得不添加它,以防有人帮助我解决问题。

经过大量调查,原来是我将子ImageViews的fitWidth设置为十进制值(非整数)引起的,ImageView接受double作为fitWidth但它似乎被四舍五入为渲染时最接近的更大的整数,调用 getFitWidth() 方法仍然会 return 您设置的双精度,但父级将使用四舍五入的值对它们进行布局(因为我猜物理像素不能显示半个像素对吧?)。

因此,在 HBox 父级上调用 getWidth() 会 return 一个比子 ImageViews 的 fitWidths 的总和更大的值 ONLY IF ImageViews 的 fitWidths是非整数。

这可以使用以下代码进行测试

ArrayList<Image> images = new ArrayList<Image>();

//Fill the list with N images

StackPane root = new StackPane();
root.setPadding(new Insets(15));

HBox parent = new HBox(0);
for (Image image : images) {
    ImageView view = new ImageView(image);
    view.setPreserveRatio(true);
    view.setFitWidth(fitWidth);
    parent.getChildren().add(view);
}

root.getChildren().add(parent);

ps.setOnShown(event -> {
    double sum = 0;
    for (Node node : parent.getChildren()) {
        sum += ((ImageView) node).getFitWidth();
    }
    System.out.println("fitWidth : " + fitWidth);
    System.out.println("Sum of fitWidths of child ImageViews : " + sum);
    System.out.println("Width of the parent HBox : " + parent.getWidth());
});

ps.setScene(new Scene(root));
ps.show();

运行 fitWidth 为 31.5 和 32.0 的结果如下

fitWidth : 31.5
Sum of fitWidths of child ImageViews : 315.0
Width of the parent HBox : 320.0

fitWidth : 32.0
Sum of fitWidths of child ImageViews : 320.0
Width of the parent HBox : 320.0

请注意,父级的宽度相同但 fitWidths 的总和不同,因为该值在布局或渲染期间的某个点被四舍五入,这导致了问题中描述的问题。

解决这个问题确实因上下文而异,我在设置 fitWidth 时通过将 double 转换为 int 来解决它,但这实际上取决于开发人员。