【问题标题】:JavaFX Double (Unwanted) Event on Tab Selection选项卡选择上的 JavaFX 双(不需要的)事件
【发布时间】: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


【解决方案1】:

James_D 的评论是我需要澄清的。他是对的,因为我的代码不必要地重新加载了内容。它是一个设计问题。我最终放弃了上面的代码并从头开始。谢谢 James_D!

【讨论】:

    猜你喜欢
    • 2012-05-23
    • 1970-01-01
    • 2017-09-29
    • 2010-12-24
    • 1970-01-01
    • 2017-06-08
    • 2020-05-29
    • 2011-04-08
    • 1970-01-01
    相关资源
    最近更新 更多