我正在制作一个MenuBar
,我不想按Menu
之类的功能:“文件”,然后执行操作。比如打开另一个fxml,或写一些输出的例子。
我想在MenuItem
之类的“文件”中使用Menu
(谎言“关于”)的功能。
package model;
import static java.lang.System.out;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* Example of creating menus in JavaFX.
*
* @author Dustin
*/
public class JavaFxMenus extends Application
{
/**
* Build menu bar with included menus for this demonstration.
*
* @param menuWidthProperty Width to be bound to menu bar width.
* @return Menu Bar with menus included.
*/
private MenuBar buildMenuBarWithMenus(final ReadOnlyDoubleProperty menuWidthProperty)
{
final MenuBar menuBar = new MenuBar();
// Prepare left-most 'File' drop-down menu
final Menu fileMenu = new Menu("File");
menuBar.getMenus().add(fileMenu);
//menuBar.getOnMouseClicked().handle(this);
// Prepare 'Examples' drop-down menu
final Menu examplesMenu = new Menu("JavaFX 2.0 Examples");
examplesMenu.getItems().add(new MenuItem("Text Example"));
examplesMenu.getItems().add(new MenuItem("Objects Example"));
examplesMenu.getItems().add(new MenuItem("Animation Example"));
menuBar.getMenus().add(examplesMenu);
// Prepare 'Help' drop-down menu
final Menu helpMenu = new Menu("Help");
helpMenu.setOnAction(null);
final MenuItem searchMenuItem = new MenuItem("Search");
searchMenuItem.setDisable(true);
helpMenu.getItems().add(searchMenuItem);
final MenuItem onlineManualMenuItem = new MenuItem("Online Manual");
onlineManualMenuItem.setVisible(false);
helpMenu.getItems().add(onlineManualMenuItem);
helpMenu.getItems().add(new SeparatorMenuItem());
final MenuItem aboutMenuItem =
MenuItemBuilder.create()
.text("About")
.onAction(
new EventHandler<ActionEvent>()
{
@Override public void handle(ActionEvent e)
{
out.println("You clicked on About!");
}
})
.accelerator(
new KeyCodeCombination(
KeyCode.A, KeyCombination.CONTROL_DOWN))
.build();
helpMenu.getItems().add(aboutMenuItem);
menuBar.getMenus().add(helpMenu);
// bind width of menu bar to width of associated stage
menuBar.prefWidthProperty().bind(menuWidthProperty);
return menuBar;
}
/**
* Start of JavaFX application demonstrating menu support.
*
* @param stage Primary stage.
*/
@Override
public void start(final Stage stage)
{
stage.setTitle("Creating Menus with JavaFX 2.0");
final Group rootGroup = new Group();
final Scene scene = new Scene(rootGroup, 800, 400, Color.WHEAT);
final MenuBar menuBar = buildMenuBarWithMenus(stage.widthProperty());
rootGroup.getChildren().add(menuBar);
stage.setScene(scene);
stage.show();
}
/**
* Main executable function for running examples.
*
* @param arguments Command-line arguments: none expected.
*/
public static void main(final String[] arguments)
{
Application.launch(arguments);
}
}
答案 0 :(得分:16)
AFAIK,A Menu
,如果没有任何添加的子菜单或Menuitem
,则不会在点击,显示或隐藏时触发事件。但是,解决方法是将图形设置为此图形节点将处理鼠标点击的位置,例如
Label menuLabel = new Label("File");
menuLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
Stage myDialog = new Stage();
myDialog.initModality(Modality.WINDOW_MODAL);
Scene myDialogScene = new Scene(VBoxBuilder.create()
.children(new Text("Hello! it's My Dialog."))
.alignment(Pos.CENTER)
.padding(new Insets(10))
.build());
myDialog.setScene(myDialogScene);
myDialog.show();
}
});
Menu fileMenuButton = new Menu();
fileMenuButton.setGraphic(menuLabel);
menuBar.getMenus().add(fileMenuButton);
这种方法的一个缺点是标签没有覆盖菜单的所有空格,因此点击菜单边缘不会触发鼠标事件。通过取消注释上面的menuLabel.setStyle
行来查看此内容。但是我可以通过玩CSS
样式来解决这个问题
代码部分取自Create Dialog using Stage。您还可以使用FXML
将myDialog
文件加载到FXMLLoader
阶段。网上有很多关于它的例子。
答案 1 :(得分:4)
最近我遇到了同样的问题,这就是我做的事情
@FXML private Menu myMenu;
@Override
public void initialize(URL url, ResourceBundle rb) {
myMenu.setGraphic(
ButtonBuilder.create()
.text("btnText")
.onAction(new EventHandler<ActionEvent>(){
@Override public void handle(ActionEvent t) {
//TODO
} })
.build()
);
}
答案 2 :(得分:1)
最近我遇到了同样的问题,这是我的出路:
我在菜单中有一个menuItem,其行为就像单击了menuItem一样(在你的File
菜单中)。所以你可以做的是有一个menuItem Dummy_menuItem
final Menu fileMenu = new Menu("File");
fileMenu.getItems().add(new MenuItem("Dummy_menuItem"));
menuBar.getMenus().add(fileMenu);
然后点击File
菜单,触发Dummy_menuItem
menuItem或您希望拥有的任何功能。为了确定哪个菜单应该具有此属性,我使用numberOfMenuItems
来获取菜单栏菜单中的menuItem数量
if (numberOfMenuItems == 1) {
menu.showingProperty().addListener(
(observableValue, oldValue, newValue) -> {
if (newValue) {
// the first menuItem is triggered
menu.getItems().get(0).fire();
}
}
);
}
结果是Dummy_menuItem
在点击File
菜单或任何具有一个menuItem的菜单时没有显示menuItem的上下文时被触发。因此,您似乎点击了File
菜单,并被重定向到另一个页面或其他任何内容。
希望这会有所帮助!!
答案 3 :(得分:1)
结合我们的朋友@Dota2的答案,我构建了一个助手类来触发Menu
onAction(Menu menu)
事件,即使它没有任何MenuItem
事件里面。这是静态辅助方法:
public static void onAction(Menu menu)
{
final MenuItem menuItem = new MenuItem();
menu.getItems().add(menuItem);
menu.addEventHandler(Menu.ON_SHOWN, event -> menu.hide());
menu.addEventHandler(Menu.ON_SHOWING, event -> menu.fire());
}
然后你打电话:
YourHelperClass.onAction(myMenu);
准备好了!我希望这会有所帮助。
答案 4 :(得分:-2)
我认为你不能在主菜单标签上允许任何操作。
但是,您可以创建一个堆栈窗格,并用文本和菜单栏填充它。