在回答有关ChoiceBox的问题时,我发现了一个有趣的问题(可能是bug?)。在Java 1.8u60中,为ChoiceBox添加了以下四个方法:setOnShownsetOnShowingsetOnHiddensetOnHiding。但是我不能让他们工作!

public class ComboBoxSample extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override public void start(Stage stage) {
        stage.setTitle("ComboBoxSample");
        Scene scene = new Scene(new Group(), 450, 250);

        final ComboBox<String> comboBox = new ComboBox<>();
        comboBox.getItems().addAll(
                "jacob.smith@example.com",
                "isabella.johnson@example.com"
        );

        comboBox.setOnShown(event -> {
            System.out.println("ComboBox onShown");
            System.out.println(comboBox.getSelectionModel().getSelectedIndex());
        });
        comboBox.setOnShowing(event -> {
            System.out.println("ComboBox setOnShowing");
            System.out.println(comboBox.getSelectionModel().getSelectedIndex());
        });

        ChoiceBox<String> choiceBox = new ChoiceBox<>();
        choiceBox.setItems(FXCollections.observableArrayList(
                "New Document", "Open ")
        );

        choiceBox.setOnShown(event -> {
            System.out.println("ChoiceBox onShown");
            System.out.println(choiceBox.getSelectionModel().getSelectedIndex());
        });

        choiceBox.setOnShowing(event -> {
            System.out.println("ChoiceBox onShowing");
            System.out.println(choiceBox.getSelectionModel().getSelectedIndex());
        });

        choiceBox.setOnHidden(event -> {
            System.out.println("ChoiceBox setOnHidden");
            System.out.println(choiceBox.getSelectionModel().getSelectedIndex());
        });

        choiceBox.getSelectionModel().selectedIndexProperty().addListener(e -> {
            System.out.println("ChoiceBox selectedIndexProperty");
        });

        GridPane grid = new GridPane();
        grid.setVgap(4);
        grid.setHgap(10);
        grid.setPadding(new Insets(5, 5, 5, 5));
        grid.add(new Label("ComboBox: "), 0, 0);
        grid.add(comboBox, 1, 0);
        grid.add(new Label("ChoiceBox: "), 0, 1);
        grid.add(choiceBox, 1, 1);

        Group root = (Group)scene.getRoot();
        root.getChildren().add(grid);
        stage.setScene(scene);
        stage.show();
    }
}


对于ComboBoxsetOnShown方法都可以正常工作,但是对于setOnShowing控制台,除了ChoiceBox侦听器之外,输出为空。
这是一个已知的错误吗?因为我找不到任何相关的错误。还是代码有问题?

我使用最新的JDK v1.8.0_121。

最佳答案

是的,这确实似乎是一个错误。

检查ChoiceBox的代码将导致以下结果:ChoiceBox以错误的事件类型触发这些事件。

设置处理程序时,将执行以下代码:

private ObjectProperty<EventHandler<Event>> onShown = new ObjectPropertyBase<EventHandler<Event>>() {
    @Override protected void invalidated() {
        setEventHandler(ON_SHOWN, get());
    }

    ....
};


其中ON_SHOWN定义为ChoiceBox的静态字段:

public static final EventType<Event> ON_SHOWN =
        new EventType<Event>(Event.ANY, "CHOICE_BOX_ON_SHOWN");


但是,当事件被触发时...

Event.fireEvent(this, value ? new Event(ComboBoxBase.ON_SHOWN) :
            new Event(ComboBoxBase.ON_HIDDEN));


...它使用ComboBoxBase.ON_SHOWN事件类型。

它似乎是复制粘贴忘记更新的问题。

简而言之:它们不起作用,因为在设置处理程序时,它们期望错误的事件类型。



作为解决方法,直到它解决,您可以侦听在ComboBoxBase中定义的触发事件类型。

使用EventFilter

choiceBox.addEventFilter(ComboBoxBase.ON_SHOWN, e ->
    System.out.println("ComboBoxBase.ON_SHOWN was fired"));


或使用EventHandler

choiceBox.addEventHandler(ComboBoxBase.ON_SHOWN, e->
    System.out.println("ComboBoxBase.ON_SHOWN was fired"));




JDK错误凭单:JDK-8175963 : ChoiceBox using events from ComboBox

关于java - ChoiceBox onShown\onHidden方法不起作用JavaFX,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42641744/

10-11 20:46