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

JavaFX TabPane仅在聚焦时切换选项卡

萧煜
2023-03-14
    TextArea@3f40a15a[styleClass=text-input text-area]
    TextArea@7b7c82a4[styleClass=text-input text-area]
    TabPane[id=null, styleClass=tab-pane]
    TextArea[id=null, styleClass=text-input text-area]
    MenuButtonSkinBase$MenuLabeledImpl[id=null, styleClass=label]
    TextArea[id=null, styleClass=text-input text-area]
    MenuButtonSkinBase$MenuLabeledImpl[id=null, styleClass=label]
    TextArea[id=null, styleClass=text-input text-area]
    TabPane[id=null, styleClass=tab-pane]
    TextArea[id=null, styleClass=text-input text-area]
    MenuButtonSkinBase$MenuLabeledImpl[id=null, styleClass=label]
    TextArea[id=null, styleClass=text-input text-area]
    scene.focusOwnerProperty().addListener(new ChangeListener<Node>() {

        @Override
        public void changed(ObservableValue<? extends Node> ov, Node t, Node t1) {
            System.out.println(t1);
        }
    });

另外,我想请求关注textArea,每次用户打开/关闭选项卡,并在选项卡之间切换(使用鼠标和键盘热键)。

    tabPane.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {

        @Override
        public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
            Platform.runLater(new Runnable() {

                @Override
                public void run() {
                    if (tabPane.getTabs().size() > 0) {
                        FileTab tab = (FileTab)tabPane.getTabs().get(tabPane.getSelectionModel().getSelectedIndex());
                        tab.getTextArea().requestFocus();
                    }
                }
            });

        }
    });

这不起作用。我尝试了tab.getContent().requestFocus()-也不起作用。

关于当TabPane child处于焦点时更改选项卡:TabPane似乎得到了KeyEvent,但因为它不在焦点中(textArea处于焦点中),它只是跳过了这个事件。也许我可以通过在TabPane上触发KeyEvent来复制默认功能,或者甚至可以自己重新实现它。或者我可以从这个监听器调用nexttab/previoustab默认操作:

        @Override
        public void handle(KeyEvent t) {
            if (t.getCode().equals(KeyCode.TAB) && t.isControlDown()) {
                  //Event.fireEvent(tabPane, event); //I'm not sure how to do it like this
                  //Maybe it's better to just call default actions on TabPane.
                  t.consume();
            }
        }
    }); 

但我仍然不知道如何设置tab切换后的TextArea焦点。也许我应该尝试在一些延迟后调用platform.runlater()?

共有1个答案

葛学民
2023-03-14

选项卡切换解决方案:

    scene.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {

        @Override
        public void handle(KeyEvent t) {
            if (t.getCode().equals(KeyCode.TAB) && t.isControlDown()) {
                int size = tabPane.getTabs().size();

                if (size > 0) {
                    SkinBase skin = (SkinBase) tabPane.getSkin();
                    TabPaneBehavior tabPaneBehavior = (TabPaneBehavior) skin.getBehavior();

                    int selectedIndex = tabPane.getSelectionModel().getSelectedIndex();

                    if (!t.isShiftDown()) {
                        if (selectedIndex < size -1) {
                            tabPaneBehavior.selectNextTab();
                        } else {
                            tabPaneBehavior.selectTab(tabPane.getTabs().get(0));
                        }
                    } else {
                        if (selectedIndex > 0) {
                            tabPaneBehavior.selectPreviousTab();
                        } else {
                            tabPaneBehavior.selectTab(tabPane.getTabs().get(size - 1));
                        }
                    }

                    t.consume();
                }

            }
        }
    });

将焦点设置在选定选项卡上的解决方案:

        tabPane.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {

        @Override
        public void changed(ObservableValue<? extends Number> ov, Number t, final Number t1) {
            Platform.runLater(new Runnable() {

                @Override
                public void run() {
                    if (tabPane.getTabs().size() > 0) {
                        final FileTab tab = (FileTab) tabPane.getTabs().get(t1.intValue());

                        final Timer timer = new Timer();
                        timer.schedule(new TimerTask() {

                            @Override
                            public void run() {
                                Platform.runLater(new Runnable() {

                                    @Override
                                    public void run() {
                                        tab.getContent().requestFocus();
                                        timer.cancel();
                                        timer.purge();
                                    }
                                });
                            }
                        }, 25);
                    }
                }
            });

        }
    });

将焦点设置在选定选项卡上的替代解决方案(基于https://stackoverflow.com/a/16920898by@uluk Biy):

        tabPane.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {

        @Override
        public void changed(ObservableValue<? extends Number> ov, Number t, final Number t1) {
            Platform.runLater(new Runnable() {

                @Override
                public void run() {
                    if (tabPane.getTabs().size() > 0) {
                        final FileTab tab = (FileTab) tabPane.getTabs().get(t1.intValue());

                        final Timeline animation = new Timeline(
                                new KeyFrame(Duration.millis(25),
                                new EventHandler<ActionEvent>() {
                                    @Override
                                    public void handle(ActionEvent actionEvent) {
                                        Platform.runLater(new Runnable() {

                                            @Override
                                            public void run() {
                                                tab.getContent().requestFocus();
                                            }
                                        });
                                    }
                                }));
                        animation.setCycleCount(1);
                        animation.play();
                    }
                }
            });

        }
    });
 类似资料:
  • 您好,我正在使用selenium单击链接,通常使用在线web应用程序。 当我单击打开新选项卡的特定链接并在新打开的选项卡中执行操作时,我会遇到问题。我有以下代码: 之后,网络驱动程序(从我的眼睛)打开到新标签,而我不必调用 所以一切都好。新标签会在WebDrive上打开。当我尝试单击新打开的选项卡上的链接时,我得到一个“无元素”异常,这意味着它找不到我要找的元素。 两个问题: 1) webdriv

  • 打开 Chrome 和新标签页: < br >在Python 2.7.11中使用Selenium,我在chrome中打开了两个选项卡。我可以访问单个选项卡(转到新的URL),但我无法聚焦于选定的选项卡。例如,当我打开一个新标签页时,它会成为焦点。当我使用< code > driver . switch _ to . window(driver . window _ handles[0])选择第一个

  • 问题内容: 我想更改JSpinner的行为,以便在单击文本时将其选中。这样可以更轻松地将字段替换为所需的值。不幸的是,我无法使该行为起作用,它只是将光标插入文本中,而没有选择已经存在的内容。 我曾尝试通过既向JSpinner本身又向文本区域本身添加了一个焦点侦听器,但这些似乎都没有达到预期的效果。我的代码(针对JSpinner本身)如下: 我不确定是什么问题。如果有关系,我正在运行Mac OS 1

  • 我编写了一个自定义的,这样当我键入示例的列时,除了数字之外什么都不能输入。 如果用户单击单元格一次,然后开始键入,同时仍然允许用户双击单元格开始编辑,我如何防止用户能够编辑单元格?

  • 出于自动化的目的,我正在创建一个在表中查找一行的脚本。此行是可单击的,并打开一个新的选项卡/地址。 使用selenium,我现在可以找到表行,单击链接,然后打开新的选项卡。问题是我找不到任何方法将焦点切换到新打开的选项卡。我试图获得所有的windowhandle,看看我是否可以切换,但即使在新标签打开后,只有一个windowhandle。 Arraylist始终包含1个windowHandle,而

  • 问题内容: 所以我有一个包含3个项目的项目: 在的中: 每次单击某个项目时,都会调用一个骨干路由器,该骨干路由器将调用,而后者又将调用一个。 我仍在努力解决基本上存在单向数据流这一事实。而且我习惯直接操作DOM。 我想做的是将类添加到单击的选项卡中,并确保将其从非活动类中删除。 我所知道的CSS技巧,你可以使用属性和不同的造型适用于为属性或。 骨干路由器已经获取了变量并调用正确的页面。我只是不确定