Skip to content

Instantly share code, notes, and snippets.

@Maran23
Last active May 25, 2023 09:11
Example of an implementation for a custom TableHeaderRow with overridden showColumnMenu()
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Dialog;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TableColumnBase;
import javafx.scene.control.TableView;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.skin.TableHeaderRow;
import javafx.scene.control.skin.TableViewSkinBase;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
public class CustomTableHeaderRow extends TableHeaderRow {
private final TableViewSkinBase skin;
public CustomTableHeaderRow(TableViewSkinBase skin) {
super(skin);
this.skin = skin;
}
@Override
protected void showColumnMenu(MouseEvent mouseEvent) {
VBox box = new VBox(5);
ScrollPane pane = new ScrollPane(box);
pane.setFitToWidth(true);
// This would be easier with an interface or (abstract) class.
ObservableList<? extends TableColumnBase<?, ?>> columns = FXCollections.emptyObservableList();
if (skin.getSkinnable() instanceof TableView<?> tableView) {
columns = tableView.getColumns();
} else if (skin.getSkinnable() instanceof TreeTableView<?> treeTableView) {
columns = treeTableView.getColumns();
}
for (TableColumnBase<?, ?> column : columns) {
CheckBox checkBox = new CheckBox(column.getText());
checkBox.selectedProperty().bindBidirectional(column.visibleProperty());
box.getChildren().add(checkBox);
}
Dialog<Void> dialog = new Dialog<>();
dialog.initOwner(getScene().getWindow());
dialog.getDialogPane().setContent(pane);
dialog.setTitle("Columns");
dialog.getDialogPane().getButtonTypes().add(ButtonType.APPLY);
dialog.show();
// For a custom context menu
ContextMenu contextMenu = new ContextMenu(new MenuItem("abc"));
// Note: A bit inconvenient here: Target is either the cornerRegion or the 'image' StackPane,
// which is a children of the cornerRegion.
Node target = (Node) mouseEvent.getTarget();
contextMenu.show(target, Side.BOTTOM, 0, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment