JavaFX - 如何使ComboBox水平自适应宽度?

12


我在使用JavaFX(8)、HBox、ComboBox和HGrow时遇到了问题。 HGrow在与ComboBox结合使用时无法正常工作。

(提示:如果使用TextField而不是ComboBox,则可以按预期工作!)

这是我的FXML代码:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<VBox prefHeight="117.0" prefWidth="285.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.test.TestController">
  <children>
     <HBox prefHeight="105.0" prefWidth="196.0" VBox.vgrow="ALWAYS">
     <children>
        <ComboBox fx:id="fxCboTest" prefHeight="25.0" prefWidth="62.0" HBox.hgrow="ALWAYS" />
     </children>
    </HBox>
  </children>
</VBox>

这段代码将会产生以下结果:

输入图像描述

我也尝试了下面的代码(但没有成功,这段代码不会有任何作用):

HBox.setHgrow(uiController.fxCboTest, Priority.ALWAYS);

有没有人知道如何使ComboBox水平伸展?

3个回答

32
这是对我自己问题的回答。
经过一些测试,我发现将最大宽度设置为MAX_VALUE时,它起作用:
输入图像描述的地方
这将导致从场景构建器生成以下代码/xml:
...
<children>
   <ComboBox maxWidth="1.7976931348623157E308" prefWidth="150.0" HBox.hgrow="ALWAYS" />
</children>
...

其中,1.7976931348623157E308 看起来像 Double.MAX_VALUE。

这也适用于 HBox 中的多个控件。
enter image description here

在我看来,这不是很一致的。
我仍然不明白为什么 HGrow 不适用于 ComboBox。


hgrow不会覆盖可调整大小节点的最大宽度,默认情况下设置为首选大小。关于这个问题在tutorial中提供了一些信息,也可以在Parleys的优秀演示(需要注册)中找到更多资料。 - James_D
1
那么,为什么在XML中只替换ComboBox为TextField时它能够工作? - Ben
4
进一步研究了默认设置。两者的 maxWidth 默认值都为特殊值 Region.COMPUTED_SIZE,这将导致调用 computeMaxWidth(...)。对于控件,这会将任务委托给皮肤实现。深入源代码,ComboBoxBaseSkin 通过返回首选宽度来解决此问题;TextFieldSkin 只是继承了默认的 SkinBase 实现,返回 Double.MAX_VALUE。因此,默认情况下,组合框仅限于其首选大小;文本字段则允许无限增长。底线是它们具有不同的默认值。 - James_D
在JavaFX 8中,您可以使用maxWidth="Infinity",这在fxml中看起来更好。 - tomorrow

2
这是一个hack,但应该能够解决问题。在控制器的初始化方法中,定义一个绑定(binding)。
@Override
public void initialize(URL location, ResourceBundle resources) {
    fxCboTest.prefWidthProperty().bind(hbox.widthProperty());
}

谢谢您的建议,但是这段代码可能在 hbox 包含多个控件时无法正常工作(不在我的代码示例中,因为我希望尽可能保持简单)。我想避免自己进行过多的计算。 - Ben
问题从未提到您想在HBox中添加多个子元素。 - ItachiUchiha
你是对的,这就是为什么我在你的答案下添加了一条评论,解释为什么你的解决方案可能不能处理多个控件。我并没有说你的解决方案完全没有帮助。 - Ben

2

我遇到了同样的问题,但是我没有使用Scene Builder
所以,根据Ben的答案,我的解决方法如下:

ComboBox comboBox = new ComboBox(...);
...
comboBox.setMaxWidth(Double.MAX_VALUE);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接