6

我是 JavaFX 2 的新手,对 ComboBox 和 ListView 的默认宽度感到困惑。我希望 ComboBox 更宽,以便文本“提示文本”完全可见,对于 ListView,我希望它更小,只有必要的宽度。代码和屏幕截图如下。

1) 我怎样才能实现 ComboBox 和 Listview 的大小都符合他们需要的宽度?

2)如何使两个控件具有相同的宽度(因此两个宽度中的最大值),是否可以在两者的宽度之间创建某种链接?我特别在为 FXML 寻找一个优雅的解决方案。

感谢您的任何提示!

@Override
public void start(Stage primaryStage) {
    ComboBox<String> comboBox = new ComboBox<String>();
    comboBox.setPromptText("the prompt text");
    ObservableList<String> items = FXCollections.observableArrayList();
    items.addAll("item 1", "item 2");
    comboBox.setItems(items);

    ListView<String> list = new ListView<String>();
    ObservableList<String> items2 =FXCollections.observableArrayList (
        "blue", "red");
    list.setItems(items2);

    VBox vBox = new VBox();
    vBox.getChildren().addAll(comboBox, list);

    primaryStage.setScene(new Scene(vBox, 200, 300));
    primaryStage.show();
}

在此处输入图像描述

4

2 回答 2

10

2)如何使两个控件具有相同的宽度(因此两个宽度中的最大值),是否可以在两者的宽度之间创建某种链接?我特别在为 FXML 寻找一个优雅的解决方案。

看起来,默认情况下,ListView 的 maxWidth 无界,但 ComboBox 的 maxWidth 被限制在其初始项目列表的宽度。要使这些控件具有相同的宽度,最简单的方法是将它们放在布局管理器中(就像您所做的那样 - VBox),然后松开组合框的 maxWidth。

在代码中,您可以这样做:

comboBox.setMaxWidth(Double.MAX_VALUE);

在 FXML 中,将以下属性定义添加到您的 ComboBox 元素中:

maxWidth="Infinity"

您可以使用 John Gray 的绑定解决方案,但我发现上面更优雅。

1) 我怎样才能实现 ComboBox 和 Listview 的大小都符合他们需要的宽度?

我想你在这里问的是如何让组合框和列表视图只占用他们需要的空间,而不是更多。这一点,我相信有点棘手,JavaFX 平台并没有为此提供很多支持。

下面是一些示例代码,用于将列表框的大小固定为所需的最小值。

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.*;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;

public class GridControlWidths extends Application {
  public static void main(String[] args) throws Exception { launch(args); }
  @Override public void start(Stage stage) {
    ComboBox<String> comboBox = new ComboBox<String>(FXCollections.observableArrayList("item 1", "item 2"));
    comboBox.setPromptText("the prompt text");

    ListView<String> list = new ListView<String>(FXCollections.observableArrayList ("blue", "red"));

    // layout the controls in a grid with appropriate constraints.
    GridPane grid = new GridPane();
    grid.add(comboBox, 0, 0);
    grid.add(list, 0, 1);
    grid.setVgrow(list, Priority.ALWAYS);  // make the list grow vertically as much as possible

    // unclamp the max width of the combo box.
    comboBox.setMaxWidth(Double.MAX_VALUE);

    // display the scene.
    stage.setScene(new Scene(grid, 200, 300));
    stage.show();

    // set the prefWidth of the listview based on the list cells (allowing 8 pixels for padding of the cells).
    double maxWidth = 0;
    for (Node n: list.lookupAll(".text")) {
      maxWidth = Math.max(maxWidth, n.getBoundsInParent().getWidth() + 8);
    }
    list.setPrefWidth(maxWidth);
  }
}

FWIW,我相信当您只有几个项目时,推荐的方法是将您的项目放在 VBox 中,而不是使用 ListView 或 ChoiceBox 而不是 ComboBox,这样您就不需要进行单元格内省和更新布局管理器和控件始终为您提供首选宽度。ListView 经过优化以处理虚拟化列表的情况,该列表可以包含数千个任意大小的项目,您可能无法轻松计算布局宽度,这就是为什么我认为它带有默认的控件大小调整行为而不是将其调整为可能具有的最小尺寸。通常在使用 ListView 时,您只需为 listView 选择一个合理的 prefWidth 并将其设置在 listView 上,而不是像上面的示例所示那样内省项目。

此外,您拥有的一些提示文本被剪裁的图像(对我来说)似乎是 JavaFX 中的一个错误,当 ComboBox 提示文本比 ComboBox 更宽时,它无法正确计算 ComboBox 控件的首选宽度项目文本。由于 ComboBox 目前是一个全新的控件,并且我在 JavaFX 控件的早期版本中看到了此类问题并且它们已得到修复,因此我希望 ComboBox 的首选宽度计算将很快得到合理的修复。

于 2012-05-07T20:48:00.920 回答
0

1)尝试设置minWidth(x), prefWidth(x), maxWidth(x)。这有帮助,但不确定这是一个好的决定。

2)使用void bind(ObservableValue<? extends Number> observable);绑定框架中的方法。它就是为这种情况而开发的。前任:

someProperty.bind(otherProperty);

您也可以使用双向绑定来链接它们。

于 2012-05-07T20:27:24.573 回答