选项卡选择中的JavaFX双(不需要)事件

时间:2018-03-10 04:25:56

标签: javafx controller tabs listener

我的JavaFX程序中有一个奇怪的错误,处理EventHandlers和Tabs。我一直在疯狂地研究它,但具体的解决方案让我望而却步。

这里是瘦的:在我的主控制器中,我有一个标签窗格;每个选项卡由嵌套控制器控制。第二个选项卡TabB中包含一个字符串ListView。每次用户单击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();
        }
    }
});

这里是来自&#34; TabBController.java&#34;的相关代码:

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填充了两个字符串,&#34;字符串A&#34;和&#34;字符串B&#34;。进一步假设我单击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时,我认为听众仍在工作并重新选择我之前的选择。我想......?

以前见过这样的人吗?任何建议/见解表示赞赏。

1 个答案:

答案 0 :(得分:0)

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