当前位置: 首页 > 知识库问答 >
问题:

如何让JavaFX MenuItem响应TAB键?

亢建白
2023-03-14

JavaFX MenuItem可以通过设置ActionEvent EventHandler来响应大多数按键事件。但是,虽然事件处理程序捕获KeyCode.Enter的按键,但它不捕获KeyCode.Tab按键事件。显然,像TAB这样的一些关键事件是在更深层次上处理的。例如,箭头键启用菜单的遍历

My ContextMenu是用户开始在TextField中键入的电子邮件地址字符串的完整列表。用户希望按箭头键选择所需的项目,并按TAB键执行完成。

我可以将事件处理程序附加到ContextMenu本身并捕获TAB键。但是事件的源是ContextMenu,我在ContextMenu中找不到任何变量来指示当按下TAB键时突出显示了哪个MenuItem。MenuItem允许css样式控制菜单项在焦点中的外观,但它没有任何属性来指示它是否在焦点中。

共有1个答案

谭翰海
2023-03-14

如果正确的话,您需要覆盖默认的按键侦听器来添加您自己的响应,因此我们必须找到它应用的位置。

为了让这件事成功,我们必须用私人API来弄脏我们的手...

ContextMenu外观(ContextMenusKin)使用ContextMenuContent对象作为包含所有项的容器。这些项中的每一项都位于ContextMenuContent.MenuItemContainer容器中。

import com.sun.javafx.scene.control.skin.ContextMenuContent;
private ContextMenuContent.MenuItemContainer itemSelected=null;

@Override
public void start(Stage primaryStage) {

    MenuItem cmItem1 = new MenuItem("Item 1");
    cmItem1.setOnAction(e->System.out.println("Item 1"));
    MenuItem cmItem2 = new MenuItem("Item 2");
    cmItem2.setOnAction(e->System.out.println("Item 2"));

    final ContextMenu cm = new ContextMenu(cmItem1,cmItem2);

    Scene scene = new Scene(new StackPane(), 300, 250);
    scene.setOnMouseClicked(t -> {
        if(t.getButton()==MouseButton.SECONDARY || t.isControlDown()){
            cm.show(scene.getWindow(),t.getScreenX(),t.getScreenY());

            ContextMenuContent cmc= (ContextMenuContent)cm.getSkin().getNode();

            cmc.setOnKeyPressed(ke->{
                switch (ke.getCode()) {
                    case UP:    break;
                    case DOWN:  break;
                    case TAB:   ke.consume();
                                if(itemSelected!=null){
                                    itemSelected.getItem().fire();
                                }
                                cm.hide();
                                break;
                    default: break;
                }
            });
            VBox itemsContainer = cmc.getItemsContainer();
            itemsContainer.getChildren().forEach(n->{
                ContextMenuContent.MenuItemContainer item=(ContextMenuContent.MenuItemContainer)n;
                item.focusedProperty().addListener((obs,b,b1)->{
                    if(b1){
                        itemSelected=item;
                    }
                });
            });
        }
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}
 类似资料:
  • 问题内容: 如何让selenium等待日历小部件的加载?现在,我只是在将测试用例导出到junit程序后进行操作。 问题答案: 我会用 这将一直等待,直到元素出现在DOM中为止。 如果您需要检查元素是否可见,则最好使用

  • 问题内容: 如何让硒等待日历小部件的加载?现在,在将测试用例导出到junit程序后,我只是在做一个。 问题答案: 我会用 这将一直等待,直到元素出现在DOM中为止。 如果您需要检查元素是否可见,则最好使用

  • 问题是,当您必须使用IFrames将内容插入到网站中时,那么在现代Web世界中,IFrame也会有相应的响应。理论上,它很简单,只需使用或将CSS宽度设置为。但实际上,它不是那么简单,但也可以。 如果内容完全响应,并且可以在没有内部滚动条的情况下调整自身大小,那么iOS Safari将在没有任何实际问题的情况下调整的大小。 如果考虑以下代码: 使用content.html: 那么这在iOS7.1

  • 我目前正在运行Wiremock standalone,我试图模拟一个访问数据库的服务。 我的映射文件如下所示:- 所以如果我点击这个网址:- http://localhost/testService/search/details?productCode=12345 然后它将进入数据库获取退货产品12345。 如果我向服务发送数据库中不存在的请求(例如productCode=0),它会给我一个标准的

  • 我使用反应路由器作为根和"/"下的所有请求都指向反应路由器。并且当响应路由器发现url与任何定义的组件不匹配时,它将呈现NoMatch组件。问题来了,NoMatch被渲染了,这就是我想要的,但是状态代码仍然是200而不是404。当我的css或js文件被放置在一个错误的url反应路由器做同样的事情,它的反应200!然后页面告诉我,我的资源内容类型有一些问题! 那么,我如何使用react router

  • 我试图让ApacheHttpClient触发HTTP请求,然后显示HTTP响应代码(200404500等)以及HTTP响应正文(文本字符串)。需要注意的是,我使用的是因为大多数HttpClient示例都来自和API从版本3到版本4发生了巨大变化。 不幸的是,我只能让HttpClient返回状态代码或响应主体(但不是两者)。 这是我所拥有的: 所以我问:使用库,如何从同一