5

The drop down list of my ComboBox expands to the size of the largest element entered in it. However I want it to be a fixed size.

---------------------
| Small Combobox | V |
--------------------------------------------
| "Long item 1"                              |
--------------------------------------------
| "Long item 2"                              |
 --------------------------------------------
| "Long item 3"                              |
 --------------------------------------------
Abra
  • 19,142
  • 7
  • 29
  • 41
vinay
  • 1,121
  • 2
  • 12
  • 17

4 Answers4

15

Use CSS

/** file: combo-size.css */

/** Size the combo-box button. */
.combo-box {
    -fx-pref-width: 100;
}

/** Size the combo-box drop down list. */
.combo-box-popup > .list-view {
    -fx-pref-width: 100;
}

Note: I tested this sample only on Java 8 and I believe the -fx-*-width and -fx-*-height css attributes may be new for JavaFX 8.

Sample Usage

In this sample, both the combo box button and the drop down list have been sized to the same preferred width (of 100 pixels).

enter image description here

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class SizedComboBoxSampleWithCss extends Application {
    public static void main(String[] args) { launch(args); }

    @Override public void start(Stage stage) {
        final ComboBox<String> combo = new ComboBox<>();

        combo.setValue(Font.getDefault().getFamily());
        combo.getItems().setAll(Font.getFamilies());
        combo.getStylesheets().add(
                getClass().getResource(
                        "combo-size.css"
                ).toExternalForm()
        );

        StackPane layout = new StackPane(combo);
        layout.setPadding(new Insets(10));

        stage.setScene(new Scene(layout));
        stage.show();
    }
}
jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • Nice! The strange thing about it: Doesn't work with `-fx-max-width` and neither does it work without setting the preferred width on the combo-box itself. – isnot2bad Feb 15 '18 at 10:49
4

The solution (of jewelsea) wasn't working the first time for me, so here is my solution if someone needs a work-around. I just provide a custom cell factory, and I get access to the parent ListView and set the maxWidth in it.

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

        @Override
        public ListCell<T> call(ListView<T> param) {
            ListCell cell = new ListCell<T>() {
                @Override
                public void updateItem(T item, boolean empty) {
                    super.updateItem(item, empty);

                    getListView().setMaxWidth(LIST_VIEW_MAX_HEIGHT);
                    if (!empty) {
                        setText(converter.toString(item));
                    } else {
                        setText(null);
                    }
                }
            };
            return cell;
        }
    });
Maxoudela
  • 2,091
  • 3
  • 15
  • 23
0
combo.setCellFactory(new Callback<ListView<T>, ListCell<T>>() {

    @Override
    public ListCell<T> call(ListView<T> param) {
        ListCell cell = new ListCell<T>() {
            @Override
            public void updateItem(T item, boolean empty) {
                if (!empty) {
                    Label label = new Label(converter.toString(item));
                    label.setMaxWidth(comboBox.getWidth());
                    label.setWrapText(true);
                    setGraphic(label);
                    setText(null);

                } else {
                    setGraphic(null);
                    setText(null);
                }
            }
        };
        return cell;
    }
});

The other answers here didn't work for me. This is a dirty way of doing it but it worked.

EDIT: or you can getChildren() and if(node instanceof Label){} and edit the label from there rather than setting a new one every time in the graphic of the same label

0

I had problem that combobox size doesn't adjust to updating list, only for the first one. So for me basically works this solution

                new Callback<ListView<String>, ListCell<String>>() {
                    @Override public ListCell<String> call(ListView<String> param) {
                        final ListCell<String> cell = new ListCell<String>() {
                            {
                                super.setPrefWidth(100);
                            }
                            @Override public void updateItem(String item,
                                                             boolean empty) {
                                super.updateItem(item, empty);
                                if (item != null) {
                                    setText(item);

                                }
                                else {
                                    setText(null);
                                }
                            }
                        };
                        return cell;
                    }

                });