JavaFX 8 ListView的事件处理程序没有收到第一个提交事件

时间:2014-10-28 17:18:51

标签: java javafx javafx-8

我有一个播放列表,我想在用户输入新的播放列表名称时自行更新。新的播放列表显示在ListView中,但是我的setOnEditCommit() Event Handler在用户输入第二个“添加播放列表”之前不会收到任何提交。 (我通过调用System.out.println(event.getEventType());找到了丢失的事件。这甚至发生在从KeyEvent Handler显式调用commitEdit()时。

此外,当我尝试将所选的ListView索引更改为playList.setOnEditCommit()Event Handler内的新播放列表时,新选择将失败。

有人能发现我在这里做错了吗?

public class AudioPlayerFXMLController implements Initializable {

@FXML
private ListView playList;
@FXML
private TableView playListTableView;
private static List<Object> playListItems;
private static final String NEW_PLAYLIST = "New Playlist";
private static final String FRIEND_PLAYLIST = "Friend's Playlist";
private static final String LIBRARY = "Library";
private static ButtonCell bc;
ObservableList<Object> observablePlayList;

@Override
public void initialize(URL url, ResourceBundle rb) {

    playListItems = new ArrayList<Object>();
    observablePlayList = FXCollections.observableArrayList(playListItems);
    observablePlayList.add(NEW_PLAYLIST);
    observablePlayList.add(FRIEND_PLAYLIST);
    observablePlayList.add(LIBRARY);
    playList.setItems((FXCollections.observableArrayList(observablePlayList)));

    playList.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
        @Override
        public ListCell<String> call(ListView<String> list) {
            bc = new ButtonCell();
            bc.addEventFilter(MouseEvent.MOUSE_CLICKED, new MyEventHandler());
            return bc;
        }
    });

    playList.setEditable(true);
    playList.getSelectionModel().select(2);

    playList.setOnEditCommit(new EventHandler<ListView.EditEvent<String>>() {

        public void handle(ListView.EditEvent<String> event) {

            System.out.println(event.getEventType());
            int size = observablePlayList.size();
            playList.getSelectionModel().select(size);
        }
    });
}

class ButtonCell extends ListCell<String> {

    private TextField fieldForEditingCell;

    @Override
    public void startEdit() {

        if (!isEditable() || !getListView().isEditable()) {
            return;
        }

        super.startEdit();

        if (isEditing()) {
            fieldForEditingCell = new TextField("Enter your edit here");
            fieldForEditingCell.setOnKeyPressed(new EventHandler<KeyEvent>() {

                public void handle(KeyEvent keyPress) {
                    if (keyPress.getCode() == KeyCode.ENTER) {
                        String nameOfnewPlayList = fieldForEditingCell.getText();
                        playList.setItems(null);
                        observablePlayList.add(nameOfnewPlayList);
                        playList.setItems(observablePlayList);

                    } else if (keyPress.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });

            setGraphic(fieldForEditingCell);
            fieldForEditingCell.requestFocus();
            fieldForEditingCell.setEditable(true);

            fieldForEditingCell.focusedProperty().addListener(new ChangeListener<Boolean>() {
                @Override
                public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                    if (!newValue && fieldForEditingCell != null) {
                        commitEdit(fieldForEditingCell.getText());
                    }
                }
            });

            fieldForEditingCell.selectAll();

        }
    }

    @Override
    public void cancelEdit() {
        super.cancelEdit();
        ImageView addSymbol;
        addSymbol = ImageViewBuilder.create().image(new Image("/images/ic_add_grey600_15dp.png")).build();
        addSymbol.fitHeightProperty();
        setText(getItem());
        setGraphic(addSymbol);
    }

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

        if ((this.getIndex() == 0) || (this.getIndex() == 1)) {
            ImageView addSymbol;
            addSymbol = ImageViewBuilder.create().image(new Image("/images/ic_add_grey600_15dp.png")).build();
            addSymbol.fitHeightProperty();
            setText(item);
            setGraphic(addSymbol);

            getStyleClass().add("custom_list-cell");
            //setStyle("-fx-background-color: #F5F5F5");
            //setStyle("-fx-hover-color: yellow");
        } else {
            setText(item);
            setGraphic(null);
        }
    }

}

class MyEventHandler implements EventHandler<MouseEvent> {

    @Override
    public void handle(MouseEvent t) {
        ListCell c = (ListCell) t.getSource();
        int index = c.getIndex();

    }
}

}

1 个答案:

答案 0 :(得分:0)

当你用FXCollections.observableArrayList双重包装playListItems时,至少我看到你的代码出错了。

你不应该将playListItems作为类成员 - 仅作为局部变量(更好的是没有任何局部变量)

private final List<Object> playListItems = FXCollections.observableArrayList(new ArrayList<Object>());
...
playList.setItems(playListItems);

第二个提示(不考虑当前问题) - 不要将Object用作类型参数,而是使用像PlayListItem这样的特定类型。