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 }