14a19,19 > import javax.swing.event.EventListenerList; 19,19c14,14 < import CH.ifa.draw.framework.*; --- > import CH.ifa.draw.framework.*; 20,20c15,15 < import CH.ifa.draw.standard.*; --- > import CH.ifa.draw.standard.*; 21,21c16,16 < import CH.ifa.draw.figures.*; --- > import CH.ifa.draw.figures.*; 22,22c17,17 < import CH.ifa.draw.util.*; --- > import CH.ifa.draw.util.*; 25,25c26,26 < * DrawApplication defines a standard presentation for standalone drawing --- > * DrawApplication defines a standard presentation for 25a27,27 > * standalone drawing editors. The presentation is 26,26c28,28 < * editors. The presentation is customized in subclasses. --- > * customized in subclasses. 39,39c41,41 < implements DrawingEditor, PaletteListener { --- > implements DrawingEditor, PaletteListener, VersionRequester { 41,41d42 < private Drawing fDrawing; 51,51d51 < private String fDrawingFilename; 52a53,53 > private UndoManager myUndoManager; 53a55,55 > private final EventListenerList listenerList = new EventListenerList(); 53,53c54,54 < static String fgUntitled = "untitled"; --- > protected static String fgUntitled = "untitled"; 57a60,60 > protected static int winCount = 0; 75a762,762 > } 76,76d761 < 89a92,92 > winCount++; 106a110,112 > if (view() == null) { > return; > } 107a114,118 > window.open(view()); > if (view().drawing().getTitle() != null ) { > window.setDrawingTitle(view().drawing().getTitle() + " (View)"); > } > else { 108,109d113 < window.open(); < window.setDrawing(drawing()); 110,110c119,119 < window.setDrawingTitle(getDrawingTitle() + " (View)"); --- > window.setDrawingTitle(getDefaultDrawingTitle() + " (View)"); 110a120,120 > } 114,114c124,124 < * Open a new window for this application containing --- > * Open a new window for this application containing the passed in drawing, 114a125,125 > * or a new drawing if the passed in drawing is null. 115,115d124 < * an new (empty) drawing. 117,117c127,127 < public void newWindow() { --- > public void newWindow(Drawing initialDrawing) { 120a132,135 > else { > window.open(createDrawingView(initialDrawing)); > } > } 122a138,138 > * Opens a new window 123,124d137 < * Opens the window and initializes its contents. < * Clients usually only call but don't override it. 126a141,150 > open(NullDrawingView.getManagedDrawingView(this)); > // open(createDrawingView()); > } > > /** > * Opens a new window with a drawing view. > */ > protected void open(DrawingView newDrawingView) { > getVersionControlStrategy().assertCompatibleVersion(); > setUndoManager(new UndoManager()); 128a153,154 > > setView(newDrawingView); 129,129d152 < fView = createDrawingView(); 130,130c155,155 < JComponent contents = createContents((StandardDrawingView)view()); --- > JComponent contents = createContents(view()); 135a791,791 > } 136,136d790 < 152,153d175 < initDrawing(); < 163a186,187 > > toolDone(); 179,185d202 < protected void initDrawing() { < setDrawing(createDrawing()); < setDrawingTitle(fgUntitled); < view().setDrawing(drawing()); < toolDone(); < } < 208a226,228 > CommandMenu menu = new CommandMenu("File"); > Command cmd = new AbstractCommand("New", this, false) { > public void execute() { 209,213d225 < JMenu menu = new JMenu("File"); < JMenuItem mi = new JMenuItem("New", new MenuShortcut('n').getKey()); < mi.addActionListener( < new ActionListener() { < public void actionPerformed(ActionEvent event) { 215a231,232 > }; > menu.add(cmd, new MenuShortcut('n')); 215a261,261 > }; 216,217d260 < } < ); 218,218c262,262 < menu.add(mi); --- > menu.add(cmd); 219a234,235 > cmd = new AbstractCommand("Open...", this, false) { > public void execute() { 220,223d233 < mi = new JMenuItem("Open...", new MenuShortcut('o').getKey()); < mi.addActionListener( < new ActionListener() { < public void actionPerformed(ActionEvent event) { 225a238,239 > }; > menu.add(cmd, new MenuShortcut('o')); 225a331,331 > }; 226,227d330 < } < ); 228,228c332,332 < menu.add(mi); --- > menu.add(cmd); 229a241,242 > cmd = new AbstractCommand("Save As...", this, true) { > public void execute() { 230,233d240 < mi = new JMenuItem("Save As...", new MenuShortcut('s').getKey()); < mi.addActionListener( < new ActionListener() { < public void actionPerformed(ActionEvent event) { 235a338,338 > }; 235a245,246 > }; > menu.add(cmd, new MenuShortcut('s')); 236,237d337 < } < ); 238,238c339,339 < menu.add(mi); --- > menu.add(cmd); 239,239d339 < 240a248,250 > > cmd = new AbstractCommand("Print...", this, true) { > public void execute() { 241,244d247 < mi = new JMenuItem("Print...", new MenuShortcut('p').getKey()); < mi.addActionListener( < new ActionListener() { < public void actionPerformed(ActionEvent event) { 246a253,254 > }; > menu.add(cmd, new MenuShortcut('p')); 247,247c458,458 < } --- > }; 248,248d458 < ); 249,249c459,459 < menu.add(mi); --- > menu.add(cmd); 250a256,258 > > cmd = new AbstractCommand("Exit", this, true) { > public void execute() { 251,254d255 < mi = new JMenuItem("Exit"); < mi.addActionListener( < new ActionListener() { < public void actionPerformed(ActionEvent event) { 257,259d260 < } < ); < menu.add(mi); 270,270c273,273 < new SelectAllCommand("Select All", view())), new MenuShortcut('a')); --- > new SelectAllCommand("Select All", this)), new MenuShortcut('a')); 272a276,276 > new CutCommand("Cut", this)), new MenuShortcut('x')); 273,273d275 < new CutCommand("Cut", view())), new MenuShortcut('x')); 274,274c277,277 < menu.add(new CopyCommand("Copy", view()), new MenuShortcut('c')); --- > menu.add(new CopyCommand("Copy", this), new MenuShortcut('c')); 276,276c279,279 < new PasteCommand("Paste", view())), new MenuShortcut('v')); --- > new PasteCommand("Paste", this)), new MenuShortcut('v')); 279,279c282,282 < new DuplicateCommand("Duplicate", view())), new MenuShortcut('d')); --- > new DuplicateCommand("Duplicate", this)), new MenuShortcut('d')); 280,280c283,283 < menu.add(new UndoableCommand(new DeleteCommand("Delete", view()))); --- > menu.add(new UndoableCommand(new DeleteCommand("Delete", this))); 281a285,285 > menu.add(new UndoableCommand(new GroupCommand("Group", this))); 282,282d284 < menu.add(new UndoableCommand(new GroupCommand("Group", view()))); 283,283c286,286 < menu.add(new UndoableCommand(new UngroupCommand("Ungroup", view()))); --- > menu.add(new UndoableCommand(new UngroupCommand("Ungroup", this))); 284a288,288 > menu.add(new UndoableCommand(new SendToBackCommand("Send to Back", this))); 285,285d287 < menu.add(new UndoableCommand(new SendToBackCommand("Send to Back", view()))); 286,286c289,289 < menu.add(new UndoableCommand(new BringToFrontCommand("Bring to Front", view()))); --- > menu.add(new UndoableCommand(new BringToFrontCommand("Bring to Front", this))); 288,288c291,291 < menu.add(new UndoCommand("Undo Command", view())); --- > menu.add(new UndoCommand("Undo Command", this)); 289,289c292,292 < menu.add(new RedoCommand("Redo Command", view())); --- > menu.add(new RedoCommand("Redo Command", this)); 299,299c302,302 < menu.addCheckItem(new ToggleGridCommand("Toggle Snap to Grid", view(), new Point(4,4))); --- > menu.addCheckItem(new ToggleGridCommand("Toggle Snap to Grid", this, new Point(4,4))); 302,302c305,305 < new AlignCommand(AlignCommand.Alignment.LEFTS, view()))); --- > new AlignCommand(AlignCommand.Alignment.LEFTS, this))); 304,304c307,307 < new AlignCommand(AlignCommand.Alignment.CENTERS, view()))); --- > new AlignCommand(AlignCommand.Alignment.CENTERS, this))); 306,306c309,309 < new AlignCommand(AlignCommand.Alignment.RIGHTS, view()))); --- > new AlignCommand(AlignCommand.Alignment.RIGHTS, this))); 309,309c312,312 < new AlignCommand(AlignCommand.Alignment.TOPS, view()))); --- > new AlignCommand(AlignCommand.Alignment.TOPS, this))); 311,311c314,314 < new AlignCommand(AlignCommand.Alignment.MIDDLES, view()))); --- > new AlignCommand(AlignCommand.Alignment.MIDDLES, this))); 313,313c316,316 < new AlignCommand(AlignCommand.Alignment.BOTTOMS, view()))); --- > new AlignCommand(AlignCommand.Alignment.BOTTOMS, this))); 322,322c325,325 < JMenu menu = new JMenu("Debug"); --- > CommandMenu menu = new CommandMenu("Debug"); 323a327,328 > Command cmd = new AbstractCommand("Simple Update", this) { > public void executable() { 324,327d326 < JMenuItem mi = new JMenuItem("Simple Update"); < mi.addActionListener( < new ActionListener() { < public void actionPerformed(ActionEvent event) { 328,328c329,329 < view().setDisplayUpdate(new SimpleUpdateStrategy()); --- > this.view().setDisplayUpdate(new SimpleUpdateStrategy()); 329,329d329 < } 331,332d330 < ); < menu.add(mi); 333a334,335 > cmd = new AbstractCommand("Buffered Update", this) { > public void executable() { 334,337d333 < mi = new JMenuItem("Buffered Update"); < mi.addActionListener( < new ActionListener() { < public void actionPerformed(ActionEvent event) { 338,338c336,336 < view().setDisplayUpdate(new BufferedUpdateStrategy()); --- > this.view().setDisplayUpdate(new BufferedUpdateStrategy()); 339,339d336 < } 341,342d337 < ); < menu.add(mi); 374a372,372 > this 374a805,806 > view().setDrawing(createDrawing()); > view().drawing().setTitle(getDefaultDrawingTitle()); 375,375d804 < view() 388,388c385,385 < new ChangeAttributeCommand("none", "ArrowMode", new Integer(PolyLineFigure.ARROW_TIP_NONE), view()))); --- > new ChangeAttributeCommand("none", "ArrowMode", new Integer(PolyLineFigure.ARROW_TIP_NONE), this))); 390,390c387,387 < new ChangeAttributeCommand("at Start", "ArrowMode", new Integer(PolyLineFigure.ARROW_TIP_START), view()))); --- > new ChangeAttributeCommand("at Start", "ArrowMode", new Integer(PolyLineFigure.ARROW_TIP_START), this))); 392,392c389,389 < new ChangeAttributeCommand("at End", "ArrowMode", new Integer(PolyLineFigure.ARROW_TIP_END), view()))); --- > new ChangeAttributeCommand("at End", "ArrowMode", new Integer(PolyLineFigure.ARROW_TIP_END), this))); 394,394c391,391 < new ChangeAttributeCommand("at Both", "ArrowMode", new Integer(PolyLineFigure.ARROW_TIP_BOTH), view()))); --- > new ChangeAttributeCommand("at Both", "ArrowMode", new Integer(PolyLineFigure.ARROW_TIP_BOTH), this))); 405,405c402,402 < for (int i = 0; i < fonts.length; i++) --- > for (int i = 0; i < fonts.length; i++) { 407,407c404,404 < new ChangeAttributeCommand(fonts[i], "FontName", fonts[i], view()))); --- > new ChangeAttributeCommand(fonts[i], "FontName", fonts[i], this))); 407a405,405 > } 417,417c415,415 < new ChangeAttributeCommand("Plain", "FontStyle", new Integer(Font.PLAIN), view()))); --- > new ChangeAttributeCommand("Plain", "FontStyle", new Integer(Font.PLAIN), this))); 419,419c417,417 < new ChangeAttributeCommand("Italic","FontStyle", new Integer(Font.ITALIC),view()))); --- > new ChangeAttributeCommand("Italic","FontStyle", new Integer(Font.ITALIC), this))); 421,421c419,419 < new ChangeAttributeCommand("Bold", "FontStyle", new Integer(Font.BOLD), view()))); --- > new ChangeAttributeCommand("Bold", "FontStyle", new Integer(Font.BOLD), this))); 437,437c435,435 < new Integer(sizes[i]), view()) --- > new Integer(sizes[i]), 437a436,437 > this > ) 448,448c448,448 < JMenu menu = new JMenu("Look'n'Feel"); --- > CommandMenu menu = new CommandMenu("Look'n'Feel"); 451,451d450 < JMenuItem mi = null; 454,454d452 < mi = new JMenuItem(lafs[i].getName()); 455a454,455 > Command cmd = new AbstractCommand(lafs[i].getName(), this) { > public void execute() { 456,458d453 < mi.addActionListener( < new ActionListener() { < public void actionPerformed(ActionEvent event) { 461,463d457 < } < ); < menu.add(mi); 496,496c492,492 < return new SelectionTool(view()); --- > return new SelectionTool(this); 512a509,514 > DrawingView createdDrawingView = createDrawingView(createDrawing()); > createdDrawingView.drawing().setTitle(getDefaultDrawingTitle()); > return createdDrawingView; > } > > protected DrawingView createDrawingView(Drawing newDrawing) { 514,514c516,516 < return new StandardDrawingView(this, d.width, d.height); --- > DrawingView newDrawingView = new StandardDrawingView(this, d.width, d.height); 514a517,519 > newDrawingView.setDrawing(newDrawing); > fireViewCreatedEvent(newDrawingView); > return newDrawingView; 539a545,545 > if (view instanceof Component) { 540,540c546,546 < JScrollPane sp = new JScrollPane((StandardDrawingView)view); --- > JScrollPane sp = new JScrollPane((Component)view); 545a552,555 > else { > return new JPanel(); > } > } 562a573,573 > * Should we through IllegalArguementException if it is? 564,564c575,575 < private void setStorageFormatManager(StorageFormatManager storageFormatManager) { --- > protected final void setStorageFormatManager(StorageFormatManager storageFormatManager) { 577,584d587 < * Sets the drawing to be edited. < */ < public void setDrawing(Drawing drawing) { < view().setDrawing(drawing); < fDrawing = drawing; < } < < /** 626,633d628 < * Gets the current drawing. < * @see DrawingEditor < */ < public Drawing drawing() { < return fDrawing; < } < < /** 641a637,637 > * Retrieve the active view from the window 648a645,654 > protected void setView(DrawingView newView) { > DrawingView oldView = fView; > fView = newView; > fireViewSelectionChangedEvent(oldView, view()); > } > > public DrawingView[] views() { > return new DrawingView[] { view() }; > } > 660a667,670 > * Fired by a view when the figure seleciton changes. Since Commands and > * Tools are Actions and they are registered to hear these events, they will > * handle themselves. So selection sensitive menuitems will update their > * own states. 661,662d666 < * Handles a change of the current selection. Updates all < * menu items that are selection sensitive. 690a699,750 > * Register to hear when the active view is changed. For Single document > * interface, this will happen when a new drawing is created. > */ > public void addViewChangeListener(ViewChangeListener vsl) { > listenerList.add(ViewChangeListener.class, vsl); > } > > /** > * Remove listener > */ > public void removeViewChangeListener(ViewChangeListener vsl) { > listenerList.remove(ViewChangeListener.class, vsl); > } > > /** > * Convience method for switching views. This is uneeded in SDI > * environments. > */ > protected void fireViewSelectionChangedEvent(DrawingView oldView, DrawingView newView) { > final Object[] listeners = listenerList.getListenerList(); > ViewChangeListener vsl = null; > for (int i = listeners.length-2; i>=0 ; i-=2) { > if (listeners[i] == ViewChangeListener.class) { > vsl = (ViewChangeListener)listeners[i+1]; > vsl.viewSelectionChanged(oldView, newView); > } > } > } > > protected void fireViewCreatedEvent(DrawingView view) { > final Object[] listeners = listenerList.getListenerList(); > ViewChangeListener vsl = null; > for (int i = listeners.length-2; i>=0 ; i-=2) { > if (listeners[i] == ViewChangeListener.class) { > vsl = (ViewChangeListener)listeners[i+1]; > vsl.viewCreated(view); > } > } > } > > protected void fireViewDestroyingEvent(DrawingView view) { > final Object[] listeners = listenerList.getListenerList(); > ViewChangeListener vsl = null; > for (int i = listeners.length-2; i>=0 ; i-=2) { > if (listeners[i] == ViewChangeListener.class) { > vsl = (ViewChangeListener)listeners[i+1]; > vsl.viewDestroying( view ); > } > } > } > > /** 698a759,760 > // We should not really deactivate a tool which was never activated. > if (tool() != null) { 699,699c129,129 < if (tool() != null) --- > if (initialDrawing == null) { 724a787,788 > winCount--; > if (winCount == 0) { 740,740d804 < initDrawing(); 822a889,892 > // Need a better alert than this. > if(view() == null) { > return; > } 824a895,896 > view().drawing().setTitle(name); > setDrawingTitle(name); 824,824c894,894 < setDrawingTitle(storeFormat.store(file, drawing())); --- > String name = storeFormat.store(file, view().drawing()); 837a910,910 > restoredDrawing.setTitle(file); 838,838d909 < newWindow(); 839,839c911,911 < setDrawing(restoredDrawing); --- > newWindow(restoredDrawing); 840,840d911 < setDrawingTitle(file); 867,867d937 < fDrawingFilename = drawingTitle; 868,868c938,938 < if (fgUntitled.equals(drawingTitle)) { --- > if (getDefaultDrawingTitle().equals(drawingTitle)) { 879a950,950 > return view().drawing().getTitle(); 880,880d949 < return fDrawingFilename; 895a966,996 > > protected void setUndoManager(UndoManager newUndoManager) { > myUndoManager = newUndoManager; > } > > public UndoManager getUndoManager() { > return myUndoManager; > } > > protected VersionControlStrategy getVersionControlStrategy() { > return new StandardVersionControlStrategy(this); > } > > /** > * Subclasses should override this method to specify to which versions of > * JHotDraw they are compatible. A string array is returned so it is possible > * to specify several version numbers of JHotDraw to which the application > * is compatible with. > * > * @return all versions number of JHotDraw the application is compatible with. > */ > public String[] getRequiredVersions() { > String[] requiredVersions = new String[1]; > // return the version of the package we are in > requiredVersions[0] = VersionManagement.getPackageVersion(DrawApplication.class.getPackage()); > return requiredVersions; > } > > protected String getDefaultDrawingTitle() { > return fgUntitled; > }