我有一个播放列表,我想在用户输入新的播放列表名称时自行更新。新的播放列表显示在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();
}
}
}
答案 0 :(得分:0)
当你用FXCollections.observableArrayList双重包装playListItems时,至少我看到你的代码出错了。
你不应该将playListItems作为类成员 - 仅作为局部变量(更好的是没有任何局部变量)
private final List<Object> playListItems = FXCollections.observableArrayList(new ArrayList<Object>());
...
playList.setItems(playListItems);
第二个提示(不考虑当前问题) - 不要将Object用作类型参数,而是使用像PlayListItem这样的特定类型。