1 31 32 package org.antlr.works.visualization.graphics.panel; 33 34 import org.antlr.xjlib.foundation.notification.XJNotificationCenter; 35 import org.antlr.xjlib.foundation.notification.XJNotificationObserver; 36 import org.antlr.works.components.grammar.CEditorGrammar; 37 import org.antlr.works.editor.EditorMenu; 38 import org.antlr.works.menu.ContextualMenuFactory; 39 import org.antlr.works.stats.StatisticsAW; 40 import org.antlr.works.swing.Toolbar; 41 import org.antlr.works.syntax.element.ElementRule; 42 import org.antlr.works.utils.IconManager; 43 import org.antlr.works.visualization.graphics.GContext; 44 import org.antlr.works.visualization.graphics.graph.GGraphAbstract; 45 import org.antlr.works.visualization.graphics.graph.GGraphGroup; 46 import org.antlr.works.visualization.graphics.path.GPathGroup; 47 import org.antlr.works.visualization.skin.nfa.NFASkin; 48 import org.antlr.works.visualization.skin.syntaxdiagram.SDSkin; 49 50 import javax.swing.*; 51 import javax.swing.event.ChangeEvent ; 52 import javax.swing.event.ChangeListener ; 53 import java.awt.*; 54 import java.awt.event.ActionEvent ; 55 import java.awt.event.ActionListener ; 56 import java.awt.image.BufferedImage ; 57 import java.util.List ; 58 59 public class GPanel implements XJNotificationObserver { 60 61 protected Container container; 62 protected Box pathButtonSelectionBox; 63 protected Toolbar controlPanel; 64 protected JTextField errorLabel; 65 66 protected GContext context; 67 protected GView view; 68 protected JScrollPane viewScrollPane; 69 70 protected ElementRule rule; 71 protected CEditorGrammar editor; 72 73 public GPanel(CEditorGrammar editor, GContext context) { 74 this.editor = editor; 75 this.context = context; 76 this.container = new JPanel(new BorderLayout()); 77 78 createNormalPanel(); 79 80 XJNotificationCenter.defaultCenter().addObserver(this, GPathGroup.NOTIF_CURRENT_PATH_DID_CHANGE); 81 } 82 83 public void close() { 84 XJNotificationCenter.defaultCenter().removeObserver(this); 85 } 86 87 public void setGraphs(List graphs) { 88 view.setGraphs(graphs); 89 view.refresh(); 90 updateCurrentAlternative(); 91 } 92 93 public void setRule(ElementRule rule) { 94 if(view != null) 95 view.setEnable(false); 96 97 this.rule = rule; 98 createPanel(); 99 view.setEnable(true); 100 } 101 102 public void setPlaceholder(String placeholder) { 103 view.setPlaceholder(placeholder); 104 } 105 106 public void update() { 107 updateCurrentError(); 108 } 109 110 public Container getContainer() { 111 return container; 112 } 113 114 public GGraphAbstract getCurrentGraph() { 115 return view.getCurrentGraph(); 116 } 117 118 public BufferedImage getImageOfView() { 119 return view.getCachedImage(); 120 } 121 122 public void createPanel() { 123 if(rule == null) 124 return; 125 126 if(rule.hasErrors()) 127 createErrorPanel(); 128 else 129 createNormalPanel(); 130 } 131 132 public void createNormalPanel() { 133 container.removeAll(); 134 container.add(createControlPane(), BorderLayout.NORTH); 135 container.add(createVisualizationPane(), BorderLayout.CENTER); 136 container.validate(); 137 } 138 139 public void createErrorPanel() { 140 container.removeAll(); 141 JPanel panel = new JPanel(new BorderLayout()); 142 panel.add(createErrorPane(), BorderLayout.NORTH); 143 panel.add(createVisualizationPane(), BorderLayout.CENTER); 144 container.add(panel, BorderLayout.CENTER); 145 container.add(createControlPane(), BorderLayout.NORTH); 146 container.validate(); 147 } 148 149 private Container createVisualizationPane() { 150 view = new CustomGView(this, context); 151 viewScrollPane = new JScrollPane(view); 152 viewScrollPane.setWheelScrollingEnabled(true); 153 return viewScrollPane; 154 } 155 156 private Container createErrorPane() { 157 controlPanel = Toolbar.createHorizontalToolbar(); 158 159 if(rule.errors.size()>1) { 160 controlPanel.addElement(createPrevErrorButton()); 161 controlPanel.addElement(createNextErrorButton()); 162 controlPanel.addGroupSeparator(); 163 } 164 controlPanel.addElement(new JLabel(IconManager.shared().getIconWarning())); 165 controlPanel.addElement(errorLabel = new JTextField()); 166 errorLabel.setBorder(null); 167 errorLabel.setEditable(false); 168 errorLabel.setBackground(getContainer().getBackground()); 169 170 controlPanel.add(Box.createHorizontalGlue()); 171 172 pathButtonSelectionBox = new Box(BoxLayout.X_AXIS); 173 controlPanel.addElement(pathButtonSelectionBox); 174 175 controlPanel.addGroupSeparator(); 176 controlPanel.addElement(createShowCrossLinksButton()); 177 178 return controlPanel; 179 } 180 181 private JButton createPrevErrorButton() { 182 JButton button = new JButton(IconManager.shared().getIconBackward()); 183 button.setFocusable(false); 184 button.setToolTipText("Show Previous Error"); 185 button.addActionListener(new ActionListener () { 186 public void actionPerformed(ActionEvent event) { 187 if(view.setPrevGraph()) { 188 view.refresh(); 189 createPathSelectionButtons(); 190 updateCurrentError(); 191 } 192 } 193 }); 194 return button; 195 } 196 197 private JButton createNextErrorButton() { 198 JButton button = new JButton(IconManager.shared().getIconForward()); 199 button.setFocusable(false); 200 button.setToolTipText("Show Next Error"); 201 button.addActionListener(new ActionListener () { 202 public void actionPerformed(ActionEvent event) { 203 if(view.setNextGraph()) { 204 view.refresh(); 205 createPathSelectionButtons(); 206 updateCurrentError(); 207 } 208 } 209 }); 210 return button; 211 } 212 213 private void updateCurrentAlternative() { 214 if(view.getCurrentGraph() instanceof GGraphGroup) { 215 if(pathButtonSelectionBox != null && pathButtonSelectionBox.getComponentCount() == 0) 216 createPathSelectionButtons(); 217 } 218 } 219 220 private void updateCurrentError() { 221 if(rule == null || !rule.hasErrors()) 222 return; 223 224 StringBuffer sb = new StringBuffer (); 225 int count = view.getGraphs().size(); 226 int index = view.getCurrentGraphIndex(); 227 if(count>1) { 228 sb.append("("); 229 sb.append(index + 1); 230 sb.append("/"); 231 sb.append(count); 232 sb.append(") "); 233 } 234 sb.append(rule.getErrorMessageString(index)); 235 errorLabel.setText(sb.toString()); 236 controlPanel.revalidate(); 237 } 238 239 private void createPathSelectionButtons() { 240 pathButtonSelectionBox.removeAll(); 241 242 if(!(view.getCurrentGraph() instanceof GGraphGroup)) 243 return; 244 245 GGraphGroup gg = (GGraphGroup)view.getCurrentGraph(); 246 int count = gg.pathGroup.getNumberOfPaths(); 247 if(count <= 1) 248 pathButtonSelectionBox.add(new JLabel("Alternative:")); 249 else 250 pathButtonSelectionBox.add(new JLabel("Alternatives:")); 251 252 for(int i=0; i<count; i++) { 253 pathButtonSelectionBox.add(createPathSelectionButton(i)); 254 } 255 } 256 257 private JCheckBox createPathSelectionButton(int pathIndex) { 258 JCheckBox button = new JCheckBox(String.valueOf(pathIndex+1)); 259 button.setName(String.valueOf(pathIndex)); 260 button.setFocusable(false); 261 button.addActionListener(new ActionListener () { 262 public void actionPerformed(ActionEvent event) { 263 JCheckBox button = (JCheckBox)event.getSource(); 264 GGraphGroup gg = (GGraphGroup)view.getCurrentGraph(); 265 gg.pathGroup.setPathVisible(Integer.parseInt(button.getName()), button.isSelected()); 266 gg.pathGroup.makeSureCurrentPathIsVisible(); 267 view.cacheRerender(); 268 view.repaint(); 269 } 270 }); 271 272 GGraphGroup gg = (GGraphGroup)view.getCurrentGraph(); 273 button.setSelected(gg.pathGroup.isPathVisible(pathIndex)); 274 275 return button; 276 } 277 278 private JButton createShowCrossLinksButton() { 279 JButton button = new JButton(IconManager.shared().getIconShowLinks()); 280 button.setFocusable(false); 281 button.setToolTipText("Show links between rules"); 282 button.addActionListener(new ActionListener () { 283 public void actionPerformed(ActionEvent event) { 284 for (Object o : view.getGraphs()) { 285 GGraphGroup gg = (GGraphGroup) o; 286 gg.pathGroup.toggleShowRuleLinks(); 287 } 288 view.cacheRerender(); 289 view.repaint(); 290 } 291 }); 292 return button; 293 } 294 295 private Container createControlPane() { 296 Toolbar box = Toolbar.createHorizontalToolbar(); 297 298 box.addElement(new JLabel("Zoom")); 299 box.addElement(createFactorSlider()); 300 301 304 307 box.addElement(createShowNFAButton()); 310 312 return box; 314 } 315 316 private JSlider createFactorSlider() { 317 JSlider slider = new JSlider(); 318 slider.setFocusable(false); 319 slider.setMinimum(1); 320 slider.setMaximum(800); 321 slider.setValue((int)(context.getFactor()*40)); 322 323 slider.addChangeListener(new ChangeListener () { 324 public void stateChanged(ChangeEvent event) { 325 JSlider slider = (JSlider)event.getSource(); 326 context.setFactor((float)slider.getValue()/40); 327 view.refreshSizeChanged(slider.getValueIsAdjusting()); 328 } 329 }); 330 return slider; 331 } 332 333 398 399 private JCheckBox createShowNFAButton() { 400 JCheckBox button = new JCheckBox("Show NFA"); 401 button.setFocusable(false); 402 button.setSelected(context.skin instanceof NFASkin); 403 button.addActionListener(new ActionListener () { 404 public void actionPerformed(ActionEvent event) { 405 StatisticsAW.shared().recordEvent(StatisticsAW.EVENT_TOGGLE_SD_NFA); 406 407 JCheckBox button = (JCheckBox)event.getSource(); 408 if(button.isSelected()) 409 context.setSkin(new NFASkin()); 410 else 411 context.setSkin(new SDSkin()); 412 413 view.refresh(); 414 } 415 }); 416 return button; 417 } 418 419 432 433 public void notificationFire(Object source, String name) { 434 if(name.equals(GPathGroup.NOTIF_CURRENT_PATH_DID_CHANGE)) 435 updateCurrentAlternative(); 436 } 437 438 protected class CustomGView extends GView { 439 440 public CustomGView(GPanel panel, GContext context) { 441 super(panel, context); 442 } 443 444 public JPopupMenu getContextualMenu() { 445 ContextualMenuFactory factory = new ContextualMenuFactory(editor.editorMenu); 446 factory.addItem(EditorMenu.MI_EXPORT_AS_EPS); 447 factory.addItem(EditorMenu.MI_EXPORT_AS_IMAGE); 448 return factory.menu; 449 } 450 451 } 452 453 } 454 | Popular Tags |