gpt4 book ai didi

JavaFX TabPane 仅在获得焦点时切换选项卡

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:16:42 27 4
gpt4 key购买 nike

我需要在 Ctrl-TabCtrl-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);
}
});

我几乎在每个组件(包括菜单、工具栏、文本区域和 Pane )上都将 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,但是因为它不在focus(textArea in focus),所以它只是跳过了这个事件。也许我可以通过在 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()

最佳答案

标签切换的解决方案:

    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();
}
}
});

}
});

这应该是比仅使用计时器更好的解决方案。

关于JavaFX TabPane 仅在获得焦点时切换选项卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19025268/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com