我需要在 Ctrl-Tab 和 Ctrl-Shift-Tab 上切换标签。但它仅在 TabPane处于焦点时才有效。我有使用setContent(textArea)的Tabs。 当 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
我创建了标签并使用了 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()?
答案 0 :(得分:4)
TABS SWITCH的解决方案:
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);
}
}
});
}
});
在选定的选项卡上设置焦点的替代解决方案(基于@ {uluk Biy的https://stackoverflow.com/a/16920898):
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();
}
}
});
}
});
这应该是比使用计时器更好的解决方案。
答案 1 :(得分:0)
只需使用以下内容聚焦第一个标签(即标签0):
Platform.runLater(() -> tabPane.getTabs().get(0).getContent().requestFocus());