2016-05-20 10 views
1

Gibt es eine Möglichkeit, den Text in einer javafx.scene.control.ChoiceBox horizontal zu zentrieren? Ich schaue, um den Text im ChoiceBox zu zentrieren, sowie das Dropdown, das sich öffnet, wenn man einen Wert auswählt.So zentrieren Sie Text in einer JavaFX ChoiceBox horizontal

+3

Eine Option besteht darin, stattdessen eine ComboBox zu verwenden und die Eigenschaften cellFactory und buttonCell festzulegen. – VGR

Antwort

1

Laut der Empfehlung von @VGR, habe ich meine Implementierung geändert, um eine javafx.scene.control.ComboBox zu verwenden. Dann habe ich eine Klasse CenteredListCell genannt:

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

} 

Als nächstes habe ich die folgende Dienstprogramm-Methode (vielen Dank für die Inspiration @kleopatra, die zu runWhenSkinned führen):

private static void runWhenSkinned(final Control control, final Runnable operation) { 
    final ReadOnlyObjectProperty<?> skinProperty = control.skinProperty(); 
    if (skinProperty.get() == null) { 
     // Run after the control has been skinned 
     skinProperty.addListener(observable -> Platform.runLater(operation)); 
    } else { 
     // Run now, since the control is already skinned 
     operation.run(); 
    } 
} 

public static <T> void center(final ComboBox<T> comboBox) { 
    runWhenSkinned(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(), 
       arrowWidth, oldPadding.getBottom(), 0); 

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

Das Endergebnis ist ein ComboBox mit zentriertem Text in der Schaltflächenzelle und Listenansicht von Elementen.

+1

Sie können einen Listener für die Skin-Eigenschaft der Combo registrieren und die Hilfsmethode aufrufen, wenn Sie über eine neue Skin benachrichtigt werden – kleopatra