我有一个在 JavaFX FXML 中的 Pane 上定义 ContextMenu 的工作示例,但我不确定它是否是最佳的。目前,只有 JavaFX 标准控件(例如 Button、TextField)定义用于指定弹出 ContextMenu 的属性。然而,我希望在 Pane 中的任何地方都有一个弹出菜单,在我的例子中是一个 VBox。

我采用了扩展 VBox 的方法来支持上下文菜单。这是一个“笨拙”的解决方案,但有效。有没有更好的方法?我是否缺少一些基本概念?

这是我的解决方案...

文件格式:

<?xml version="1.0" encoding="UTF-8"?> 
 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 
<?import custommenu.view.ContextMenuPane?> 
 
<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="custommenu.controller.CustomMenuController"> 
    <children> 
        <VBox fx:id="vbox" onContextMenuRequested="#showMenu" 
            onMousePressed="#hideMenu" prefHeight="200" prefWidth="200"> 
        </VBox> 
        <ContextMenuPane> 
            <contextMenu> 
                <ContextMenu fx:id="menu"> 
                    <items> 
                        <MenuItem text="add" onAction="#add" /> 
                    </items> 
                </ContextMenu> 
            </contextMenu> 
        </ContextMenuPane> 
    </children> 
</AnchorPane> 

自定义菜单 Pane ...
package custommenu.view; 
 
import javafx.scene.control.ContextMenu; 
import javafx.scene.layout.Pane; 
 
public class ContextMenuPane extends Pane { 
 
    private ContextMenu contextMenu; 
 
    public void setContextMenu(ContextMenu contextMenu) { 
        this.contextMenu = contextMenu; 
    } 
 
    public ContextMenu getContextMenu() { 
        return contextMenu; 
    } 
 
} 

Controller ...
package custommenu.controller; 
 
import javafx.fxml.FXML; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.input.ContextMenuEvent; 
import javafx.scene.layout.VBox; 
 
public class CustomMenuController { 
 
    @FXML private VBox vbox; 
    @FXML private ContextMenu menu; 
 
    @FXML public void add() { 
        System.out.println("add"); 
    } 
 
    @FXML 
    public void showMenu(ContextMenuEvent event) { 
        System.out.println("showMenu"); 
 
        menu.show(vbox, event.getScreenX(), event.getScreenY()); 
        event.consume(); 
    } 
 
    @FXML public void hideMenu() { 
        menu.hide(); 
    } 
} 

主应用...
package custommenu; 
import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Scene; 
import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 
 
public class CustomMenuApplication extends Application { 
 
    @Override 
    public void start(Stage primaryStage) throws Exception { 
        Pane myPane = (Pane)FXMLLoader.load(getClass().getResource("/custommenu/custom_menu_main.fxml")); 
        Scene scene = new Scene(myPane); 
        primaryStage.setScene(scene); 
        primaryStage.show(); 
    } 
 
     public static void main(String[] args) { 
         launch(args); 
     } 
} 

请您参考如下方法:

尝试在弹出窗口中执行此操作?捕获 MouseButton.SECONDARY 的 MouseEvent 检查并在弹出窗口中显示您的 VBox。

private void showContextMenu() // showContextMenu(MouseEvent event) 
{ 
    Popup popup = new Popup(); 
 
    VBox content = new VBox(); 
    Button b = new Button("Click Me!"); 
    b.setOnAction(new EventHandler<ActionEvent>() { }); 
    content.getChildren().addAll(b); 
 
    popup.getContent().add(content); 
    popup.setX(0); // or get mouse event x and y 
    popup.setY(0); // event.getY() 
    popup.setAutoHide(true); 
    popup.show(your popup owner); 
} 


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!