只显示MenuItems的JavaFX ContextMenu

时间:2014-10-22 21:18:24

标签: javafx-8

通过阅读“JavaFX 8:Example by Example”一书,我正在学习JavaFX。我正在研究关键组合和上下文菜单部分并遇到了问题。我正在探索的示例创建了一个窗口,其中包含已分配了键组合的简单菜单以及列出可用的各种键组合的中心区域。当您按其中一个组合时,窗口只显示您按下的组合。到目前为止一切都很好。但是,代码还定义了一个上下文菜单,在右键单击时显示(应显示)单个菜单项。事实上并没有显示任何东西。

我在代码上运行Debug并执行相关的行。我已经尝试分配其他菜单项,我尝试使用.addAll(...)分配菜单项,而不是在实例化上下文菜单时。他们都没有任何区别。

但是,当我将菜单分配给上下文菜单时,无论是在创建实例时还是使用.addAll,它都能正常工作。

我查找了ContextMenu(JavaFX 8 ContextMenu)的Java文档,它清楚地显示了分配给上下文菜单的菜单项,所以我很困惑。有人可以提出建议吗?相关行位于下面代码的底部。

感谢。

package jfx8ibe;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.effect.InnerShadow;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 *
 * @author cdea
 */
public class KeyCombinationsAndContextMenus extends Application {

    @Override
    public void start(Stage primaryStage) {
        BorderPane root = new BorderPane();
        Scene scene = new Scene(root, 530, 350, Color.WHITE);

        final StringProperty statusProperty = new SimpleStringProperty();

        InnerShadow iShadow = new InnerShadow();
        iShadow.setOffsetX(3.5f);
        iShadow.setOffsetY(3.5f);
        final Text status = new Text();
        status.setEffect(iShadow);
        status.setX(100);
        status.setY(50);
        status.setFill(Color.LIME);
        status.setFont(Font.font(null, FontWeight.BOLD, 35));
        //status.setTranslateY(50);

        status.textProperty().bind(statusProperty);
        statusProperty.set("Keyboard Shortcuts\n"
                + "Ctrl-N, \n"
                + "Ctrl-S, \n"
                + "Ctrl-X \n"
                + "Ctrl-Shift-E");
        root.setCenter(status);

        MenuBar menuBar = new MenuBar();
        menuBar.prefWidthProperty()
               .bind(primaryStage.widthProperty());
        root.setTop(menuBar);

        Menu fileMenu = new Menu("_File");
        fileMenu.setMnemonicParsing(true);
        menuBar.getMenus().add(fileMenu);

        MenuItem newItem = new MenuItem("_New");       
        newItem.setMnemonicParsing(true);

        newItem.setAccelerator(new KeyCodeCombination(KeyCode.N, 
                KeyCombination.SHORTCUT_DOWN));
        newItem.setOnAction(actionEvent -> statusProperty.set("Ctrl-N"));
        fileMenu.getItems().add(newItem);

        MenuItem saveItem = new MenuItem("_Save");
        saveItem.setMnemonicParsing(true);
        saveItem.setAccelerator(new KeyCodeCombination(KeyCode.S, 
                KeyCombination.SHORTCUT_DOWN));
        saveItem.setOnAction(actionEvent -> statusProperty.set("Ctrl-S"));
        fileMenu.getItems().add(saveItem);

        fileMenu.getItems().add(new SeparatorMenuItem());

        MenuItem exitItem = new MenuItem("Exit");
        exitItem.setAccelerator(new KeyCodeCombination(KeyCode.X, 
                KeyCombination.SHORTCUT_DOWN));

        exitItem.setOnAction(actionEvent -> {
            statusProperty.set("Ctrl-X");
            Platform.exit();
        });

        scene.getAccelerators().put(
                new KeyCodeCombination(KeyCode.E, 
                                       KeyCombination.SHORTCUT_DOWN, 
                                       KeyCombination.SHIFT_DOWN),
                () -> statusProperty.set("Ctrl-Shift-E")
        );

        fileMenu.getItems().add(exitItem);

        ContextMenu contextFileMenu = new ContextMenu(exitItem);

        primaryStage.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent me) -> {
            if (me.getButton() == MouseButton.SECONDARY) {
                contextFileMenu.show(root, me.getScreenX(), me.getScreenY());
            } else {
                contextFileMenu.hide();
            }
        });


        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}

1 个答案:

答案 0 :(得分:1)

您无法将相同的菜单项添加到两个不同的菜单中。由于您的退出项目已经在文件菜单中,因此它不会出现在上下文菜单中。

要在不同的地方重复使用此功能,我建议在JavaFX之上使用ControlsFX framework,尤其是actions API

E.g。

Action exitAction = new Action("Exit", event -> {
    statusProperty.set("Ctrl-X");
    Platform.exit();
});
exitAction.setAccelerator(new KeyCodeCombination(KeyCode.X, 
       KeyCombination.SHORTCUT_DOWN));

fileMenu.getItems().add(ActionUtils.createMenuItem(exitAction));

ContextMenu contextFileMenu = new ContextMenu(ActionUtils.createMenuItem(exitAction));
相关问题