I need to switch tabs on Ctrl-Tab and Ctrl-Shift-Tab . But it works only when TabPane is in focus . I have Tabs with setContent(textArea). When textArea is in focus, and I press Ctrl-Tab , focus goes somewhere in menu:
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]
I track focus changes like this:
scene.focusOwnerProperty().addListener(new ChangeListener<Node>() {
@Override
public void changed(ObservableValue<? extends Node> ov, Node t, Node t1) {
System.out.println(t1);
}
});
I have setFocusTraversable to false almost on every component(including menu, toolbar, textArea and panes)
I created Tabs and used setContent(textArea) .
Also I want to requestFocus on textArea every time user open/close tab and switch between tabs(using mouse and keyboard hotkeys).
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();
}
}
});
}
});
This does not work. I tried tab.getContent().requestFocus() - doesn't work too.
About changing tabs when TabPane child is in focus: It seems like TabPane gets KeyEvent, but because it's not in focus(textArea in focus), it just skips this event. Maybe I could duplicate default functionality by firing KeyEvent at TabPane or maybe even re implement it on my own. Or maybe I could call nextTab/previousTab default actions from this listener:
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
But I still don't know how to set focus on TextArea after tab switch. Maybe I should try to call Platform.runLater() after some delay?
SOLUTION FOR 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();
}
}
}
});
SOLUTION FOR SETTING FOCUS ON SELECTED TAB:
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);
}
}
});
}
});
ALTERNATIVE SOLUTION FOR SETTING FOCUS ON SELECTED TAB(based on https://stackoverflow.com/a/16920898 by @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();
}
}
});
}
});
This should be better solution than just using timer.
只需使用以下内容来聚焦第一个选项卡(即选项卡 0):
Platform.runLater(() -> tabPane.getTabs().get(0).getContent().requestFocus());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.