我注意到在TabPane
添加和删除标签时,它无法匹配基础列表中标签顺序的位置。仅当父级的宽度完全隐藏至少一个选项卡时才会发生这种情况。这里有一些复制问题的代码:
public class TabPaneTester extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = sizeScene();
primaryStage.setMinHeight(200);
primaryStage.setWidth(475);
primaryStage.setScene(scene);
primaryStage.show();
}
private Scene sizeScene(){
TabPane tabPane = new TabPane();
tabPane.setTabMinWidth(200);
tabPane.getTabs().addAll(newTabs(3));
Scene scene = new Scene(tabPane);
scene.setOnKeyPressed(e -> tabPane.getTabs().add(1, tabPane.getTabs().remove(0)));
return scene;
}
private static Tab[] newTabs(int numTabs){
Tab[] tabs = new Tab[numTabs];
for(int i = 0; i < numTabs; i++) {
Label label = new Label("Tab Number " + (i + 1));
Tab tab = new Tab();
tab.setGraphic(label);
tabs[i] = tab;
}
return tabs;
}
public static void main(String[] args) {
launch();
}
}
当您按某个键时,它会删除第一个标签(在索引0处)并将其放回索引1,从而有效地交换前两个标签。但是,在运行时,标签实际上不会在视觉上交换(即使标签切换器菜单 切换其位置)。
如果您更改屏幕的宽度以包括隐藏的第三个选项卡的像素(用500替换475),它将按预期工作。关于如何解决这个问题的任何线索?
答案 0 :(得分:2)
这确实是一个错误,我无法在公共JIRA中报告现在报告https://bugs.openjdk.java.net/browse/JDK-8193495。
如果你想亲眼看看,我所有的分析都是基于TabPaneSkin
中的代码。
当您删除然后添加标签时,问题就出现了#34;太快了#34;删除选项卡时,在删除过程中进行异步调用。如果您进行了其他更改,例如在异步调用完成之前添加选项卡(或至少&#34;完成足够的&#34;),则更改过程会将窗格视为无效状态。
删除标签removeTabs
,如下所示:
GROW
),
requestLayout
方法的调用排队,该方法本身是异步调用的,NONE
),
requestLayout
,方法返回。窗格处于无效状态的时间是从调用返回到requestLayout
返回的时间(在另一个线程上)。此持续时间相当于requestLayout
的持续时间加上动画的持续时间(如果有的话),即ANIMATION_SPEED = 150
[ms]。在此期间调用addTabs
会导致意外的影响,因为正确添加选项卡所需的数据尚未准备就绪。
在通话之间添加一个人工暂停:
ObservableList<Tab> tabs = tabPane.getTabs();
PauseTransition p = new PauseTransition(Duration.millis(150 + 20));
scene.setOnKeyPressed(e -> {
Tab remove = tabs.remove(0);
p.setOnFinished(e2 -> tabs.add(1, remove));
p.play();
});
这是异步调用返回的足够时间(不要过快地调用KeyPressed
处理程序,因为您将删除选项卡的速度超过可以添加的选项卡)。您可以使用
tabPane.setStyle("-fx-close-tab-animation: NONE;");
允许您减少暂停持续时间。在我的机器上15是安全的(在这里你也可以连续快速调用KeyPressed
处理程序,因为延迟很短)。
tabHeaderArea
上的某些同步。