【发布时间】:2013-10-02 05:54:35
【问题描述】:
我需要在 Ctrl-Tab 和 Ctrl-Shift-Tab 上切换选项卡。但它仅在 TabPane 处于焦点状态 时有效。我有带有 setContent(textArea) 的标签。 当 textArea 成为焦点时,我按下 Ctrl-Tab,焦点转到菜单中的某处:
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 和窗格)上都将 setFocusTraversable 设置为 false
我创建了 Tabs 并使用了 setContent(textArea)。
我还想在每次用户打开/关闭选项卡并在选项卡之间切换(使用鼠标和键盘热键)时在 textArea 上requestFocus。
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 子项处于焦点时更改选项卡: 似乎 TabPane 获得了 KeyEvent,但因为它不在焦点中(焦点中的 textArea),所以它只是跳过了这个事件。 也许我可以通过在 TabPane 触发 KeyEvent 来复制默认功能,或者甚至可以自己重新实现它。或者,也许我可以从此监听器调用 nextTab/previousTab 默认操作:
tabPane.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler() {
@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();
}
}
});
http://s23.postimg.org/poeujzwbf/screenshot_185.png
但我仍然不知道如何在标签切换后将焦点设置在 TextArea 上。 也许我应该在延迟一段时间后尝试调用 Platform.runLater()?
【问题讨论】:
-
你能filter the event on the scene而不是TabPane吗?
-
似乎是个好主意。我认为 JavaFX 有更优雅的解决方案。无论如何我让它工作了,但仍然不知道在选项卡切换后将焦点设置在 Tab 内的 TextArea 上,有时它工作,有时它不工作(requestFocus())。
-
@AS3Boyan,你能不能试着把
tab.getTextArea().requestFocus();放到Platform.runLater中,也就是把if语句去掉。例如,或者使用时间轴在 100 毫秒后请求焦点。 -
@Uluk Biy,我想过延迟后运行,我想知道在 Java 8 中这些东西是否已修复。 new Timer() 似乎工作正常,但应用程序没有正确终止。我将尝试使用 Timeline,如果您有如何将其用作计时器的示例,请告诉我。