001 /** 002 * Created by IntelliJ IDEA. 003 * User: Wei Wang 004 * Date: Nov 27, 2002 005 * Time: 3:50:38 PM 006 */ 007 008 package EVolve.visualization.XYViz; 009 010 import java.awt.*; 011 import java.awt.event.*; 012 import java.util.*; 013 import javax.swing.*; 014 import EVolve.Scene; 015 import EVolve.data.Entity; 016 import EVolve.data.Selection; 017 import EVolve.util.HelperFuncs; 018 import EVolve.util.Magnifier; 019 import EVolve.util.xmlutils.datastructures.SerializedVisualization; 020 import EVolve.util.painters.DefaultPainter; 021 import EVolve.util.painters.Painter; 022 import EVolve.util.phasedetectors.PhaseDetector; 023 import EVolve.util.sourcebrowser.SourceBrowser; 024 import EVolve.visualization.AutoImage; 025 import EVolve.visualization.AutoShapeImage; 026 import EVolve.visualization.AxesPanel; 027 import EVolve.visualization.ReferenceDimension; 028 import EVolve.visualization.Visualization; 029 import EVolve.visualization.VisualizationDefinition; 030 031 public abstract class XYVisualization extends Visualization{ 032 protected int autoInterval,interval; 033 protected long xMax, xOffset, currentThread; 034 protected boolean shift_pressed, flipMagnifier = true; 035 protected Painter painter; 036 protected Magnifier magnifier; 037 protected JMenuItem itemChangeOrientation,itemScale,itemBrowseSource,itemRecolor; 038 protected JMenuItem itemScaleX, itemScaleY; 039 protected boolean normalOrientation; 040 protected HashMap imageMap,threadDataSet; 041 protected SourceBrowser sourceBrowser; 042 protected AxesPanel canvas; 043 protected AutoImage image; // the image 044 protected ArrayList timeMap; 045 protected PhaseDetector phaseDetector; 046 protected boolean phaseDetectorEnabled; 047 048 protected abstract String mouseMove(int x, int y); 049 050 public XYVisualization() { 051 super(); 052 shift_pressed = false; 053 autoInterval = -1; 054 interval = -1; 055 normalOrientation = true; 056 currentThread = -1; 057 imageMap = new HashMap(); 058 threadDataSet = new HashMap(); 059 sourceBrowser = new SourceBrowser(); 060 timeMap = new ArrayList(); 061 phaseDetectorEnabled = Scene.getVisualizationManager().isPhaseDetectorEnabled(); 062 } 063 064 protected Component createPanel() { 065 canvas = new AxesPanel(AxesPanel.Axis_Enabled | AxesPanel.Flip_Image | AxesPanel.Scale_Image); 066 flipMagnifier = true; 067 addMagnifier(canvas,flipMagnifier); 068 JScrollPane returnVal = new JScrollPane(canvas); 069 canvas.setParent(returnVal); 070 071 return returnVal; 072 } 073 074 protected void addMagnifier(Component aPanel, boolean flipImage) { 075 magnifier = new Magnifier(flipImage); 076 aPanel.addMouseMotionListener(new MouseMotionAdapter() { 077 public void mouseMoved(MouseEvent e) { 078 079 if (e.isShiftDown()) shift_pressed = true; 080 else shift_pressed = false; 081 082 if (e.isAltDown()) { 083 int x = e.getX(), y = e.getY(); 084 x = canvas.getImageX(x); 085 y = canvas.getImageY(y); 086 magnifier.convertMousePosition(canvas); 087 magnifier.showWindow(canvas.getSubImage(x,y)); 088 canvas.drawZoomingArea(e.getX(),e.getY()); 089 } 090 mouseMove(e.getX(), e.getY()); 091 } 092 093 public void mouseDragged(MouseEvent e) { 094 if (e.isShiftDown()) shift_pressed = true; 095 else shift_pressed = false; 096 mouseMove(e.getX(), e.getY()); 097 } 098 }); 099 100 101 aPanel.addMouseListener(new MouseListener() { 102 public void mouseClicked(MouseEvent e) { 103 mouseX = e.getX(); 104 mouseY = e.getY(); 105 freezed = false; 106 } 107 108 public void mouseEntered(MouseEvent e) {} 109 110 public void mouseExited(MouseEvent e) {} 111 112 public void mousePressed(MouseEvent e) {} 113 114 public void mouseReleased(MouseEvent e) {} 115 }); 116 117 } 118 119 protected void updateConfiguration() { 120 if (panel instanceof JScrollPane) 121 ((AxesPanel)(((JScrollPane)panel)).getViewport().getView()).setImage(null); 122 else 123 ((AxesPanel)panel).setImage(null); 124 panel.repaint(); 125 126 normalOrientation = true; 127 } 128 129 protected void createMenu() { 130 super.createMenu(); 131 int flag = canvas.getFlag(); 132 133 if ((flag & 0xff000000) == 0) { 134 itemScale = new JMenuItem("Fit Visualization to Window"); 135 itemScale.setMnemonic(KeyEvent.VK_F); 136 } else { 137 itemScale = new JMenuItem("Restore Visualization"); 138 itemScale.setMnemonic(KeyEvent.VK_R); 139 } 140 itemScale.addActionListener(new ActionListener() { 141 public void actionPerformed(ActionEvent e) { 142 if (e.getActionCommand().charAt(0) == 'F') { 143 canvas.scaleImage(true); 144 itemScale.setText("Restore Visualization"); 145 itemScale.setActionCommand("Restore Visualization"); 146 itemScale.setMnemonic(KeyEvent.VK_R); 147 } else { 148 canvas.scaleImage(false); 149 itemScale.setText("Fit Visualization to Window"); 150 itemScale.setActionCommand("Fit Visualization to Window"); 151 itemScale.setMnemonic(KeyEvent.VK_F); 152 } 153 canvas.repaint(); 154 } 155 }); 156 157 158 if ((flag & 0xf0000000) == AxesPanel.Scale_X) { 159 itemScaleX = new JMenuItem("RestoreX axis"); 160 } else { 161 itemScaleX = new JMenuItem("Fit X axis to Window"); 162 } 163 itemScaleX.setMnemonic(KeyEvent.VK_X); 164 itemScaleX.addActionListener(new ActionListener() { 165 public void actionPerformed(ActionEvent e) { 166 if (e.getActionCommand().charAt(0) == 'F') { 167 int flag = canvas.getFlag(); 168 canvas.setPanelFlag(flag | AxesPanel.Scale_X); 169 itemScaleX.setText("Restore X axis"); 170 itemScaleX.setActionCommand("Restore X axis"); 171 itemScaleX.setMnemonic(KeyEvent.VK_X); 172 } else { 173 int flag = canvas.getFlag(); 174 canvas.setPanelFlag(flag & ~AxesPanel.Scale_X); 175 itemScaleX.setText("Fit X axis to Window"); 176 itemScaleX.setActionCommand("Fit X axis to Window"); 177 itemScaleX.setMnemonic(KeyEvent.VK_X); 178 } 179 canvas.repaint(); 180 } 181 }); 182 183 if ((flag & 0x0f000000) == AxesPanel.Scale_Y) { 184 itemScaleY = new JMenuItem("Restore Y axis"); 185 } else { 186 itemScaleY = new JMenuItem("Fit Y axis to Window"); 187 } 188 itemScaleY.setMnemonic(KeyEvent.VK_Y); 189 itemScaleY.addActionListener(new ActionListener() { 190 public void actionPerformed(ActionEvent e) { 191 if (e.getActionCommand().charAt(0) == 'F') { 192 int flag = canvas.getFlag(); 193 canvas.setPanelFlag(flag | AxesPanel.Scale_Y); 194 itemScaleY.setText("Restore Y axis"); 195 itemScaleY.setActionCommand("Restore Y axis"); 196 itemScaleY.setMnemonic(KeyEvent.VK_X); 197 } else { 198 int flag = canvas.getFlag(); 199 canvas.setPanelFlag(flag & ~AxesPanel.Scale_Y); 200 itemScaleY.setText("Fit Y axis to Window"); 201 itemScaleY.setActionCommand("Fit Y axis to Window"); 202 itemScaleY.setMnemonic(KeyEvent.VK_Y); 203 } 204 canvas.repaint(); 205 } 206 }); 207 208 itemBrowseSource = new JMenuItem("Browse source code..."); 209 itemBrowseSource.setMnemonic(KeyEvent.VK_B); 210 itemBrowseSource.addActionListener(new ActionListener() { 211 public void actionPerformed(ActionEvent e) { 212 sourceBrowser.showSourceFile(getEntityUnderMouse()); 213 } 214 }); 215 216 itemRecolor = new JMenuItem("Recolor"); 217 itemRecolor.setMnemonic(KeyEvent.VK_R); 218 itemRecolor.addActionListener(new ActionListener() { 219 public void actionPerformed(ActionEvent e) { 220 Selection[] selections = Scene.getFilter().getSelection(); 221 boolean found = false; 222 for (int i=0; i<selections.length; i++) { 223 if (selections[i].getColor()!=null) { 224 found = true; 225 break; 226 } 227 } 228 if (!found) { 229 Scene.showErrorMessage("No selection is colored, can not recolor current visualization."); 230 return; 231 } 232 Visualization visual = Scene.getVisualizationManager().getActiveVisualization(); 233 if (visual == null) return; 234 if (image instanceof AutoShapeImage) { 235 //reColorShapes(); 236 Scene.showErrorMessage("Can not recolor image with shapes."); 237 return; 238 } else 239 reColor(); 240 } 241 }); 242 243 popup.add(itemBrowseSource); 244 popup.add(itemScale); 245 popup.add(itemScaleX); 246 popup.add(itemScaleY); 247 popup.add(itemRecolor); 248 itemBrowseSource.setEnabled(false); 249 } 250 251 public VisualizationDefinition getDefinition() { 252 return definition; 253 } 254 255 public void restoreConfiguration(SerializedVisualization config) { 256 autoInterval = Integer.parseInt(config.Interval); 257 interval = autoInterval; 258 super.restoreConfiguration(config); 259 } 260 261 public SerializedVisualization getCurrentConfiguration() { 262 SerializedVisualization data = super.getCurrentConfiguration(); 263 264 data.Interval = String.valueOf(interval); 265 266 return data; 267 } 268 269 public long getxMax() { 270 return xMax; 271 } 272 273 public AutoImage getImage() { 274 return image; 275 } 276 277 public void setImage(AutoImage image) { 278 this.image = image; 279 } 280 281 public void disablePopupMenu() { 282 MenuElement[] menus = popup.getSubElements(); 283 for (int i=0; i<menus.length; i++) { 284 if (((JMenuItem)menus[i]).getText().equals("Sort") || 285 ((JMenuItem)menus[i]).getText().equals("Save...") || 286 ((JMenuItem)menus[i]).getText().equals("Restore") || 287 ((JMenuItem)menus[i]).getText().equals("Fit Window")) 288 continue; 289 ((JMenuItem)menus[i]).setEnabled(false); 290 } 291 Scene.getUIManager().disableFunctionMenus(); 292 } 293 294 protected void changeOrientation() { 295 AutoImage newImage = new AutoImage(); 296 int wMax = image.getW(); 297 int hMax = image.getH(); 298 Color color; 299 300 for (int i=0; i<wMax; i++) { 301 for (int j=0; j<hMax; j++) { 302 color = (Color)image.getColor(i,j); 303 if (color != null) { 304 newImage.setColor(j,i,color); 305 } 306 } 307 } 308 image = newImage; 309 310 normalOrientation = ! normalOrientation; 311 } 312 313 protected void switchThread(long threadId) { 314 if (currentThread != threadId) { 315 currentThread = threadId; 316 image = (AutoImage)imageMap.get(new Long(threadId)); 317 if (image == null) { 318 image = new AutoImage(); 319 imageMap.put(new Long(threadId),image); 320 } 321 } 322 } 323 324 protected void installPainter() { 325 painter = new DefaultPainter(); 326 } 327 328 protected void enableBrowseSourceMenu() { 329 itemBrowseSource.setEnabled(true); 330 } 331 332 protected void countEvents(long x) { 333 /*while (x/Math.abs(interval) >= eventCounter.size()) { 334 eventCounter.add(new Long(Scene.getEventCounter())); 335 } 336 337 while (x/Math.abs(interval) >= timeCounter.size()) { 338 timeCounter.add(new Long(x)); 339 }*/ 340 long eventNo = Scene.getEventCounter(); 341 long[] time2event = new long[2]; 342 time2event[0] = x; 343 time2event[1] = eventNo; 344 while (x/Math.abs(interval) - xOffset >= timeMap.size()) { 345 timeMap.add(time2event); 346 } 347 } 348 349 public void cleanup() { 350 super.cleanup(); 351 magnifier.cleanup(); 352 } 353 354 public void enablePhaseDetector(boolean enabled) { 355 phaseDetectorEnabled = enabled; 356 } 357 358 protected void reset() { 359 super.reset(); 360 image = null; 361 } 362 363 protected void dialogApply() { 364 super.dialogApply(); 365 image = null; 366 } 367 368 public PhaseDetector getPhaseDetector() { 369 return phaseDetector; 370 } 371 372 public Point getMousePosition() { 373 return new Point(mouseX, mouseY); 374 } 375 376 public void freeze(boolean flag) { 377 freezed = flag; 378 } 379 380 public Object clone() { 381 XYVisualization o = null; 382 383 o = (XYVisualization) super.clone(); 384 o.image = (image == null) ? null : (AutoImage)image.clone(); 385 386 o.imageMap = HelperFuncs.cloneHashMap(imageMap); 387 o.itemChangeOrientation = null; 388 o.threadDataSet = HelperFuncs.cloneHashMap(threadDataSet); 389 o.sourceBrowser = (SourceBrowser)sourceBrowser.clone(); 390 o.painter = (painter == null) ?null : (Painter)painter.clone(); 391 o.itemBrowseSource = null; 392 o.itemChangeOrientation = null; 393 o.canvas = (AxesPanel)canvas.clone(); 394 o.panel = new JScrollPane(o.canvas); 395 o.canvas.setParent((JScrollPane)o.panel); 396 o.addMagnifier(o.canvas,flipMagnifier); 397 o.addPopupTrigger(o.panel); 398 o.timeMap = new ArrayList(); 399 for (int i=0; i<timeMap.size(); i++) { 400 long[] newValue = new long[2]; 401 long[] oldValue = (long[])timeMap.get(i); 402 newValue[0] = oldValue[0]; 403 newValue[1] = oldValue[1]; 404 o.timeMap.add(newValue); 405 } 406 o.phaseDetector = null; 407 if (phaseDetector != null) { 408 o.phaseDetector = (PhaseDetector)phaseDetector.clone(); 409 o.phaseDetector.setPanel((AxesPanel)((JScrollPane)o.getPanel()).getViewport().getView()); 410 } 411 return o; 412 } 413 414 public ArrayList getTimeMap() { 415 return timeMap; 416 } 417 418 public int getInterval() { 419 return interval; 420 } 421 422 private void reColor() { 423 Selection[] selections = Scene.getFilter().getSelection(); 424 425 for (int i=0; i<2; i++) { 426 if (!(dimension[i] instanceof ReferenceDimension)) continue; 427 ReferenceDimension reference = (ReferenceDimension)dimension[i]; 428 429 HashMap entityName2Int = reference.getEntityName2IntMap(); 430 for (int j=0; j<selections.length; j++) { 431 Color color = selections[j].getColor(); 432 if (color == null) continue; 433 434 HashSet set = new HashSet(); 435 Entity[] selected = selections[j].getSelected(); 436 for (int k=0; k<selected.length; k++) { 437 String entityName = selected[k].getName(); 438 if (entityName2Int.containsKey(entityName)) { 439 set.add(entityName2Int.get(entityName)); 440 } 441 } 442 443 fillColor(image.getW(), image.getH(), set, color, i==0); 444 } 445 } 446 sort(); 447 } 448 449 private void reColorShapes() { 450 Selection[] selections = Scene.getFilter().getSelection(); 451 int w = image.getW(); 452 int h = image.getH(); 453 454 for (int i=0; i<2; i++) { 455 if (!(dimension[i] instanceof ReferenceDimension)) continue; 456 ReferenceDimension reference = (ReferenceDimension)dimension[i]; 457 458 HashMap entityName2Int = reference.getEntityName2IntMap(); 459 for (int j=0; j<selections.length; j++) { 460 Color color = selections[j].getColor(); 461 if (color == null) continue; 462 463 HashSet set = new HashSet(); 464 Entity[] selected = selections[j].getSelected(); 465 for (int k=0; k<selected.length; k++) { 466 String entityName = selected[k].getName(); 467 if (entityName2Int.containsKey(entityName)) { 468 set.add(entityName2Int.get(entityName)); 469 } 470 } 471 for (int a=0; a<w; a++) { 472 for (int b=0; b<h; b++) { 473 ArrayList value = (ArrayList)image.getColor(a,b); 474 if (value == null) continue; 475 EVolve.util.painters.shapes.Shape shape = (EVolve.util.painters.shapes.Shape)value.get(0); 476 if (set.contains(new Integer((int)shape.getEntityID()))) 477 shape.setColor(color); 478 } 479 } 480 } 481 } 482 483 sort(); 484 } 485 486 private void fillColor(int width, int height, HashSet tobeFilled, Color color, boolean fillColumn) { 487 int loop1 = width, loop2 = height; 488 if (!fillColumn) { 489 loop1 = height; 490 loop2 = width; 491 } 492 493 for (int w = 0; w<loop1; w++) { 494 if (!tobeFilled.contains(new Integer(w))) continue; 495 496 for (int h = 0; h<loop2; h++) { 497 if (fillColumn) { 498 if (image.getColor(w,h)!=null) 499 image.setColor(w,h,color); 500 } 501 else { 502 if (image.getColor(h,w)!=null) 503 image.setColor(h,w,color); 504 } 505 } 506 } 507 } 508 509 protected abstract String getEntityUnderMouse(); 510 }