package com.revolsys.swing.tree; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.Arrays; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeWillExpandListener; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreePath; import com.revolsys.swing.menu.MenuFactory; import com.revolsys.swing.parallel.Invoke; import com.revolsys.swing.tree.node.LazyLoadTreeNode; import com.revolsys.swing.tree.node.OpenStateTreeNode; public class BaseTreeListener implements MouseListener, TreeExpansionListener, TreeModelListener, TreeWillExpandListener { private BaseTree tree; public BaseTreeListener(final BaseTree baseTree) { this.tree = baseTree; baseTree.addMouseListener(this); baseTree.addTreeExpansionListener(this); baseTree.addTreeWillExpandListener(this); final DefaultTreeModel model = baseTree.getModel(); model.addTreeModelListener(this); } public void close() { if (this.tree != null) { this.tree.removeMouseListener(this); this.tree.removeTreeExpansionListener(this); this.tree.removeTreeWillExpandListener(this); final DefaultTreeModel model = this.tree.getModel(); model.removeTreeModelListener(this); this.tree = null; } } @Override public void mouseClicked(final MouseEvent e) { final int x = e.getX(); final int y = e.getY(); final TreePath path = this.tree.getPathForLocation(x, y); if (path != null) { final Object node = path.getLastPathComponent(); if (node instanceof MouseListener) { final MouseListener listener = (MouseListener)node; Object userObject = null; if (node instanceof BaseTreeNode) { final BaseTreeNode treeNode = (BaseTreeNode)node; userObject = treeNode.getUserObject(); } if (userObject == null) { MenuFactory.setMenuSource(userObject); } else { MenuFactory.setMenuSource(node); } listener.mouseClicked(e); } } } @Override public void mouseEntered(final MouseEvent e) { } @Override public void mouseExited(final MouseEvent e) { } @Override public void mousePressed(final MouseEvent e) { if (e.isPopupTrigger()) { popup(e); } } @Override public void mouseReleased(final MouseEvent e) { if (e.isPopupTrigger()) { popup(e); } } private void popup(final MouseEvent e) { if (this.tree.isMenuEnabled()) { final int x = e.getX() + 5; final int y = e.getY(); final TreePath path = this.tree.getPathForLocation(x, y); if (path != null) { TreePath[] selectionPaths = this.tree.getSelectionPaths(); if (selectionPaths == null || !Arrays.asList(selectionPaths).contains(path)) { selectionPaths = new TreePath[] { path }; this.tree.setSelectionPaths(selectionPaths); } final MenuFactory menu = this.tree.getMenuFactory(path); final BaseTreeNode node = (BaseTreeNode)path.getLastPathComponent(); BaseTree.setMenuNode(node); Object userObject = node.getUserObject(); if (userObject == null) { userObject = node; } if (menu != null) { menu.showMenu(userObject, this.tree, x, y); } } this.tree.repaint(); } } @Override public void treeCollapsed(final TreeExpansionEvent event) { } @Override public void treeExpanded(final TreeExpansionEvent event) { } @Override public void treeNodesChanged(final TreeModelEvent e) { } @Override public void treeNodesInserted(final TreeModelEvent e) { final TreePath treePath = e.getTreePath(); for (final Object child : e.getChildren()) { if (child instanceof OpenStateTreeNode) { final OpenStateTreeNode openState = (OpenStateTreeNode)child; if (openState.isOpen()) { final TreePath childTreePath = treePath.pathByAddingChild(child); Invoke.background("", () -> this.tree.setExpandedState(childTreePath, true)); } } } } @Override public void treeNodesRemoved(final TreeModelEvent e) { } @Override public void treeStructureChanged(final TreeModelEvent e) { } @Override public void treeWillCollapse(final TreeExpansionEvent event) throws ExpandVetoException { } @Override public void treeWillExpand(final TreeExpansionEvent event) throws ExpandVetoException { final TreePath path = event.getPath(); final Object node = path.getLastPathComponent(); if (node instanceof LazyLoadTreeNode) { final LazyLoadTreeNode lazyLoadTreeNode = (LazyLoadTreeNode)node; lazyLoadTreeNode.loadChildren(); } } }