javafxcomboboxtext-alignment

Custom combobox, centered text in JavaFX


I want to centre align the text in a combobox button cell and make it a default behaviour. I already know how to do that when a combobox Object has been created. How can i implement that method inside of a derived class of combobox ?

box.setButtonCell(new ListCell<String>() {
    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        if (item != null) {
            setText(item);
            setAlignment(Pos.CENTER_RIGHT);
            Insets old = getPadding();
            setPadding(new Insets(old.getTop(), 0, old.getBottom(), 0));
        }
    }
});

Solution

  • Of course you could move the code (with box replaced with this) to the constructor of your class (or put it in a initializer block).

    But why create a subclass when CSS easily allows you to do this:

    Add the following style sheet to the scene

    .combo-box>.list-cell {
        -fx-alignment: center;
    }
    

    If you want to be able to change this behaviour for individual ComboBoxes, you just need add a way to tell centered ComboBoxes apart from others with a css selector, e.g. a class

    java code

    comboBox.getStyleClass().add("center-aligned");
    

    CSS

    .combo-box.center-aligned>.list-cell {
        -fx-alignment: center;
    }
    

    Using a pseudoclass would allow you to switch the behavour on and of more easily though. The following code center aligns every item at even indices:

    @Override
    public void start(Stage primaryStage) {
        ComboBox<String> combo = new ComboBox<>();
    
        PseudoClass centerAligned = PseudoClass.getPseudoClass("center-aligned");
        combo.pseudoClassStateChanged(centerAligned, true);
        combo.getSelectionModel().selectedIndexProperty().addListener((o, oldValue, newValue)
                -> combo.pseudoClassStateChanged(centerAligned, newValue.intValue() % 2 == 0));
    
        for (int i = 0; i < 5; i++) {
            combo.getItems().add("item " + i);
        }
        combo.setValue("item 0");
        combo.setMaxWidth(Double.MAX_VALUE);
    
        VBox root = new VBox(combo);
        root.setFillWidth(true);
        root.setPrefWidth(300);
        Scene scene = new Scene(root);
        scene.getStylesheets().add("style.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    

    style.css

    .combo-box:center-aligned>.list-cell {
        -fx-alignment: center;
    }