Javafx ComboBox disappears after selection

I created a (JavaFX) combobox that I fill with an observable list from HBoxes so that I can display an image with some text in each list.

This shows well, except that whenever you select one of the items in the list, it disappears. Once you have selected each item, it will not display any items. (You can still select them by clicking in the space where they were previously.

Do you know how I can fix this please?

enter image description hereenter image description here

Part of my code is displayed below:

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);


}

      

Thanks in advance for your help!

+3


source to share


2 answers


This is the example provided in the documentation under "Inserting Nodes in ComboBox List" section.

The list of items in the combo box should represent data, not a UI component used to display the data. The problem is that HBox

it cannot appear twice in the scene graph, so it cannot appear both in the "selected cell" and as a cell in the dropdown.



Instead, create a class that represents the data you display in ComboBox

and use a factory cell to specify ComboBox

how to display that data. Don't forget to also set the button cell (the cell used for the selected item).

+3


source


Ok so I managed to get it done, thanks to @James_D very kind help!

This is for those who, like me, were a bit discouraged by the example provided in the Java documentation. (Though, my description below is probably worse!)


So I started by adding HBox

that was in the layout I wanted right in ComboBox

... which is a bad idea !

So, before you delete whatever you've done, save HBox

somewhere and follow these steps:

1 . Create a new class to store the date (image and string) to be displayed in each cell. Make getters / setters to do this. I named mine IconTextCell

.

2 . Add the following code to the class where yours is located 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
                }
           }
      };
  }
});

      

You will see that the main content is very similar to what I have already produced, so no code is lost. Just replace "T" with your own class to represent the cell.

3 . This will display your icon and string in the list, but you will also need to display on the button (gray selector part ComboBox

, otherwise button

). Do this, we need to add the following code:

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());

      

... and how I did it. Hope this helps - please compare this to my original post. The actual content (where I am creating the HBox, etc.) is obviously not generic. You can make it as simple or as complex as you want.

Thanks again for your help! Hope this post helps others!

+3


source







All Articles