停止显示多个 ListCell 上下文菜单

Stop multiple ListCell Context Menus from Showing

我制作了一个自定义 ListView 单元格,因此我可以添加一个上下文菜单,但是当您多次单击时它会不断打开多个上下文菜单,而旧菜单在使用时只会引发异常。

这是我的 SongCell class

public SongCell(ListView<Song> list, Playlist playlist) {

    setAlignment(Pos.CENTER_LEFT);

    ContextMenu listContextMenu = new ContextMenu();
    MenuItem removeItem = new MenuItem("Remove");
    MenuItem editID3Item = new MenuItem("Edit ID3");
    MenuItem playNextItem = new MenuItem("Play Next");
    removeItem.setOnAction((ActionEvent event) -> {

        list.getItems().remove(getIndex());

    });

    editID3Item.setOnAction((ActionEvent event) -> {
        Optional<Pair<String, String>> show = new FXID3Edit(getItem()).show();
    });
    playNextItem.setOnAction((ActionEvent event) -> {
        Song song = getItem();
        list.getItems().remove(song);
        playlist.addSongRequest(new SongRequest(song, SongRequest.type.NEXT));
    });

    listContextMenu.getItems().add(removeItem);
    listContextMenu.getItems().add(playNextItem);
    listContextMenu.getItems().add(editID3Item);

    setOnMousePressed(event -> {
        if (event.getButton().equals(MouseButton.SECONDARY)) {

            if (getItem() != null) {

                if (getItem().equals(playlist.getSong())) {
                    playNextItem.setDisable(true);
                    removeItem.setDisable(true);
                } else {
                    playNextItem.setDisable(false);
                    removeItem.setDisable(false);
                }
                listContextMenu.show(list, event.getScreenX(), event.getScreenY());
            }

        }

        if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
            playlist.setIndex(this.getIndex());
            playlist.play();

        }

        event.consume();
    });

}
@Override
protected void updateItem(Song item, boolean empty) {
    super.updateItem(item, empty);

    if (!empty && item != null) {
        this.setText(item.toString());
    } else {
        this.setText("");
    }
}

我也非常感谢对我的编码风格的帮助

不要注册鼠标侦听器来显示上下文菜单,而是使用内置的 setContextMenu(...) 属性。即:

public SongCell(ListView<Song> list, Playlist playlist) {

    // ...

    setOnMousePressed(event -> {

        if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
            playlist.setIndex(this.getIndex());
            playlist.play();

        }

        event.consume();
    });

}

@Override
public void updateItem(Song item, boolean empty) {
    super.updateItem(item, empty);

    if (!empty && item != null) {
        this.setText(item.toString());
        this.setContextMenu(listContextMenu);
    } else {
        this.setText("");
        this.setContextMenu(null);
    }
}