每行使用一個行工廠和一個上下文菜單,就像在你鏈接的問題中一樣。
對於「全局」CheckMenuItem
,創建一個BooleanProperty
並雙向綁定CheckMenuItem
的選定屬性。
SSCCE:
import java.util.function.Function;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TableWithContextMenu extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Item> table = new TableView<>();
table.getColumns().add(column("Item", Item::nameProperty));
table.getColumns().add(column("Value", Item::valueProperty));
BooleanProperty globalSelection = new SimpleBooleanProperty();
table.setRowFactory(t -> {
TableRow<Item> row = new TableRow<>();
ContextMenu contextMenu = new ContextMenu();
MenuItem item1 = new MenuItem("Do something");
item1.setOnAction(e -> System.out.println("Do something with "+row.getItem().getName()));
MenuItem item2 = new MenuItem("Do something else");
item2.setOnAction(e -> System.out.println("Do something else with "+row.getItem().getName()));
CheckMenuItem item3 = new CheckMenuItem("Global selection");
item3.selectedProperty().bindBidirectional(globalSelection);
contextMenu.getItems().addAll(item1, item2, new SeparatorMenuItem(), item3);
row.emptyProperty().addListener((obs, wasEmpty, isEmpty) -> {
if (isEmpty) {
row.setContextMenu(null);
} else {
row.setContextMenu(contextMenu);
}
});
return row ;
});
IntStream.rangeClosed(1, 25).mapToObj(i -> new Item("Item "+i, i)).forEach(table.getItems()::add);
primaryStage.setScene(new Scene(new BorderPane(table), 800, 600));
primaryStage.show();
}
private <S,T> TableColumn<S,T> column(String title, Function<S, ObservableValue<T>> property) {
TableColumn<S,T> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
return col ;
}
public static class Item {
private final IntegerProperty value = new SimpleIntegerProperty();
private final StringProperty name = new SimpleStringProperty();
public Item(String name, int value) {
setName(name);
setValue(value);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
}
public static void main(String[] args) {
launch(args);
}
}