Javafx ComboBox 选择后选项消失

5
我创建了一个(JavaFX)combobox,我正在使用从HBoxes制作的observable list填充它,以便在每个列表单元格中显示带有一些文本的图像。这样显示得很好,但是每当您选择列表中的某个项目时,它都会消失。一旦您选择了每个项目,它将不再呈现任何项目。(您仍然可以通过单击先前存在它们的空间来选择它们。)
请问您知道如何纠正这个问题吗?
下面显示了我的代码的一部分: enter image description here enter image description here
public class IconListComboBox {

Group listRoot = new Group();
VBox mainVBox = new VBox();
ComboBox selectionBox = new ComboBox();
List<HBox> list = new ArrayList<HBox>();
ListView<HBox> listView = new ListView<HBox>();
ObservableList<HBox> observableList;



public IconListComboBox(int dimensionX, int dimensionY, ArrayList<String> names, ArrayList<ImageView> icons)
{

    //VBox.setVgrow(list, Priority.ALWAYS);
    selectionBox.setPrefWidth(dimensionY);
    selectionBox.setPrefHeight(40);

    for(int i = 0; i < names.size(); i++)
    {
        HBox cell = new HBox();
        Label name = new Label(names.get(i));
        Label icon = new Label();
        icon.setGraphic(icons.get(i));
        name.setAlignment(Pos.CENTER_RIGHT);
        icon.setAlignment(Pos.CENTER_LEFT);
        icon.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(icon, Priority.ALWAYS);
        cell.getChildren().add(icon);
        cell.getChildren().add(name);
        list.add(cell);


    }

    observableList = FXCollections.observableList(list);
    listView.setItems(observableList);

    listView.setPrefWidth(dimensionX);
    selectionBox.setMaxWidth(dimensionX);
    listView.setMaxWidth(dimensionX);

    selectionBox.setItems(observableList);

    mainVBox.getChildren().add(selectionBox);
    mainVBox.getChildren().add(listRoot);
    //mainVBox.getChildren().add(listView);
    //listRoot.getChildren().add(listView);


}

非常感谢您提前的协助!

2个回答

5

好的,我已经成功解决了这个问题,感谢@James_D非常友善的帮助!

这是为那些像我一样被Java文档中给出的示例吓到了的人而准备的。(虽然,我的描述可能更糟糕!!)


所以,我首先添加了一个HBoxComboBox中想要的布局中......这是一个不好的想法

因此,在删除您所做的所有内容之前,请将HBox保存在某个地方,并执行以下操作:

1.创建一个新类来保存您的日期(图片和字符串),它们将进入每个单元格。 创建getters/setters来完成此操作。 我称之为IconTextCell

2.将以下代码添加到您的ComboBox所在的类中:

yourComboBox.setCellFactory(new Callback<ListView<T>, ListCell<T>>() {

    @Override public ListCell<T> call(ListView<T> p) {
        return new ListCell<T>() {
            Label name = new Label();
            Label icon = new Label();
            private final HBox cell;
            { 
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY); 
                cell = new HBox();

                //HERE, ADD YOUR PRE-MADE HBOX CODE

                name.setAlignment(Pos.CENTER_RIGHT);
                icon.setAlignment(Pos.CENTER_LEFT);
                icon.setMaxWidth(Double.MAX_VALUE);
                HBox.setHgrow(icon, Priority.ALWAYS);
                cell.getChildren().add(icon);
                cell.getChildren().add(name);
            }

            @Override protected void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setGraphic(null);
                } else {
                    name.setText(item.getLabel());
                    icon.setGraphic(item.getIcon());
                    setGraphic(cell);
                    //HERE IS WHERE YOU GET THE LABEL AND NAME
                }
           }
      };
  }
});

你会发现主要内容与我已经制作的非常相似,因此不会丢失任何代码。只需将“T”替换为您自己表示单元格的类即可。 3. 这将在列表中显示您的图标和字符串,但您还需要在按钮(combobox的灰色顶部选择器部分,也称为按钮)中显示。为此,我们需要添加以下代码:
class IconTextCellClass extends ListCell<T> {
    @Override
    protected void updateItem(T item, boolean empty) {
        super.updateItem(item, empty);
        if (item != null) {
            setText(item.getLabel());
        }
    }
};

selectionBox.setButtonCell(new IconTextCellClass());

...这就是我做到的方法。希望这能对你有所帮助 - 请将其与我的原始帖子进行比较。实际内容(我创建HBox等)显然不是通用的。您可以根据需要使其简单或复杂。

再次感谢您的帮助!希望这篇文章对其他人有所帮助!


4

这正是文档中“关于向ComboBox项目列表中插入节点的警告”所引用的示例。

组合框中的项目列表应表示数据,而不是用于显示数据的UI组件。问题在于HBox不能在场景图中出现两次:因此它既不能出现在“选定单元格”中,也不能作为下拉列表中的单元格。

相反,创建一个代表您在ComboBox中显示的数据的类,并使用单元格工厂来指示ComboBox如何显示这些数据。确保还设置了按钮单元格(用于选定项的单元格)。


谢谢@James_D,这确实有帮助。我已经在文档中看到过这个,但是不太理解.setCellFactory如何工作,现在仍然不太明白。我需要进一步研究一下。我能否做类似于:.setCellFactory(new Callback<ListView<HBox>, ListCell<HBox>>() ...? - Ben Hayward
或多或少,但您需要将 ComboBox 的类型从 HBox 更改为表示数据的类。因此,您需要一个 Callback<ListView<T>, ListCell<T>>,其中 T 是表示数据的类。(在文档示例中,表示数据的类是 Color。这里需要更复杂的东西,封装文本和图像。) - James_D
非常感谢 @James_D。我已经让它工作到需要“设置按钮单元格”的程度了。我应该如何做才能将其设置为与下拉列表中看到的完全相同的布局?他们给出的示例是 .setButtonCell(cellFactory.call(null)); 但我需要把它放在哪里呢?cellFactory不是<Color>示例中所给的变量。.. 我需要将其从null更改吗? - Ben Hayward

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