2023-02-17 481
我正在学习javafx.scene.control.contextmenu,现在我面临一个问题:
如何从EventHandler中获取单击对象? event.source()和event.target()返回menuitem.
让我用一个例子解释:
我应该在函数句柄中写什么?
TextField text = new TextField();
Label label1 = new Label("hello");
Label label2 = new Label("world");
Label label3 = new Label("java");
ContextMenu menu = new ContextMenu();
MenuItem item = new MenuItem("copy to text field");
menu.getItems().add(item);
item.setOnAction(new EventHandler(){
public void handle(Event event) {
//I want to copy the text of the Label I clicked to TextField
event.consume();
}
});
label1.setContextMenu(menu);
label2.setContextMenu(menu);
label3.setContextMenu(menu);
编辑:我希望有一些简单的解决方案(一个衬里),但是如果没有很多复杂的方法.
您可以创建自己的ContextMenu实例,并将操作父添加到其上以供进一步参考:
public class Main extends Application {
TextField text = new TextField();
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
Label label1 = new Label("hello");
Label label2 = new Label("world");
Label label3 = new Label("java");
label1.setContextMenu(new MyContextMenu(label1));
label2.setContextMenu(new MyContextMenu(label2));
label3.setContextMenu(new MyContextMenu(label3));
HBox root = new HBox();
root.getChildren().addAll(text, label1, label2, label3);
Scene scene = new Scene(root, 300, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
private class MyContextMenu extends ContextMenu {
public MyContextMenu(Label label) {
MenuItem item = new MenuItem("copy to text field");
item.setOnAction(event -> {
// I want to copy the text of the Label I clicked to TextField
text.setText(label.getText());
event.consume();
});
getItems().add(item);
}
}
}
我认为最简单的方法是将节点保存为上下文菜单的用户数据.
EventHandler<? super ContextMenuEvent> eventHandle = e->menu.setUseData(e.getSource());
label1.setOnContextMenuRequested(eventHandle );
label2.setOnContextMenuRequested(eventHandle );
label3.setOnContextMenuRequested(eventHandle );
和行动:
EventHandler<ActionEvent> menuItemEvent = e->{
Node node = (Node) ((MenuItem)e.getSource()).getParentPopup().getUserData();
...
};
总结基本要求:掌握打开contextMenu的节点.根据Popupwindow的API Doc(ContextMenu的祖父母)的说法,这应该很容易实现
show(节点节点,…)
…弹出窗口与指定的所有者节点相关联…
noreflow noreferrer”> node getownernode() >
该弹出窗口的所有者的节点.
因此,menuitem作用的一般方法是
最后,该示例仅在磁带文本和验证中,它是按预期工作的…如果我们使用控件的Contection -Menuproperty,我们是 不是.在控件中不工作的原因是方法违反方法(可能是由错误引入的修复 contextMenu的textInputControls中的自动嵌套行为):在将其设置为ContectionMenu之后,它始终使用show(Window w, ..)将其设置为任何控件(实现详细信息:control.contextmenuproperty设置了flag setShowRelativeToWindow(true)触发错误的flag setShowRelativeToWindow(true) -Behavior)
现在我们该怎么做才能掌握自己的股票?有几个选项,没有一个很好:
中
前两个引入了额外的耦合,后者(除了肮脏的反射访问)可能会重新引起自动隐藏的问题(“固定”行为本身是肮脏的..违反”守护者” – 插入”保证)
最后,一个示例要播放:
public class ContextMenuOwnerSO extends Application {
private Parent createContent() {
TextField text = new TextField();
// the general approach to grab a property from the Node
// that the ContextMenu was opened on
EventHandler<ActionEvent> copyText = e -> {
MenuItem source = (MenuItem) e.getTarget();
ContextMenu popup = source.getParentPopup();
String ownerText = "<not available>";
if (popup != null) {
Node ownerNode = popup.getOwnerNode();
if (ownerNode instanceof Labeled) {
ownerText = ((Label) ownerNode).getText();
} else if (ownerNode instanceof Text) {
ownerText = ((Text) ownerNode).getText();
}
}
text.setText(ownerText);
};
MenuItem printOwner = new MenuItem("copy to text field");
printOwner.setOnAction(copyText);
// verify with manual managing of contextMenu
Text textNode = new Text("I DON'T HAVE a contextMenu property");
Label textNode2 = new Label("I'm NOT USING the contextMenu property");
ContextMenu nodeMenu = new ContextMenu();
nodeMenu.getItems().addAll(printOwner);
EventHandler<ContextMenuEvent> openRequest = e -> {
nodeMenu.show((Node) e.getSource(), Side.BOTTOM, 0, 0);
e.consume();
};
textNode.setOnContextMenuRequested(openRequest);
textNode2.setOnContextMenuRequested(openRequest);
Label label1 = new Label("I'm USING the contextMenu property");
ContextMenu menu = new ContextMenu() {
// force menu to have an owner node: this being the case, it is not hidden
// on mouse events inside its owner
//@Override
//public void show(Node anchor, double screenX, double screenY) {
// ReadOnlyObjectWrapper<Node> owner =
// (ReadOnlyObjectWrapper<Node>)
// FXUtils.invokeGetFieldValue(PopupWindow.class, this, "ownerNode");
// owner.set(anchor);
// super.show(anchor, screenX, screenY);
//}
};
MenuItem item = new MenuItem("copy to text field");
menu.getItems().add(item);
item.setOnAction(copyText);
label1.setContextMenu(menu);
// same effect as forcing the owner node
// has to be done after the last setting of contextMenuProperty
// setting to true was introduced as fix for
// https://bugs.openjdk.java.net/browse/JDK-8114638
//FXUtils.invokeGetMethodValue(ContextMenu.class, menu, "setShowRelativeToWindow", Boolean.TYPE, false);
VBox content = new VBox(10, textNode, textNode2, text, label1);
return content;
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent(), 400, 200));
stage.setTitle(FXUtils.version());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(ContextMenuOwnerSO.class.getName());
}
以上所述是小编给大家介绍的Javafx ContextMenu如何获得单击对象?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/34202.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态