JavaFX选项卡窗格选项卡不带';t更新位置
我注意到,在JavaFX选项卡窗格选项卡不带';t更新位置,java,javafx,tabs,javafx-2,tabpanel,Java,Javafx,Tabs,Javafx 2,Tabpanel,我注意到,在选项卡窗格中添加和删除选项卡时,它无法匹配基本列表中选项卡顺序的位置。只有当至少一个选项卡由于父选项卡的宽度而完全隐藏时,才会发生这种情况。下面是一些复制问题的代码: public class TabPaneTester extends Application { @Override public void start(Stage primaryStage) throws Exception { Scene scene = sizeScene();
选项卡窗格
中添加和删除选项卡时,它无法匹配基本列表中选项卡顺序的位置。只有当至少一个选项卡由于父选项卡的宽度而完全隐藏时,才会发生这种情况。下面是一些复制问题的代码:
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();
}
}
public类TabPaneTester扩展应用程序{
@凌驾
public void start(Stage primaryStage)引发异常{
Scene-Scene=sizeScene();
初生阶段:最低高度(200);
初生阶段,坐骨宽度(475);
初级阶段。场景(场景);
primaryStage.show();
}
私人场景sizeScene(){
TabPane TabPane=新建TabPane();
tabPane.setTabMinWidth(200);
tabPane.getTabs().addAll(newTabs(3));
场景=新场景(选项卡窗格);
按scene.setOnKeyPressed(e->tabPane.getTabs().add(1,tabPane.getTabs().remove(0));
返回场景;
}
私有静态选项卡[]newTabs(int numTabs){
Tab[]tabs=新选项卡[numTabs];
对于(int i=0;i
当您按下一个键时,它会删除第一个选项卡(在索引0处)并将其放回索引1,从而有效地交换前两个选项卡。但是,当运行时,选项卡实际上不会在视觉上交换(即使选项卡切换菜单确实切换了它们的位置)
如果将屏幕宽度更改为包含第三个隐藏选项卡的一个像素(将475替换为500),它将按预期工作。关于如何修复这个问题,有什么线索吗?这确实是一个bug,我在公开的JIRA中找不到它的报道,现在它被报道在
如果您想亲自查看,我所有的分析都基于TabPaneSkin
中的代码
总结
当您删除然后添加选项卡“太快”时,问题就会出现。移除选项卡时,将在移除过程中进行异步调用。如果您进行了另一项更改,例如在异步调用完成之前添加了一个选项卡(或者至少“足够完成”),那么更改过程会看到窗格处于无效状态
细节
删除选项卡将调用removeTabs
,如下所示:
- 如果是(
),增长
- 动画将对
方法的调用排队,该方法本身是异步调用的requestLayout
- 动画开始(异步)并返回方法
NONE
),
requestLayout
,方法返回requestLayout
返回(在另一个线程上)的时间。此持续时间等于requestLayout
的持续时间加上动画的持续时间(如果有),即animation\u 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();
});
这允许您减少暂停持续时间。在我的机器上,15是安全的(这里你也可以连续快速调用按键
处理程序,因为延迟很短)
可能的解决办法
tabHeaderArea
上的一些同步 我想你发现了一只虫子。如果在.add(2,yourTab)
中使用2,您将看到新的选项卡的位置比它应该处于的位置少一个。您能解释一下这是如何导致该行为的吗?我看不出所选选项卡如何影响它们的位置,因为无论哪种方式,都应该删除第一个选项卡并更新列表,导致选项卡2显示(并选中)在前面,然后选项卡1放在后面。同样,如果宽度不重要,它如何改变行为?编辑:哎呀,虫子……一定是虫子。如果在再次添加选项卡后打印该选项卡的实际位置,它将显示与实际可视位置不同的位置。现在如果调用tabPane.autosize()代码>在关键事件结束时,它将修复位置。似乎在fx9@kleopatraTabPaneSkin
是否更改了其异步行为?
tabPane.setStyle("-fx-close-tab-animation: NONE;");