001package jmri.util; 002 003import java.awt.event.ActionEvent; 004import java.awt.event.ActionListener; 005import java.awt.event.MouseAdapter; 006import java.awt.event.MouseEvent; 007import javax.swing.JComponent; 008import javax.swing.JMenuItem; 009import javax.swing.JPopupMenu; 010import javax.swing.JTree; 011import javax.swing.tree.DefaultMutableTreeNode; 012import javax.swing.tree.DefaultTreeModel; 013import javax.swing.tree.TreePath; 014 015/** 016 * JTree subclass that supports a popup menu. 017 * <p> 018 * From the 019 * <A HREF="http://www.java-tips.org/java-se-tips/javax.swing/have-a-popup-attached-to-a-jtree.html">Java 020 * Tips</a> web site. 021 */ 022class JTreeWithPopup extends JTree implements ActionListener { 023 024 JPopupMenu popup; 025 JMenuItem mi; 026 027 JTreeWithPopup(DefaultMutableTreeNode dmtn) { 028 super(dmtn); 029 // define the popup 030 popup = new JPopupMenu(); 031 mi = new JMenuItem("Insert a children"); 032 mi.addActionListener(this); 033 mi.setActionCommand("insert"); 034 popup.add(mi); 035 mi = new JMenuItem("Remove this node"); 036 mi.addActionListener(this); 037 mi.setActionCommand("remove"); 038 popup.add(mi); 039 popup.setOpaque(true); 040 popup.setLightWeightPopupEnabled(true); 041 042 addMouseListener( 043 new MouseAdapter() { 044 @Override 045 public void mouseReleased(MouseEvent e) { 046 if (e.isPopupTrigger()) { 047 popup.show((JComponent) e.getSource(), e.getX(), e.getY()); 048 } 049 } 050 } 051 ); 052 053 } 054 055 @Override 056 public void actionPerformed(ActionEvent ae) { 057 DefaultMutableTreeNode dmtn, node; 058 059 TreePath path = this.getSelectionPath(); 060 dmtn = (DefaultMutableTreeNode) path.getLastPathComponent(); 061 if (ae.getActionCommand().equals("insert")) { 062 node = new DefaultMutableTreeNode("children"); 063 dmtn.add(node); 064 // thanks to Yong Zhang for the tip for refreshing the tree structure. 065 ((DefaultTreeModel) this.getModel()).nodeStructureChanged(dmtn); 066 } 067 if (ae.getActionCommand().equals("remove")) { 068 node = (DefaultMutableTreeNode) dmtn.getParent(); 069 // Bug fix by essam 070 int nodeIndex = node.getIndex(dmtn); // declare an integer to hold the selected nodes index 071 dmtn.removeAllChildren(); // remove any children of selected node 072 node.remove(nodeIndex); // remove the selected node, retain its siblings 073 ((DefaultTreeModel) this.getModel()).nodeStructureChanged(dmtn); 074 } 075 } 076}