如何解决JavaFX ContextMenu源节点?
How to solve JavaFX ContextMenu source node?
我在 FXML 文件中创建的用户界面中有多个 CheckBox
。
<CheckBox..>
<contextMenu>
<ContextMenu>
<items>
<MenuItem text="%uncheckall" onAction="#uncheckAll" />
<MenuItem text="%checkall" onAction="#checkAll" />
</items>
</ContextMenu>
</contextMenu>
</CheckBox>
...
所有 CheckBox
es 使用相同的方法,即 uncheckAll
和 checkAll
。
我如何 return ContextMenu
的来源 Node
即 CheckBox
在 Event
的处理方法中?
@FXML private void uncheckAll(Event event) {
MenuItem mni = (MenuItem)event.getSource();
ContextMenu cm = mni.getParentPopup();
...???
}
API 中似乎没有任何内容可用于获取 Node
的上下文菜单的所有者,但是 ContextMenu
的祖先 class有方法 setUserData。您可以将CheckBox
设置为ContextMenu
的用户数据。这是一个仅使用代码的示例,即不使用 FXML。
CheckBox cb = new CheckBox("check");
MenuItem mi = new MenuItem("menu item");
mi.setOnAction(this::uncheckAll);
ContextMenu cm = new ContextMenu(mi);
cm.setUserData(cb);
cb.setContextMenu(cm);
然后,在您的 uncheckAll
方法中,您可以通过方法 getUserData
检索 CheckBox
。
@FXML private void uncheckAll(Event event) {
MenuItem mi = (MenuItem) event.getSource();
ContextMenu cm = mi.getParentPopup();
CheckBox cb = (CheckBox) cm.getUserData();
}
编辑
在 FXML 中,只需将 userData
属性添加到 ContextMenu
标签即可。
<ContextMenu userData="cbxGroup1">
您实际上可能不需要弄清楚上下文菜单附加到哪个复选框。
您的任务可能可以通过将标准 fxml 注入控制器来完成。
在您的 fxml 中为复选框分配 fx:id:
fx:id="cb"
将它注入你的控制器:
@FXML private CheckBox cb;
加载 fxml 后,您可以在控制器的任何位置通过名称引用复选框 cb
,包括在事件处理程序实现中。
@FXML private void uncheckAll(Event e) {
// you can refer to cb directly here.
}
由于您的界面中有多个复选框,请多次执行上述所有操作,包括事件处理程序定义。
如果您想共享事件处理程序的公共处理,您可以调用一个单独的方法,将引用传递给与事件处理程序关联的复选框。
@FXML private CheckBox cb1;
@FXML private CheckBox cb2;
@FXML private void uncheckAllForCb1(Event e) {
uncheckAll(cb1);
}
@FXML private void uncheckAllForCb2(Event e) {
uncheckAll(cb2);
}
private void uncheckAll(CheckBox sourceBox) {
// take action for box.
}
我在 FXML 文件中创建的用户界面中有多个 CheckBox
。
<CheckBox..>
<contextMenu>
<ContextMenu>
<items>
<MenuItem text="%uncheckall" onAction="#uncheckAll" />
<MenuItem text="%checkall" onAction="#checkAll" />
</items>
</ContextMenu>
</contextMenu>
</CheckBox>
...
所有 CheckBox
es 使用相同的方法,即 uncheckAll
和 checkAll
。
我如何 return ContextMenu
的来源 Node
即 CheckBox
在 Event
的处理方法中?
@FXML private void uncheckAll(Event event) {
MenuItem mni = (MenuItem)event.getSource();
ContextMenu cm = mni.getParentPopup();
...???
}
API 中似乎没有任何内容可用于获取 Node
的上下文菜单的所有者,但是 ContextMenu
的祖先 class有方法 setUserData。您可以将CheckBox
设置为ContextMenu
的用户数据。这是一个仅使用代码的示例,即不使用 FXML。
CheckBox cb = new CheckBox("check");
MenuItem mi = new MenuItem("menu item");
mi.setOnAction(this::uncheckAll);
ContextMenu cm = new ContextMenu(mi);
cm.setUserData(cb);
cb.setContextMenu(cm);
然后,在您的 uncheckAll
方法中,您可以通过方法 getUserData
检索 CheckBox
。
@FXML private void uncheckAll(Event event) {
MenuItem mi = (MenuItem) event.getSource();
ContextMenu cm = mi.getParentPopup();
CheckBox cb = (CheckBox) cm.getUserData();
}
编辑
在 FXML 中,只需将 userData
属性添加到 ContextMenu
标签即可。
<ContextMenu userData="cbxGroup1">
您实际上可能不需要弄清楚上下文菜单附加到哪个复选框。
您的任务可能可以通过将标准 fxml 注入控制器来完成。
在您的 fxml 中为复选框分配 fx:id:
fx:id="cb"
将它注入你的控制器:
@FXML private CheckBox cb;
加载 fxml 后,您可以在控制器的任何位置通过名称引用复选框 cb
,包括在事件处理程序实现中。
@FXML private void uncheckAll(Event e) {
// you can refer to cb directly here.
}
由于您的界面中有多个复选框,请多次执行上述所有操作,包括事件处理程序定义。
如果您想共享事件处理程序的公共处理,您可以调用一个单独的方法,将引用传递给与事件处理程序关联的复选框。
@FXML private CheckBox cb1;
@FXML private CheckBox cb2;
@FXML private void uncheckAllForCb1(Event e) {
uncheckAll(cb1);
}
@FXML private void uncheckAllForCb2(Event e) {
uncheckAll(cb2);
}
private void uncheckAll(CheckBox sourceBox) {
// take action for box.
}