ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaFX KeyEvent传播顺序

2019-05-29 00:49:49  阅读:316  来源: 互联网

标签:java javafx javafx-2 javafx-8


我想在我的场景中听一些KeyEvent,比如KeyCode.ESCAPE(按下时关闭场景).

scene.addEventHandler(KeyEvent.ANY, event -> {
            if (event.isConsumed())
                return;
            switch (event.getCode()) {
            case ESCAPE:
                stage.hide();
                event.consume();
                break;
            default:
                break;
            }
        });

现在,场景中的节点也可以听取ESCAPE.

// ....
someOtherNode.addEventHandler(KeyEvent.ANY, e -> {
        if (e.getCode() == KeyCode.ESCAPE) {
            // do stuff
            e.consume();
        }
});
// ....

如何确保将从节点而不是场景中使用KeyEvent?

基于Oracle的图表,一种解决方法是在Node层次结尾处添加一个虚拟节点,用于侦听KeyCodes

但是有没有更好的解决方案,比如反转传播路径?

编辑:

用例:

阻止其他节点的类似弹出窗口的节点需要侦听ESC键或focusProperty()以便它可以自行关闭.

解决方法:

有两种方法可以影响事件:

>使用Node.addEventFilter(...)方法注册过滤器.过滤器将在事件的捕获阶段执行(因为窗口越来越具体,确定哪些节点应该获取事件).
>使用Node.addEventHandler(...)方法注册处理程序.处理程序将从捕获阶段中找到的最特定节点开始执行,向下一直到消耗.

因此在捕获阶段,会创建一个堆栈.从窗口(最顶层的父节点)开始,此事件可能执行的每个节点都将添加到堆栈中(以最底层的子节点结束).过滤器可以中断此过程,或者只是在此过程中执行事件.

在冒泡阶段,事件处理程序将从堆栈顶部(在捕获阶段创建)开始触发,直到堆栈为空或消耗事件为止.

在你的情况下,你真的不应该担心任何事情.如果任何节点关心处理“ESC”事件,他们将在冒泡阶段这样做(他们应该使用该事件以防止进一步处理).您可以在ComboBox中看到此行为.如果他们不关心,它将冒泡到你的场景并且该处理程序将执行.只需确保您创建的任何处理“ESC”按下的自定义代码也会消耗该事件.

有关更多信息,请参阅此处的说明和教程:http://docs.oracle.com/javafx/2/events/jfxpub-events.htm

这里有一些演示Escape功能的示例代码.在聚焦ComboBox时按ESC不会导致应用程序关闭,而它将关闭其他控件.

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.converter.DefaultStringConverter;


public class FXEventFiltering extends Application {

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

    @Override
    public void start(final Stage stage) throws Exception {
        //All the controls are added here
        VBox box = new VBox();
        ComboBox<String> dropdown = new ComboBox<>();
        TextField field = new TextField();
        CheckBox check = new CheckBox("Check");
        RadioButton radio = new RadioButton("Radio!");
        TextArea area = new TextArea();
        TableView<String> table = new TableView<String>(FXCollections.observableArrayList(new String[]{"one","two"}));
        TableColumn<String, String> tc = new TableColumn<String, String>("Column1");
        tc.setEditable(true);
        tc.setCellFactory(TextFieldTableCell.<String,String>forTableColumn(new DefaultStringConverter()));
        tc.setCellValueFactory(new Callback<CellDataFeatures<String,String>, ObservableValue<String>>(){
            @Override
            public ObservableValue<String> call(CellDataFeatures<String, String> arg0) {
                return new SimpleStringProperty(arg0.getValue());
            }});
        table.getColumns().add(tc);

        box.getChildren().addAll(dropdown, field, check, radio, area, table);

        //Setting up your scene
        Scene scene = new Scene(box);
        stage.setScene(scene);
        scene.addEventHandler(KeyEvent.ANY, new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                System.out.println("KEYS!" + event.getEventType().getName());
                switch (event.getCode()) {
                case ESCAPE:
                    System.out.println("Escape!");
                    stage.hide();
                    event.consume();
                    break;
                default:
                    break;
                }
            }
        });

        box.requestFocus(); // Removing default focus

        stage.show();
    }

}

标签:java,javafx,javafx-2,javafx-8
来源: https://codeday.me/bug/20190529/1175017.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有