TableView上的一行上下文菜单?

时间:2014-01-09 00:20:01

标签: java javafx contextmenu

我正在使用JavaFX,我的应用程序有一个表,我可以向表中添加元素,但我想创建一个上下文菜单,当我右键单击该行时,该菜单显示在一行上。

我有什么......

在Scene Builder中,我有一个方法,可以在激活上下文菜单时运行,但这不是我想要的。这很好,因为我可以随时以编程方式从表中获取所选项目。问题是,如果我保留我目前所拥有的,就是在所选元素上弹出上下文菜单。

contextMenu是包含菜单项的上下文菜单。 connectedUsers是TableView

以下是我能得到的最接近的内容,但这会显示TableView底部的上下文菜单

contextMenu.show(connectedUsers, Side.BOTTOM, 0, 0);

3 个答案:

答案 0 :(得分:13)

我相信最好的解决方案就是here中所讨论的。

table.setRowFactory(
    new Callback<TableView<Person>, TableRow<Person>>() {
        @Override
        public TableRow<Person> call(TableView<Person> tableView) {
            final TableRow<Person> row = new TableRow<>();
            final ContextMenu rowMenu = new ContextMenu();
            MenuItem editItem = new MenuItem("Edit");
            editItem.setOnAction(...);
            MenuItem removeItem = new MenuItem("Delete");
            removeItem.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent event) {
                    table.getItems().remove(row.getItem());
                }
            });
            rowMenu.getItems().addAll(editItem, removeItem);

            // only display context menu for non-null items:
            row.contextMenuProperty().bind(
              Bindings.when(Bindings.isNotNull(row.itemProperty()))
              .then(rowMenu)
              .otherwise((ContextMenu)null));
            return row;
    }
});

答案 1 :(得分:10)

试试这个..

ContextMenu cm = new ContextMenu();
MenuItem mi1 = new MenuItem("Menu 1");
cm.getItems().add(mi1);
MenuItem mi2 = new MenuItem("Menu 2");
cm.getItems().add(mi2);

table.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {

    @Override
    public void handle(MouseEvent t) {
        if(t.getButton() == MouseButton.SECONDARY) {
            cm.show(table, t.getScreenX(), t.getScreenY());
        }
    }
});

答案 2 :(得分:10)

JavaFX 8(使用Lambda):

package application;

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;


public class Main extends Application {

    public VBox resultsBox;
    public ScrollPane scroll;
    public List<CustomClass> results = new ArrayList<CustomClass>();
    public Button returnToResults;

    public class CustomClass extends HBox {
        public List<CustomClass> items;

        public boolean hasItems() {
            return items != null && !items.isEmpty();
        }

        public CustomClass(String text, boolean hasItems) {
            setMinHeight(90);
            setPrefHeight(90);
            setMaxHeight(90);
            setMaxWidth(Double.MAX_VALUE);
            setAlignment(Pos.CENTER);
            setStyle("-fx-border-color: red");

            Button children = new Button("View Children "+text);
            children.setDisable(!hasItems);
            getChildren().add(children);
            children.setOnAction(e -> {
                viewChildren(this);
            });

            if(hasItems) {
                items = new ArrayList<CustomClass>();
                for(int i=0; i<10; i++) {
                    items.add(new CustomClass(text+"."+i, false));
                }
            }
        }
    }

    public double vValue = 0.0;

    public void viewChildren(CustomClass cc) {
        Platform.runLater(() -> {
            vValue = scroll.getVvalue();
            System.out.println("0. "+vValue);
            resultsBox.getChildren().clear();
            resultsBox.getChildren().addAll(cc.items);
            returnToResults.setDisable(false);
        });
    }

    public void returnToResults() {
        Platform.runLater(() -> {
            resultsBox.getChildren().clear();
            resultsBox.getChildren().addAll(results);
            System.out.println("1. "+vValue+"    "+scroll.getVvalue());
            scroll.setVvalue(vValue);
            System.out.println("2. "+vValue+" -> "+scroll.getVvalue()); // Sets correctly.
            returnToResults.setDisable(true);
        });
    }

    public void start(Stage stage) throws Exception {

        resultsBox = new VBox(5);
        resultsBox.setFillWidth(true);
        resultsBox.setAlignment(Pos.TOP_CENTER);

        scroll = new ScrollPane(resultsBox);
        scroll.setMaxWidth(Double.MAX_VALUE);
        scroll.setFitToWidth(true);

        for(int i=0; i<100; i++) {
            results.add(new CustomClass("#"+i, true));
        }

        resultsBox.getChildren().addAll(results);

        returnToResults = new Button("Return to Results");
        returnToResults.setStyle("-fx-base: green");
        returnToResults.setDisable(true);
        returnToResults.setOnAction(e -> {
            returnToResults();
        });

        BorderPane root = new BorderPane();
        root.setCenter(scroll);
        root.setBottom(returnToResults);

        Scene scene = new Scene(root,400,400);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

另见: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/ContextMenu.html