JavaFX TableView 上下文菜单项在 Java 8 上 运行 时出现,直到更新 5,但在以后的更新中不显示
JavaFX TableView Context Menu Item shows up when run on Java 8 until update 5 but not on later ones
下面的代码在 Java 8 update 5 上如其名称所示运行,但在以后的更新上不会运行:
public class TableViewShowingOnlyAnAppendContextMenuItemIfRowIsEmptyElseDeleteIsIncluded extends Application {
private final TableView<Name> table = new TableView<>();
private final ObservableList<Name> data = FXCollections.observableArrayList(new Name("Jacob"),
new Name("Isabella"), new Name("Ethan"), new Name("Emma"), new Name("Michael"));
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
TableColumn<Name, String> column = new TableColumn<>("Name");
column.setCellValueFactory(new PropertyValueFactory<>("name"));
table.getColumns().add(column);
table.setItems(data);
ContextMenu contextMenu = new ContextMenu();
contextMenu.getItems().add(new MenuItem("append"));
table.setContextMenu(contextMenu);
table.setRowFactory(tableView -> {
TableRow<Name> row = new TableRow<>();
row.contextMenuProperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(showOnlyAppendContextMenuItemIfRowIsEmptyElseIncludeDelete())
.otherwise((ContextMenu) null));
return row;
});
Scene scene = new Scene(table);
stage.setScene(scene);
stage.show();
}
private ContextMenu showOnlyAppendContextMenuItemIfRowIsEmptyElseIncludeDelete() {
ContextMenu rowMenu = new ContextMenu();
ContextMenu tableMenu = table.getContextMenu();
if (tableMenu != null)
rowMenu.getItems().addAll(tableMenu.getItems());
rowMenu.getItems().add(new MenuItem("delete"));
return rowMenu;
}
public static class Name {
private final SimpleStringProperty name;
private Name(String name) {
this.name = new SimpleStringProperty(name);
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
} }
能帮我找出代码中的错误吗?或者如果有none,这是应该提交的回归吗?截至目前,所有使用的PC都是8u5。
提前致谢。
此代码看起来像是我前一段时间发布的内容...
问题是不真正支持在多个菜单中使用 MenuItem
。虽然这在 Javadocs 中没有明确说明,但 MenuItem
有一个 getMenu()
方法这一事实确实暗示了这一点。事实上,它在 8u5 之前工作真的只是运气......
解决方法是创建新的菜单项,它们是 table 的上下文菜单中菜单项的副本:
private ContextMenu showOnlyAppendContextMenuItemIfRowIsEmptyElseIncludeDelete() {
ContextMenu rowMenu = new ContextMenu();
ContextMenu tableMenu = table.getContextMenu();
if (tableMenu != null) {
for (MenuItem item : tableMenu.getItems()) {
MenuItem rowItem = new MenuItem(item.getText());
rowItem.setGraphic(item.getGraphic());
rowItem.setOnAction(item.getOnAction());
rowMenu.getItems().add(rowItem);
}
}
rowMenu.getItems().add(new MenuItem("delete"));
return rowMenu;
}
另一种方法是使用 ControlsFX 动作,因此您可以为整个 table 维护一个(单个)动作列表,并从中为 table 和行生成菜单项。
下面的代码在 Java 8 update 5 上如其名称所示运行,但在以后的更新上不会运行:
public class TableViewShowingOnlyAnAppendContextMenuItemIfRowIsEmptyElseDeleteIsIncluded extends Application {
private final TableView<Name> table = new TableView<>();
private final ObservableList<Name> data = FXCollections.observableArrayList(new Name("Jacob"),
new Name("Isabella"), new Name("Ethan"), new Name("Emma"), new Name("Michael"));
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
TableColumn<Name, String> column = new TableColumn<>("Name");
column.setCellValueFactory(new PropertyValueFactory<>("name"));
table.getColumns().add(column);
table.setItems(data);
ContextMenu contextMenu = new ContextMenu();
contextMenu.getItems().add(new MenuItem("append"));
table.setContextMenu(contextMenu);
table.setRowFactory(tableView -> {
TableRow<Name> row = new TableRow<>();
row.contextMenuProperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(showOnlyAppendContextMenuItemIfRowIsEmptyElseIncludeDelete())
.otherwise((ContextMenu) null));
return row;
});
Scene scene = new Scene(table);
stage.setScene(scene);
stage.show();
}
private ContextMenu showOnlyAppendContextMenuItemIfRowIsEmptyElseIncludeDelete() {
ContextMenu rowMenu = new ContextMenu();
ContextMenu tableMenu = table.getContextMenu();
if (tableMenu != null)
rowMenu.getItems().addAll(tableMenu.getItems());
rowMenu.getItems().add(new MenuItem("delete"));
return rowMenu;
}
public static class Name {
private final SimpleStringProperty name;
private Name(String name) {
this.name = new SimpleStringProperty(name);
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
} }
能帮我找出代码中的错误吗?或者如果有none,这是应该提交的回归吗?截至目前,所有使用的PC都是8u5。
提前致谢。
此代码看起来像是我前一段时间发布的内容...
问题是不真正支持在多个菜单中使用 MenuItem
。虽然这在 Javadocs 中没有明确说明,但 MenuItem
有一个 getMenu()
方法这一事实确实暗示了这一点。事实上,它在 8u5 之前工作真的只是运气......
解决方法是创建新的菜单项,它们是 table 的上下文菜单中菜单项的副本:
private ContextMenu showOnlyAppendContextMenuItemIfRowIsEmptyElseIncludeDelete() {
ContextMenu rowMenu = new ContextMenu();
ContextMenu tableMenu = table.getContextMenu();
if (tableMenu != null) {
for (MenuItem item : tableMenu.getItems()) {
MenuItem rowItem = new MenuItem(item.getText());
rowItem.setGraphic(item.getGraphic());
rowItem.setOnAction(item.getOnAction());
rowMenu.getItems().add(rowItem);
}
}
rowMenu.getItems().add(new MenuItem("delete"));
return rowMenu;
}
另一种方法是使用 ControlsFX 动作,因此您可以为整个 table 维护一个(单个)动作列表,并从中为 table 和行生成菜单项。