Jeff G Jeff G - 6 months ago 114
Java Question

How to Horizontally Center Text in a JavaFX ChoiceBox

Is there any way to horizontally center the text in a

javafx.scene.control.ChoiceBox
? I am looking to center the text in the
ChoiceBox
, as well as the dropdown that opens when in the process of selecting a value.

Answer

Per the recommendation of @VGR, I changed my implementation to use a javafx.scene.control.ComboBox. Then, I created a class called CenteredListCell:

import javafx.geometry.Pos;
import javafx.scene.control.ListCell;

public class CenteredListCell<T> extends ListCell<T> {

    /** Default constructor */
    public CenteredListCell() {
        setMaxWidth(Double.POSITIVE_INFINITY);
        setAlignment(Pos.BASELINE_CENTER);
    }

    @Override
    public void updateItem(final T item, final boolean empty) {
        super.updateItem(item, empty);
        setText(empty || item == null ? null : item.toString());
    }

}

Next, I created the following utility method:

NOTE: The following utility method cannot be called until the ComboBox is added to a stage and that stage is being shown

public static <T> void center(final ComboBox<T> comboBox) {
    // Get the width of the combo box arrow button
    final Region arrow = (Region)comboBox.lookup(".arrow-button");
    final double arrowWidth = arrow.getWidth();

    // Create a centered button cell
    final ListCell<T> buttonCell = new CenteredListCell<T>();
    comboBox.setButtonCell(buttonCell);

    // Create an insets object with uneven horizontal padding
    final Insets oldPadding = buttonCell.getPadding();
    final Insets newPadding = new Insets(oldPadding.getTop(), oldPadding.getRight() +
            arrowWidth, oldPadding.getBottom(), oldPadding.getLeft());

    // Replace the default cell factory
    comboBox.setCellFactory(listView -> new CenteredListCell<T>() {
        { setPadding(newPadding); }
    });
}

The end result is a ComboBox with centered text in both the button cell and list-view of items.