001 package nl.cwi.sen1.gui.plugin; 002 003 import java.awt.BorderLayout; 004 import java.awt.Component; 005 import java.awt.Graphics2D; 006 import java.awt.Image; 007 import java.awt.event.MouseListener; 008 import java.awt.image.BufferedImage; 009 import java.util.Enumeration; 010 011 import javax.swing.Icon; 012 import javax.swing.ImageIcon; 013 import javax.swing.JPanel; 014 import javax.swing.JScrollPane; 015 import javax.swing.JTree; 016 import javax.swing.event.TreeSelectionEvent; 017 import javax.swing.event.TreeSelectionListener; 018 import javax.swing.tree.DefaultTreeCellRenderer; 019 import javax.swing.tree.TreePath; 020 021 import nl.cwi.sen1.gui.plugin.data.Module; 022 import nl.cwi.sen1.gui.plugin.data.ModuleSelectionListener; 023 import nl.cwi.sen1.gui.plugin.data.ModuleSelectionModel; 024 import nl.cwi.sen1.gui.plugin.data.ModuleTreeModel; 025 import nl.cwi.sen1.gui.plugin.data.ModuleTreeNode; 026 import aterm.ATerm; 027 028 public class ModuleTree extends JPanel { 029 private JTree tree; 030 031 private Enumeration<TreePath> expansionState; 032 033 private final ModuleTreeModel manager; 034 035 public ModuleTree(Navigator modulebrowser, final ModuleTreeModel manager) { 036 this.manager = manager; 037 038 setLayout(new BorderLayout()); 039 040 tree = new JTree(manager); 041 tree.setRootVisible(false); 042 tree.setShowsRootHandles(true); 043 tree.setExpandsSelectedPaths(true); 044 tree.setSelectionModel(new ModuleSelectionModel()); 045 tree.addTreeSelectionListener(new TreeSelectionListener() { 046 public void valueChanged(TreeSelectionEvent e) { 047 manager.selectModule(getCurrentModule()); 048 } 049 }); 050 051 ImageIcon folderIcon = new ImageIcon(getClass().getResource( 052 "/resources/images/folder.png")); 053 ImageIcon documentIcon = new ImageIcon(getClass().getResource( 054 "/resources/images/document.png")); 055 ImageIcon errorOverlayIcon = new ImageIcon(getClass().getResource( 056 "/resources/images/error-overlay.png")); 057 058 ImageIcon errorFolderIcon = createOverlayIcon(folderIcon, errorOverlayIcon); 059 ImageIcon errorDocumentIcon = createOverlayIcon(documentIcon, errorOverlayIcon); 060 061 tree.setCellRenderer(new TreeIconCellRenderer(folderIcon, documentIcon, 062 errorFolderIcon, errorDocumentIcon)); 063 064 add(new JScrollPane(tree)); 065 066 manager.addModuleSelectionListener(new ModuleSelectionListener() { 067 public void moduleSelected(Module module) { 068 if (module != null) { 069 TreePath path = manager.makeTreePath(module.getFile()); 070 tree.setSelectionPath(path); 071 tree.scrollPathToVisible(path); 072 } else { 073 tree.clearSelection(); 074 } 075 } 076 }); 077 } 078 079 private ImageIcon createOverlayIcon(ImageIcon icon, ImageIcon overlay) { 080 Image image = icon.getImage(); 081 BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), 082 image.getHeight(null), BufferedImage.TYPE_INT_ARGB); 083 084 Graphics2D g = bufferedImage.createGraphics(); 085 g.drawImage(image, null, null); 086 g.drawImage(overlay.getImage(), 0, 0, null); 087 g.dispose(); 088 return new ImageIcon(bufferedImage); 089 } 090 091 public void saveExpansionState() { 092 expansionState = tree.getExpandedDescendants(new TreePath(tree 093 .getModel().getRoot())); 094 } 095 096 public void loadExpansionState() { 097 if (expansionState != null) { 098 while (expansionState.hasMoreElements()) { 099 TreePath treePath = expansionState.nextElement(); 100 tree.expandPath(treePath); 101 } 102 } 103 } 104 105 public ATerm selectModule(int X, int Y) { 106 TreePath path = tree.getClosestPathForLocation(X, Y); 107 if (path != null) { 108 tree.setSelectionPath(path); 109 ModuleTreeNode selectedModule = (ModuleTreeNode) path 110 .getLastPathComponent(); 111 return selectedModule.getId(); 112 } 113 return null; 114 } 115 116 private Module getCurrentModule() { 117 TreePath path = tree.getSelectionPath(); 118 119 if (path != null) { 120 ModuleTreeNode selectedModule = (ModuleTreeNode) path 121 .getLastPathComponent(); 122 return manager.getModule(selectedModule.getId()); 123 } 124 125 return null; 126 } 127 128 public void addMouseListener(MouseListener l) { 129 tree.addMouseListener(l); 130 } 131 132 class TreeIconCellRenderer extends DefaultTreeCellRenderer { 133 private Icon folderIcon; 134 private Icon documentIcon; 135 private Icon errorFolderIcon; 136 private Icon errorDocumentIcon; 137 138 public TreeIconCellRenderer(Icon folderIcon, Icon documentIcon, 139 Icon errorFolderIcon, Icon errorDocumentIcon) { 140 this.folderIcon = folderIcon; 141 this.documentIcon = documentIcon; 142 this.errorFolderIcon = errorFolderIcon; 143 this.errorDocumentIcon = errorDocumentIcon; 144 } 145 146 public Component getTreeCellRendererComponent(JTree tree, Object value, 147 boolean sel, boolean expanded, boolean leaf, int row, 148 boolean hasFocus) { 149 150 super.getTreeCellRendererComponent(tree, value, sel, expanded, 151 leaf, row, hasFocus); 152 153 ModuleTreeNode treeNode = (ModuleTreeNode) value; 154 if (treeNode.hasError() == true) { 155 if (treeNode.isLeaf() == true) { 156 setIcon(errorDocumentIcon); 157 } else { 158 setIcon(errorFolderIcon); 159 } 160 } else { 161 if (treeNode.isLeaf() == true) { 162 setIcon(documentIcon); 163 } else { 164 setIcon(folderIcon); 165 } 166 } 167 168 return this; 169 } 170 } 171 }