Run following example, and use only the up/down keys to select the Button, then Combo, then the other Button, and backwards. You'll see that you have to press the navigation key twice when passing the ComboBox (sometimes twice up, sometimes twice down to pass it).
The focus listener shows that the ComboBox has two parts that can get the focus, see sample output:
[INFO] Focus set to: Button@1ffe55f[styleClass=button]'A'
[INFO] Focus set to: ComboBoxListViewSkin$8[id=list-view, styleClass=list-view]
[INFO] Focus set to: ComboBox@ce8b48[styleClass=combo-box-base combo-box]
[INFO] Focus set to: Button@16153e2[styleClass=button]'B'
[INFO] Focus set to: ComboBox@ce8b48[styleClass=combo-box-base combo-box]
[INFO] Focus set to: Button@1ffe55f[styleClass=button]'A'
package hs.mediasystem;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ComboBox2Test extends Application {
public static void main(String[] args) {
System.setProperty("com.sun.javafx.twoLevelFocus", "true");
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(new VBox() {{
getChildren().add(new Button("A"));
getChildren().add(new ComboBox<>(FXCollections.observableArrayList("Aap", "Noot", "Mies")));
getChildren().add(new Button("B"));
}});
scene.focusOwnerProperty().addListener(new ChangeListener<Node>() {
@Override
public void changed(ObservableValue<? extends Node> observable, Node oldValue, Node newValue) {
if(newValue != null) {
System.out.println("[INFO] Focus set to: " + newValue);
}
}
});
scene.getStylesheets().add("combobox.css");
primaryStage.setScene(scene);
primaryStage.setWidth(400);
primaryStage.setHeight(300);
primaryStage.show();
}
}
The focus listener shows that the ComboBox has two parts that can get the focus, see sample output:
[INFO] Focus set to: Button@1ffe55f[styleClass=button]'A'
[INFO] Focus set to: ComboBoxListViewSkin$8[id=list-view, styleClass=list-view]
[INFO] Focus set to: ComboBox@ce8b48[styleClass=combo-box-base combo-box]
[INFO] Focus set to: Button@16153e2[styleClass=button]'B'
[INFO] Focus set to: ComboBox@ce8b48[styleClass=combo-box-base combo-box]
[INFO] Focus set to: Button@1ffe55f[styleClass=button]'A'
package hs.mediasystem;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ComboBox2Test extends Application {
public static void main(String[] args) {
System.setProperty("com.sun.javafx.twoLevelFocus", "true");
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(new VBox() {{
getChildren().add(new Button("A"));
getChildren().add(new ComboBox<>(FXCollections.observableArrayList("Aap", "Noot", "Mies")));
getChildren().add(new Button("B"));
}});
scene.focusOwnerProperty().addListener(new ChangeListener<Node>() {
@Override
public void changed(ObservableValue<? extends Node> observable, Node oldValue, Node newValue) {
if(newValue != null) {
System.out.println("[INFO] Focus set to: " + newValue);
}
}
});
scene.getStylesheets().add("combobox.css");
primaryStage.setScene(scene);
primaryStage.setWidth(400);
primaryStage.setHeight(300);
primaryStage.show();
}
}