001 package nl.cwi.sen1.error.viewer; 002 003 import java.awt.BorderLayout; 004 import java.awt.event.ActionEvent; 005 import java.net.URL; 006 import java.util.Enumeration; 007 008 import javax.swing.AbstractAction; 009 import javax.swing.Action; 010 import javax.swing.ImageIcon; 011 import javax.swing.JFrame; 012 import javax.swing.JPanel; 013 import javax.swing.JScrollPane; 014 import javax.swing.JToolBar; 015 import javax.swing.JTree; 016 import javax.swing.SwingConstants; 017 import javax.swing.tree.DefaultMutableTreeNode; 018 import javax.swing.tree.DefaultTreeCellRenderer; 019 import javax.swing.tree.DefaultTreeModel; 020 import javax.swing.tree.TreeNode; 021 import javax.swing.tree.TreePath; 022 import javax.swing.tree.TreeSelectionModel; 023 024 import nl.cwi.sen1.error.model.ErrorDecorator; 025 import errorapi.types.Summary; 026 027 public class ErrorPanel extends JPanel { 028 private JTree tree; 029 030 private ErrorDecorator errorDecorator; 031 032 private DefaultMutableTreeNode top; 033 034 private DefaultTreeModel treeModel; 035 036 private Enumeration<TreePath> expansionState; 037 038 public ErrorPanel() { 039 super(new BorderLayout()); 040 041 JToolBar toolBar = new JToolBar("Error ToolBar", 042 SwingConstants.VERTICAL); 043 addButtons(toolBar); 044 045 errorDecorator = new ErrorDecorator(); 046 047 top = new DefaultMutableTreeNode("Errors"); 048 treeModel = new DefaultTreeModel(top); 049 050 tree = new JTree(treeModel); 051 tree.getSelectionModel().setSelectionMode( 052 TreeSelectionModel.SINGLE_TREE_SELECTION); 053 tree.setRootVisible(false); 054 tree.setShowsRootHandles(true); 055 056 DefaultTreeCellRenderer renderer = new ErrorTreeCellRenderer(); 057 058 tree.setCellRenderer(renderer); 059 060 JScrollPane scrollPane = new JScrollPane(tree); 061 add(toolBar, BorderLayout.WEST); 062 add(scrollPane, BorderLayout.CENTER); 063 } 064 065 public JTree getTree() { 066 return tree; 067 } 068 069 public void saveExpansionState() { 070 expansionState = tree.getExpandedDescendants(new TreePath(tree 071 .getModel().getRoot())); 072 } 073 074 public void loadExpansionState() { 075 if (expansionState != null) { 076 while (expansionState.hasMoreElements()) { 077 TreePath treePath = expansionState.nextElement(); 078 tree.expandPath(treePath); 079 } 080 } 081 } 082 083 public void addError(Summary summary) { 084 errorDecorator.addErrors(top, summary); 085 saveExpansionState(); 086 ((DefaultTreeModel) tree.getModel()).reload(); 087 loadExpansionState(); 088 tree.expandPath(new TreePath(top)); 089 } 090 091 public void removeAllMatchingErrors(String producer, String id) { 092 errorDecorator.removeAllMatchingErrors(top, producer, id); 093 saveExpansionState(); 094 treeModel.reload(); 095 loadExpansionState(); 096 } 097 098 public void removeAllMatchingErrors(String path) { 099 errorDecorator.removeAllMatchingErrors(top, path); 100 saveExpansionState(); 101 treeModel.reload(); 102 loadExpansionState(); 103 } 104 105 public void expandAll(JTree tree, boolean expand) { 106 TreeNode root = (TreeNode) tree.getModel().getRoot(); 107 108 // Traverse tree from root 109 expandAll(tree, new TreePath(root), expand); 110 } 111 112 private void expandAll(JTree tree, TreePath parent, boolean expand) { 113 // Traverse children 114 TreeNode node = (TreeNode) parent.getLastPathComponent(); 115 if (node.getChildCount() >= 0) { 116 for (Enumeration<?> e = node.children(); e.hasMoreElements();) { 117 TreeNode n = (TreeNode) e.nextElement(); 118 TreePath path = parent.pathByAddingChild(n); 119 expandAll(tree, path, expand); 120 } 121 } 122 123 // Expansion or collapse must be done bottom-up 124 if (expand) { 125 tree.expandPath(parent); 126 } else { 127 tree.collapsePath(parent); 128 } 129 } 130 131 private void addButtons(JToolBar toolBar) { 132 URL zoomInUrl = getClass().getResource( 133 "/toolbarButtonGraphics/general/ZoomIn16.gif"); 134 Action expandAction = new AbstractAction("Expand All", new ImageIcon( 135 zoomInUrl)) { 136 { 137 putValue(Action.SHORT_DESCRIPTION, "Expand All"); 138 } 139 140 public void actionPerformed(ActionEvent e) { 141 expandAll(tree, true); 142 } 143 }; 144 toolBar.add(expandAction); 145 URL zoomOutUrl = getClass().getResource( 146 "/toolbarButtonGraphics/general/ZoomOut16.gif"); 147 Action collapseAction = new AbstractAction("Collapse All", 148 new ImageIcon(zoomOutUrl)) { 149 { 150 putValue(Action.SHORT_DESCRIPTION, "Collapse All"); 151 } 152 public void actionPerformed(ActionEvent e) { 153 expandAll(tree, false); 154 tree.expandPath(new TreePath(tree.getModel().getRoot())); 155 } 156 }; 157 toolBar.add(collapseAction); 158 159 URL errorGroupUrl = getClass().getResource( 160 "/toolbarButtonGraphics/general/Stop16.gif"); 161 Action groupAction = new AbstractAction("Group by error", 162 new ImageIcon(errorGroupUrl)) { 163 { 164 putValue(Action.SHORT_DESCRIPTION, "Group by error"); 165 } 166 public void actionPerformed(ActionEvent e) { 167 errorDecorator.groupOnDescription((DefaultMutableTreeNode) tree 168 .getModel().getRoot()); 169 ((DefaultTreeModel) tree.getModel()).reload(); 170 tree.expandPath(new TreePath(top)); 171 } 172 }; 173 toolBar.add(groupAction); 174 175 URL fileGroupUrl = getClass().getResource( 176 "/toolbarButtonGraphics/general/Edit16.gif"); 177 Action fileGroupAction = new AbstractAction("Group by file", 178 new ImageIcon(fileGroupUrl)) { 179 { 180 putValue(Action.SHORT_DESCRIPTION, "Group by file"); 181 } 182 public void actionPerformed(ActionEvent e) { 183 errorDecorator.groupOnFile((DefaultMutableTreeNode) tree 184 .getModel().getRoot()); 185 ((DefaultTreeModel) tree.getModel()).reload(); 186 tree.expandPath(new TreePath(top)); 187 } 188 }; 189 toolBar.add(fileGroupAction); 190 191 URL unGroupUrl = getClass().getResource( 192 "/toolbarButtonGraphics/general/Undo16.gif"); 193 Action unGroupAction = new AbstractAction("Ungroup", new ImageIcon( 194 unGroupUrl)) { 195 { 196 putValue(Action.SHORT_DESCRIPTION, "Ungroup"); 197 } 198 public void actionPerformed(ActionEvent e) { 199 errorDecorator.unGroup((DefaultMutableTreeNode) tree.getModel() 200 .getRoot()); 201 ((DefaultTreeModel) tree.getModel()).reload(); 202 tree.expandPath(new TreePath(top)); 203 } 204 }; 205 toolBar.add(unGroupAction); 206 } 207 208 private static void createAndShowGUI() { 209 JFrame frame = new JFrame("Error Viewer"); 210 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 211 212 ErrorPanel newContentPane = new ErrorPanel(); 213 newContentPane.setOpaque(true); // content panes must be opaque 214 frame.setContentPane(newContentPane); 215 216 frame.pack(); 217 frame.setVisible(true); 218 } 219 220 public static void main(String[] args) { 221 javax.swing.SwingUtilities.invokeLater(new Runnable() { 222 public void run() { 223 createAndShowGUI(); 224 } 225 }); 226 } 227 }