[英]Right-click context menu for Java JTree?
我正在尝试在Java JTree中实现弹出菜单。 我已经对DefaultTreeCellRenderer(更改节点外观)和DefaultTreeCellEditor(创建组件以附加事件侦听器)进行了分类,因为显然DefaultTreeCellRenderer.getTreeCellRendererComponent()返回的组件不能这样做吗?)。 我真的不想“编辑”节点,只需在节点右键单击时弹出菜单,但这是我现在想到的唯一方法......
下面是我到目前为止的代码 - 我只想弄清楚如何捕获MouseEvents。 它有点工作,但很糟糕。 有什么更好的方法来完成我在这里要做的事情?
private class My_TreeCellRenderer extends DefaultTreeCellRenderer {
My_TreeCellRenderer() {
super ();
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
// set label text and tool tips
setText(((My_Object)value).getTreeLabel());
setToolTipText(((My_Object)value).getTreeToolTip());
return this;
}
}
private class My_TreeCellEditor extends DefaultTreeCellEditor {
private MouseAdapter ma;
My_TreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
super (tree, renderer);
ma = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger()) {
System.out.println("My Popup");
}
}
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
System.out.println("My Popup");
}
}
};
}
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) {
String src_filename = null;
// return non-editing component
Component c = renderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, true);
// add mouse listener if it's not listening already
MouseListener mouseListeners[] = c.getMouseListeners();
int i;
for (i=0; i < mouseListeners.length && mouseListeners[i] != ma; i++);
if (i >= mouseListeners.length)
c.addMouseListener(ma);
return c;
}
protected boolean canEditImmediately(EventObject event) {
if (event instanceof MouseEvent && ((MouseEvent)event).getClickCount() == 1)
return true;
else
return false;
}
}
这个任务很容易完成,以下是您所需要的:
//create a class which implements the MouseListener interface and
//implement the following in your overridden mouseClicked method
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
int row = tree.getClosestRowForLocation(e.getX(), e.getY());
tree.setSelectionRow(row);
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
然后,您可以将此自定义侦听器添加到所需的树。
// If you are interested in detecting either double-click events or when a user clicks on a node, regardless of whether or not it was selected, we recommend you do the following:
final JTree tree = ...;
MouseListener ml = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY());
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
if(selRow != -1) {
if(e.getClickCount() == 1) {
mySingleClick(selRow, selPath);
}
else if(e.getClickCount() == 2) {
myDoubleClick(selRow, selPath);
}
}
}
};
tree.addMouseListener(ml);
当然,您需要稍微修改它以进行右键单击而不是左键单击
感谢大家。 当我花费大量精力实现一个简单的弹出窗口时,我知道出了什么问题。
我首先驳回了这一思路,因为使用x和y坐标找到我正在寻找的节点感觉很奇怪,但我想这是做到这一点的方法。
// add MouseListener to tree
MouseAdapter ma = new MouseAdapter() {
private void myPopupEvent(MouseEvent e) {
int x = e.getX();
int y = e.getY();
JTree tree = (JTree)e.getSource();
TreePath path = tree.getPathForLocation(x, y);
if (path == null)
return;
tree.setSelectionPath(path);
My_Obj obj = (My_Obj)path.getLastPathComponent();
String label = "popup: " + obj.getTreeLabel();
JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem(label));
popup.show(tree, x, y);
}
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger()) myPopupEvent(e);
}
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) myPopupEvent(e);
}
};
(...)
JTree tree = new JTree();
tree.addMouseListener(ma);
我认为你的做法比他们需要的更难。
JTree上有几个“add_foo_Listener”方法。 实现其中一个(TreeSelectionListener看起来正确),然后你有了当前选择的节点。
实现一个MouseListener,以便您可以检测到右键单击事件(并将其添加到JTree,因为JTree是一个组件),然后您应该拥有发布上下文相关菜单所需的一切。
有关更多详细信息,请查看本教程 。
渲染器只是一个短暂的“橡皮图章”,因此添加输入监听器不会特别有用。 正如你所指出的那样,编辑只有在你打手势编辑之后才会出现。 所以你想为JTree添加一个监听器(假设它没有实现为复合组件)。
调用addRightClickListener()
以将右键单击上下文菜单侦听器添加到JTree
。 这两个覆盖都是为了适当的跨平台功能( Windows
和Linux
在这里不同)。
private void addRightClickListener()
{
MouseListener mouseListener = new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent mouseEvent)
{
handleContextMenu(mouseEvent);
}
@Override
public void mouseReleased(MouseEvent mouseEvent)
{
handleContextMenu(mouseEvent);
}
};
tree.addMouseListener(mouseListener);
}
private void handleContextMenu(MouseEvent mouseEvent)
{
if (mouseEvent.isPopupTrigger())
{
MyContextMenu contextMenu = new MyContextMenu();
contextMenu.show(mouseEvent.getComponent(),
mouseEvent.getX(),
mouseEvent.getY());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.