我正在尝试在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; } }
b1nary.atr0p.. 31
这项任务很容易完成,以下是您所需要的:
//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()); } }
然后,您可以将此自定义侦听器添加到所需的树.
这项任务很容易完成,以下是您所需要的:
//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()); } }
然后,您可以将此自定义侦听器添加到所需的树.
取自JTree API
// 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);