Skip to content

Instantly share code, notes, and snippets.

@james-d
Created January 23, 2014 15:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save james-d/8580044 to your computer and use it in GitHub Desktop.
Save james-d/8580044 to your computer and use it in GitHub Desktop.
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class BigTableWithContextMenu extends Application {
private static final int NUM_COLS = 100 ;
private static final int NUM_ROWS = 1000 ;
@Override
public void start(Stage primaryStage) {
long startMethodStartTime = System.currentTimeMillis();
final BorderPane root = new BorderPane();
final TableView<List<String>> table = new TableView<>();
for (int colIndex = 0 ; colIndex < NUM_COLS; colIndex++) {
TableColumn<List<String>, String> col = new TableColumn<>("Col " +colIndex);
final int cIndex = colIndex ;
col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<List<String>,String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(CellDataFeatures<List<String>, String> cdf) {
List<String> rowData = cdf.getValue();
return new ReadOnlyStringWrapper(rowData.get(cIndex));
}
});
createContextMenuCellFactory(col);
table.getColumns().add(col);
}
for (int rowIndex = 0; rowIndex < NUM_ROWS; rowIndex++) {
List<String> rowData = new ArrayList<>();
for (int colIndex = 0 ; colIndex < NUM_COLS; colIndex++) {
rowData.add(String.format("[%d,%d]", rowIndex, colIndex));
}
table.getItems().add(rowData);
}
root.setCenter(table);
final Scene scene = new Scene(root, 1600, 1200);
primaryStage.setScene(scene);
primaryStage.show();
long startMethodEndTime = System.currentTimeMillis();
System.out.println("start took "+(startMethodEndTime - startMethodStartTime)/1000.0 + " seconds");
}
private void createContextMenuCellFactory(TableColumn<List<String>, String> col) {
final StringProperty contextMenuValue = new SimpleStringProperty("");
final ContextMenu menu = new ContextMenu();
final MenuItem mi1 = new MenuItem("Choice 1");
final MenuItem mi2 = new MenuItem("Choice 2");
final MenuItem mi3 = new MenuItem();
// text depends on "current cell"
// more commonly, the action handler would depend on this value,
// but this is just a proof of concept
mi3.textProperty().bind(Bindings.format("Specific choice for %s", contextMenuValue));
menu.getItems().addAll(mi1, mi2, mi3);
col.setCellFactory(new Callback<TableColumn<List<String>, String>, TableCell<List<String>, String>>() {
@Override
public TableCell<List<String>, String> call(TableColumn<List<String>, String> col) {
final TableCell<List<String>, String> cell = new TableCell<List<String>, String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
} else {
setText(item);
}
}
};
cell.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (event.isSecondaryButtonDown() && !cell.isEmpty()) {
contextMenuValue.setValue(cell.getItem());
menu.show(cell, event.getScreenX(), event.getScreenY());
}
}
});
return cell;
}
});
}
public static void main(String[] args) {
launch(args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment