【发布时间】:2018-08-18 16:58:29
【问题描述】:
我的 JavaFX 程序中有一个奇怪的错误,处理 EventHandlers 和 Tabs。我一直在疯狂地研究它,但具体的解决方案却让我望而却步。
这是瘦身:在我的主控制器中,我有一个选项卡窗格;每个选项卡都由嵌套控制器控制。第二个选项卡 TabB 中有一个字符串列表视图。每次用户单击 TabB 时,我都希望 ListView 刷新其内容。这是设置 TabB 的主控制器中的代码:
@FXML TabBController AnchorPaneTabBController; // Nested Controller
@FXML Tab tabB;
...
AnchorPaneTabBController.setUpTabB();
// Code to detect when this tab is clicked:
tabB.setOnSelectionChanged(new EventHandler<Event>() {
@Override
public void handle(Event t) {
if (tabB.isSelected()) {
AnchorPaneTabBController.refreshContent();
}
}
});
这是来自“TabBController.java”的相关代码:
public class TabBController {
@FXML ListView listViewMyStuff;
private @FXML void initialize() {...blah blah...}
public void setUpTabB(){
System.out.println("......setUpTabB()");
// set listener for the ListView
listViewMyStuff
.getSelectionModel()
.selectedIndexProperty()
.addListener(
(obs, oldVal, newVal) -> doStuffWithSelection(listViewMyStuff));
}
private void doStuffWithSelection(ListView newVal){
String str = (String) listViewMyStuff.getSelectionModel().getSelectedItem();
System.out.println(" -- You clicked on: "+str);
}
public void refreshContent(){
ArrayList<String> arrList = new ArrayList<SpaceObject>();
ObservableList<SpaceObject> obsList;
// put items in arrList
obsList = FXCollections.observableArrayList( arrList );
listViewMyStuff.setItems(obsList);
}
}
说实话,我不确定这是不是最好的设计。我的基本想法是 setUpTabB() 将由主控制器调用一次,它会执行 TabB 需要的所有一次性操作。每次用户单击 TabB 时都会调用 refreshContent()。您会注意到 ListView 的侦听器位于 setUpTabB() - 这是因为我只想创建一个侦听器。 (我认为把它放在refreshContent() 中会在每次点击 TabB 时创建一个新的监听器。)
好的...所以这几乎可以工作。假设 ListView 填充了两个字符串,“String A”和“String B”。进一步假设我单击 TabB,然后按顺序单击每个字符串。这是输出:
......setUpTabB()
-- You clicked on: String A
-- You clicked on: String B
到目前为止,一切都很好。现在这是错误。假设我单击另一个选项卡,任何选项卡,然后再次单击 TabB。发生的那一刻,输出变为:
......setUpTabB()
-- You clicked on: String A
-- You clicked on: String B
-- You clicked on: null
-- You clicked on: String B
所以...这是我一年来见过的最奇怪的事情。似乎当我第二次单击 TabB 时,setUpTabB() 中设置的侦听器启动并...重新选择任何内容然后重新选择我之前的选择... ?我已经用调试器逐步完成了这个,但我无法弄清楚这里发生了什么。事实上,每次我点击离开然后重新点击 TabB 时,都会发生同样的事情:
......setUpTabB()
-- You clicked on: String A
-- You clicked on: String B // Now I click TabA, then TabB...
-- You clicked on: null
-- You clicked on: String B // Now I click TabC, then TabB...
-- You clicked on: null
-- You clicked on: String B // Now I click TabA, then TabC, then TabB...
-- You clicked on: null
-- You clicked on: String B
这打败了我。当我重新选择 TabB 时,我假设侦听器仍在工作并重新选择我之前的选择。我猜……?
有人见过这样的事情吗?任何建议/见解表示赞赏。
【问题讨论】:
-
您替换列表视图中的所有项目。所以这首先删除了那里的所有东西,然后用一堆新东西替换它。如果在删除所有内容时选择了某些内容,如果不为空,您希望所选项目更改为什么?这似乎正是预期的行为。
-
@James_D ...有趣!我完全没有想到你的看法。我假设如果我删除了列表的内容,那么从那时起用户的选择将不存在。
标签: javafx controller tabs listener