San*_*til 11 popupmenu javafx-2
我是javafx的新手.我想在鼠标右键单击时显示弹出菜单.我找到一个教程在这里 和这里,但不明白.我想创建弹出菜单,在此链接上显示图像.
现在我正在创造舞台,但我不想舞台.我需要显示右键单击显示的弹出菜单,单击任意位置时关闭.
这是我的代码,我正在使用舞台,但我需要打开上面链接的弹出菜单.
public void MouseClickedOnTree(MouseEvent event) {
if (event.isSecondaryButtonDown()) {
System.out.println("secondary press");
final Stage optionstage = new Stage();
VBox vBox = new VBox(5);
vBox.setMinHeight(50);
vBox.setMinWidth(50);
Button btnNewTestBed = new Button("New Testbed");
btnNewTestBed.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
try {
optionstage.close();
stage.show();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}
});
Button btnOpenTestbed = new Button("Open Testbed");
btnOpenTestbed.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
optionstage.close();
}
});
optionstage.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ESCAPE) {
System.out.println("click on escape");
//Stage sb = (Stage) label.getScene().getWindow();//use any one object
if(optionstage.isShowing())
optionstage.close();
}
}
});
vBox.getChildren().addAll(btnNewTestBed, btnOpenTestbed);
optionstage.setScene(new Scene(vBox, 100, 100));
//stage.setScene(new Scene(new Group(new Text(50,50, "my second window"))));
optionstage.setX(event.getSceneX());
optionstage.setY(event.getScreenY());
optionstage.initStyle(StageStyle.UNDECORATED);
optionstage.show();
}
Run Code Online (Sandbox Code Playgroud)
请提供任何链接或参考.
Jam*_*s_D 24
代码的上下文不是很清楚:这是在事件处理程序中吗?如果是这样,它的事件处理程序是什么?如果没有,event开幕词中的内容是什么if?
您提供的两个链接非常复杂; 在JavaFX中(与Swing不同),您应该只考虑将现有Node类子类化为非常高级的用例.只需创建一个弹出菜单,您就不需要这种复杂程度.
创建弹出菜单的最简单方法是Control(或子类); 你只需要创建一个ContextMenu,添加MenuItems,并将其设置为contextMenu你的控件:
TextField textField = new TextField("Type Something"); // we will add a popup menu to this text field
final ContextMenu contextMenu = new ContextMenu();
MenuItem cut = new MenuItem("Cut");
MenuItem copy = new MenuItem("Copy");
MenuItem paste = new MenuItem("Paste");
contextMenu.getItems().addAll(cut, copy, paste);
cut.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Cut...");
}
});
// ...
textField.setContextMenu(contextMenu);
Run Code Online (Sandbox Code Playgroud)
如果你想ContextMenu在一个非Control(a Pane或a Shape)的节点上使用a ,你就没有setContextMenu(...)方法,所以你只需要做一些工作:
final AnchorPane pane = new AnchorPane();
// fill pane with nodes, etc
// create context menu and menu items as above
pane.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (event.isSecondaryButtonDown()) {
contextMenu.show(pane, event.getScreenX(), event.getScreenY());
}
}
});
Run Code Online (Sandbox Code Playgroud)
看到的Javadoc的ContextMenu或教程了解更多详情.
fuz*_*BSc 14
James_D已经提供了一个与教程一致的工作示例,但我遇到了问题.James说的是,对于任何类型Control的节点,打开上下文菜单的正确方法是使用Control.setContextMenu().但是与本教程相反,在非控制节点上注册上下文菜单的正确方法如下(Java 8):
pane.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, event -> {
contextMenu.show(pane, event.getScreenX(), event.getScreenY());
event.consume();
});
pane.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
contextMenu.hide();
});
Run Code Online (Sandbox Code Playgroud)
这与setContextMenu在幕后所做的一致.该setContextMenu实施控制使用和消耗的ContextMenuEvent但并没有消耗鼠标事件.这意味着如果您在窗格上为MouseEvent注册一个侦听器并在窗格中的Control上使用setContextMenu,则右键单击该控件将实际打开两个上下文菜单:当Pane侦听时,Control将侦听并使用ContextMenuEvent并使用MouseEvent.我在openddk-8的代码中发现,在Pane上注册ContextMenuEvent监听器解决了这个重复的上下文菜单问题.
我还发现,当用户点击其他地方时,默认情况下,在窗格上注册的菜单不会被忽略.不使用其事件的MOUSE_PRESSED侦听器确保在应该的时候关闭菜单.