当前位置: 首页 > 知识库问答 >
问题:

Javafx 组合框在选择后消失的项目

郝冥夜
2023-03-14

我创建了一个 (JavaFX) 组合框,我正在填充一个由 HBoxes 制成的可观察列表,以便我可以在每个列表单元格中显示带有一些文本的图像。

这显示得很好,除了每当您选择列表中的一个项目时,它都会消失。一旦您选择了每个项目,它根本不会呈现任何项目。(您仍然可以通过单击它们之前所在的空间来选择它们。

你知道我该怎么纠正吗?

我的部分代码显示如下:

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个答案

柯国安
2023-03-14

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

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

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

瞿文柏
2023-03-14

好的,我已经设法解决了这个问题,多亏了@James_D的帮助!

这是给任何像我一样,被Java留档中给出的例子稍微吓倒的人的。(尽管,我下面的描述可能更糟!!)

因此,我首先将我想要的布局中的HBox直接添加到ComboBox中...这是个坏主意!

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

1.创建一个新类来保存您的日期(图像和字符串),它将进入每个单元格。让getter/setter来执行此操作。我调用了我的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.这将在列表中显示您的图标和字符串,但您也需要显示在按钮中(组合框的灰色顶部选择器部分,也称为button>)。为此,我们需要添加以下代码:

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等的地方)显然不是一概而论的。你可以把它变得简单或复杂。

再次感谢您的帮助!我希望这个帖子能帮助别人!

 类似资料:
  • 所以,我有一个奇怪的问题,我从组合框列表中选择一个项目,为了填充第二个组合框,我必须首先从第一个组合框中再次选择单词,而不是从项目列表中,而是单词本身。只有这样,代码才会注册我选择了该项目。我拥有的代码是简单的$variable.SelectedItem。参见下面的代码; 我想做的就是从下拉列表中选择位置“医院”,然后第二个名为“$ComboBox_Printer”的组合框填充我服务器中的打印机名

  • 我有一个奇怪的问题。我在JavaFX中使用了一个ComboBox,其中每一项都是一个HBox,是一个图像和一个标签的组合。 是字符串的数组列表。只是一个

  • 我有一个带有2个ComboBox的应用程序,我想将用户的选择返回到一个变量中。我该怎么做?这是我的控制器类: 我需要使用这个变量来改变应用程序的工作方式。在“methode”组合框中,我想要一个包含大量文本字段的新窗口。例如,如果用户选择3,它将打开一个包含3个文本字段的新窗口,或者(如果可能,只需在组合框下方添加3个测试字段)谢谢

  • 问题内容: 我们正在使用Selenium WebDriver和JBehave在我们的Web应用程序上运行“集成”测试。我有一种方法,可以在表单输入中输入一个值。 但是,当我尝试使用它在下拉列表中选择一个项目时,它(毫无疑问)失败了 java.lang.UnsupportedOperationException:您只能设置作为输入元素的元素的值 如何在组合中选择一个值? 问题答案: 这是怎么做的:

  • 我在后台有< code>ViewModel(实现< code > INotifyPropertyChanged )和类< code>Category,它只有一个< code>string类型的属性。我的ComboBox SelectedItem绑定到类别的实例。当我更改instance的值时,SelectedItem没有更新,Combobox也没有更改。 编辑:代码 组合框: 物业: 我尝试的是:

  • 我需要在加载时选择组合框的第一个项目。 XAML: 我希望在打开窗口时在组合框中最初选择。 我使用< code>SelectedItem属性在所选项目发生更改时触发一个事件。