Run the following app:
package application;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
final ComboBox<String> myCombo = new ComboBox<>();
final ListCell<String> customCell = new ListCell<String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
System.err.println("UPDATEING: " + item);
setText(item);
}
};
myCombo.setButtonCell(customCell);
myCombo.setItems(FXCollections.observableArrayList("A","B","C"));
root.setCenter(myCombo);
Button b = new Button("Toggle");
b.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if( myCombo.getValue() == null ) {
myCombo.setValue("A");
} else {
myCombo.setValue(null);
}
System.err.println(customCell.getPseudoClassStates());
}
});
root.setBottom(b);
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
and notice that the pseudo state is always empty after the first selection. The reason is that ComboBoxListViewSkin does the following calls:
buttonCell.setItem(null);
buttonCell.updateIndex(index);
2 solutions:
a) you are setting the real item (=value) on it
b) you manually set the pseudoStates (like you do for the empty selection)
buttonCell.pseudoClassStateChanged(PSEUDO_CLASS_EMPTY, false);
buttonCell.pseudoClassStateChanged(PSEUDO_CLASS_FILLED, true);
buttonCell.pseudoClassStateChanged(PSEUDO_CLASS_SELECTED, true);
package application;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
final ComboBox<String> myCombo = new ComboBox<>();
final ListCell<String> customCell = new ListCell<String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
System.err.println("UPDATEING: " + item);
setText(item);
}
};
myCombo.setButtonCell(customCell);
myCombo.setItems(FXCollections.observableArrayList("A","B","C"));
root.setCenter(myCombo);
Button b = new Button("Toggle");
b.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if( myCombo.getValue() == null ) {
myCombo.setValue("A");
} else {
myCombo.setValue(null);
}
System.err.println(customCell.getPseudoClassStates());
}
});
root.setBottom(b);
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
and notice that the pseudo state is always empty after the first selection. The reason is that ComboBoxListViewSkin does the following calls:
buttonCell.setItem(null);
buttonCell.updateIndex(index);
2 solutions:
a) you are setting the real item (=value) on it
b) you manually set the pseudoStates (like you do for the empty selection)
buttonCell.pseudoClassStateChanged(PSEUDO_CLASS_EMPTY, false);
buttonCell.pseudoClassStateChanged(PSEUDO_CLASS_FILLED, true);
buttonCell.pseudoClassStateChanged(PSEUDO_CLASS_SELECTED, true);