Source code: novaworx/viewarea/ViewPane.java
1 /*
2 Novaworx Development Environment
3 Copyright (C) 2000-2003 Mark Soderquist
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to:
17
18 Free Software Foundation, Inc.
19 59 Temple Place, Suite 330
20 Boston, MA 02111-1307 USA
21 */
22
23 package novaworx.viewarea;
24
25 import java.awt.*;
26 import java.awt.event.*;
27 import java.util.*;
28 import java.util.prefs.*;
29 import javax.swing.*;
30 import javax.swing.event.*;
31 import novaworx.gui.*;
32 import novaworx.swing.*;
33 import cosmoworx.log.*;
34
35 /**
36 <p>The <code>ViewPane</code> is used by the <code>ViewArea</code>
37 to to construct the view area. This class is abstract and intended
38 to be extended by implementing classes. <code>ViewArea</code> uses
39 a <code>ViewPaneFactory</code> to create <code>ViewPane</code>
40 objects. Custom implementers of <code>ViewPaneFactory</code> must
41 return subclasses of this class.</p>
42 */
43 public abstract class ViewPane extends JComponent implements SwingConstants, RootPaneContainer {
44
45 /**
46 The selected flag. This is used to determine if the pane is
47 selected or not. This flag is true unless the pane has been
48 added to a <code>ViewArea</code> object. In such case the
49 <code>ViewArea</code> is responsible for setting the flag.
50 */
51 private boolean mbSelected;
52
53 /**
54 The percent X1 value.
55 */
56 double mdX1 = 0.0;
57
58 /**
59 The percent Y1 value.
60 */
61 double mdY1 = 0.0f;
62
63 /**
64 The percent X2 value.
65 */
66 double mdX2 = 1.0;
67
68 /**
69 The percent Y2 value.
70 */
71 double mdY2 = 1.0;
72
73 /**
74 The divider to the north.
75 */
76 ViewDivider moNorthDivider;
77
78 /**
79 The divider on the east.
80 */
81 ViewDivider moEastDivider;
82
83 /**
84 The divider to the south.
85 */
86 ViewDivider moSouthDivider;
87
88 /**
89 The divider to the west.
90 */
91 ViewDivider moWestDivider;
92
93 /**
94 The header.
95 */
96 private ViewHeader moViewHeader;
97
98 /**
99 The <code>JRootPane</code>.
100 */
101 private JRootPane moRootPane;
102
103 /**
104 The <code>ViewPaneListener</code> list.
105 */
106 private Vector mvViewPaneListeners;
107
108 /**
109 The maximize action.
110 */
111 private MaximizeAction moMaximizeAction;
112
113 /**
114 The restore action.
115 */
116 private RestoreAction moRestoreAction;
117
118 /**
119 The close action.
120 */
121 private CloseAction moCloseAction;
122
123 /**
124 The <code>Preferences</code> node.
125 */
126 private Preferences moPreferences;
127
128 /**
129 The preference change chandler.
130 */
131 private PreferenceChangeHandler moPreferenceChangeHandler;
132
133 /**
134 Construct a <code>ViewPane</code> object.
135 */
136 protected ViewPane( ViewHeader aoViewHeader ) {
137 if( aoViewHeader == null ) throw new IllegalArgumentException( "Header can not be null." );
138 moViewHeader = aoViewHeader;
139 aoViewHeader.setViewPane( this );
140
141 // Create the listener list.
142 mvViewPaneListeners = new Vector();
143
144 // Create the preference change handler.
145 moPreferenceChangeHandler = new PreferenceChangeHandler();
146
147 // Set the layout.
148 setLayout( new BorderLayout() );
149
150 // Set transparent.
151 setOpaque( false );
152
153 // Create the root pane.
154 moRootPane = new XRootPane();
155 add( moRootPane, BorderLayout.CENTER );
156
157 // Setup any actions.
158 moMaximizeAction = new MaximizeAction();
159 moRestoreAction = new RestoreAction();
160 moCloseAction = new CloseAction();
161
162 aoViewHeader.getMaximizeButton().addActionListener( moMaximizeAction );
163 aoViewHeader.getCloseButton().addActionListener( moCloseAction );
164 }
165
166 /**
167 Called by <code>ViewArea</code> to notify that this pane is selected.
168 */
169 protected void select() {
170 //
171 }
172
173 /**
174 Called by <code>ViewArea</code> to notify that this pane is unselected.
175 */
176 protected void unselect() {
177 //
178 }
179
180 /**
181 Is the pane selected.
182 */
183 public boolean isSelected() {
184 ViewArea oViewArea = getViewArea();
185 if( oViewArea == null ) {
186 return true;
187 } else {
188 return oViewArea.getSelectedViewPane() == this;
189 }
190 }
191
192 /**
193 The the icon for the pane.
194 */
195 public void setIcon( Icon aoIcon ) {
196 moViewHeader.setIcon( aoIcon );
197 }
198
199 /**
200 Set the title.
201 */
202 public void setTitle( String asTitle ) {
203 moViewHeader.setTitle( asTitle );
204 }
205
206 /**
207 Get the <code>ViewArea</code> containing this pane.
208 If the pane is not contained or not contained by a
209 <code>ViewArea</code> object then null is returned.
210 */
211 public ViewArea getViewArea() {
212 Component oParent = getParent();
213 return ( oParent instanceof ViewArea ) ? (ViewArea)oParent : null;
214 }
215
216 /**
217 Get the <code>ViewHeader</code>.
218 */
219 public ViewHeader getViewHeader() {
220 return moViewHeader;
221 }
222
223 /**
224 This component is a validation root.
225 */
226 public boolean isValidateRoot() {
227 return true;
228 }
229
230 /**
231 Get the root pane.
232 */
233 public JRootPane getRootPane() {
234 return moRootPane;
235 }
236
237 /**
238 Set the glass pane.
239 */
240 public void setGlassPane( Component aoPane ) {
241 moRootPane.setGlassPane( aoPane );
242 }
243
244 /**
245 Get the glass pane.
246 */
247 public Component getGlassPane() {
248 return moRootPane.getGlassPane();
249 }
250
251 /**
252 Set the layered pane.
253 */
254 public void setLayeredPane( JLayeredPane aoPane ) {
255 moRootPane.setLayeredPane( aoPane );
256 }
257
258 /**
259 Get the layered pane.
260 */
261 public JLayeredPane getLayeredPane() {
262 return moRootPane.getLayeredPane();
263 }
264
265 /**
266 Set the content pane.
267 */
268 public void setContentPane( Container aoPane ) {
269 moRootPane.setContentPane( aoPane );
270 }
271
272 /**
273 Get the content pane.
274 */
275 public Container getContentPane() {
276 return moRootPane.getContentPane();
277 }
278
279 /**
280 Maximize this pane.
281 */
282 public void maximize() throws ViewPaneVetoException {
283 firePaneWillMaximize();
284
285 getViewHeader().getMaximizeButton().removeActionListener( moMaximizeAction );
286 ViewArea oViewArea = getViewArea();
287 if( oViewArea != null ) oViewArea.setMaximizedPane( this );
288 getViewHeader().getMaximizeButton().addActionListener( moRestoreAction );
289 getViewHeader().getMaximizeButton().setIcon( IconLibrary.get( "pane.restore" ) );
290 getViewHeader().getMaximizeButton().setPressedIcon( IconLibrary.getPressed( "pane.restore" ) );
291
292 firePaneMaximized();
293 }
294
295 /**
296 Restore this pane.
297 */
298 public void restore() throws ViewPaneVetoException {
299 firePaneWillRestore();
300
301 getViewHeader().getMaximizeButton().removeActionListener( moRestoreAction );
302 ViewArea oViewArea = getViewArea();
303 if( oViewArea != null ) oViewArea.setMaximizedPane( null );
304 getViewHeader().getMaximizeButton().addActionListener( moMaximizeAction );
305 getViewHeader().getMaximizeButton().setIcon( IconLibrary.get( "pane.maximize" ) );
306 getViewHeader().getMaximizeButton().setPressedIcon( IconLibrary.getPressed( "pane.maximize" ) );
307
308 firePaneRestored();
309 }
310
311 /**
312 Close the pane. This mostly just sends events
313 since a pane cannot be removed by closing it,
314 only by having it merged by another pane.
315 */
316 public void close() throws ViewPaneVetoException {
317 firePaneWillClose();
318
319 // Do anything necessary to close the pane.
320
321 firePaneClosed();
322 }
323
324 /**
325 Add a <code>ViewPaneListener</code>.
326 */
327 public void addViewPaneListener( ViewPaneListener aoListener ) {
328 mvViewPaneListeners.add( aoListener );
329 }
330
331 /**
332 Remove a <code>ViewPaneListener</code>.
333 */
334 public void removeViewPaneListener( ViewPaneListener aoListener ) {
335 mvViewPaneListeners.remove( aoListener );
336 }
337
338 /**
339 Send a pane resized event to all registered listeners.
340 */
341 void firePaneResized() {
342 Vector vListeners = (Vector)mvViewPaneListeners.clone();
343 int iSize = vListeners.size();
344 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
345 ((ViewPaneListener)vListeners.get( iIndex )).paneResized( new ViewPaneEvent( ViewPane.this ) );
346 }
347 }
348
349 /**
350 Send a pane activated event to all registered listeners.
351 */
352 void firePaneActivated() {
353 Vector vListeners = (Vector)mvViewPaneListeners.clone();
354 int iSize = vListeners.size();
355 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
356 ((ViewPaneListener)vListeners.get( iIndex )).paneActivated( new ViewPaneEvent( ViewPane.this ) );
357 }
358 }
359
360 /**
361 Send a pane deactivated event to all registered listeners.
362 */
363 void firePaneDeactivated() {
364 Vector vListeners = (Vector)mvViewPaneListeners.clone();
365 int iSize = vListeners.size();
366 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
367 ((ViewPaneListener)vListeners.get( iIndex )).paneDeactivated( new ViewPaneEvent( ViewPane.this ) );
368 }
369 }
370
371 /**
372 Send a pane will split event to all registered listeners.
373 */
374 void firePaneWillSplit() throws ViewPaneVetoException {
375 Vector vListeners = (Vector)mvViewPaneListeners.clone();
376 int iSize = vListeners.size();
377 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
378 ((ViewPaneListener)vListeners.get( iIndex )).paneWillSplit( new ViewPaneEvent( ViewPane.this ) );
379 }
380 }
381
382 /**
383 Send a pane split event to all registered listeners.
384 */
385 void firePaneSplit() {
386 Vector vListeners = (Vector)mvViewPaneListeners.clone();
387 int iSize = vListeners.size();
388 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
389 ((ViewPaneListener)vListeners.get( iIndex )).paneSplit( new ViewPaneEvent( ViewPane.this ) );
390 }
391 }
392
393 /**
394 Send a pane will merge event to all registered listeners.
395 */
396 void firePaneWillMerge() throws ViewPaneVetoException {
397 Vector vListeners = (Vector)mvViewPaneListeners.clone();
398 int iSize = vListeners.size();
399 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
400 ((ViewPaneListener)vListeners.get( iIndex )).paneWillMerge( new ViewPaneEvent( ViewPane.this ) );
401 }
402 }
403
404 /**
405 Send a pane merged event to all registered listeners.
406 */
407 void firePaneMerged() {
408 Vector vListeners = (Vector)mvViewPaneListeners.clone();
409 int iSize = vListeners.size();
410 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
411 ((ViewPaneListener)vListeners.get( iIndex )).paneMerged( new ViewPaneEvent( ViewPane.this ) );
412 }
413 }
414
415 /**
416 Send a pane will maximize event to all registered listeners.
417 */
418 void firePaneWillMaximize() throws ViewPaneVetoException {
419 Vector vListeners = (Vector)mvViewPaneListeners.clone();
420 int iSize = vListeners.size();
421 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
422 ((ViewPaneListener)vListeners.get( iIndex )).paneWillMaximize( new ViewPaneEvent( ViewPane.this ) );
423 }
424 }
425
426 /**
427 Send a pane maximized event to all registered listeners.
428 */
429 void firePaneMaximized() {
430 Vector vListeners = (Vector)mvViewPaneListeners.clone();
431 int iSize = vListeners.size();
432 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
433 ((ViewPaneListener)vListeners.get( iIndex )).paneMaximized( new ViewPaneEvent( ViewPane.this ) );
434 }
435 }
436
437 /**
438 Send a pane will restore event to all registered listeners.
439 */
440 void firePaneWillRestore() throws ViewPaneVetoException {
441 Vector vListeners = (Vector)mvViewPaneListeners.clone();
442 int iSize = vListeners.size();
443 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
444 ((ViewPaneListener)vListeners.get( iIndex )).paneWillRestore( new ViewPaneEvent( ViewPane.this ) );
445 }
446 }
447
448 /**
449 Send a pane restored event to all registered listeners.
450 */
451 void firePaneRestored() {
452 Vector vListeners = (Vector)mvViewPaneListeners.clone();
453 int iSize = vListeners.size();
454 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
455 ((ViewPaneListener)vListeners.get( iIndex )).paneRestored( new ViewPaneEvent( ViewPane.this ) );
456 }
457 }
458
459 /**
460 Send a pane will close event to all registered listeners.
461 */
462 void firePaneWillClose() throws ViewPaneVetoException {
463 Vector vListeners = (Vector)mvViewPaneListeners.clone();
464 int iSize = vListeners.size();
465 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
466 ((ViewPaneListener)vListeners.get( iIndex )).paneWillClose( new ViewPaneEvent( ViewPane.this ) );
467 }
468 }
469
470 /**
471 Send a pane closed event to all registered listeners.
472 */
473 void firePaneClosed() {
474 Vector vListeners = (Vector)mvViewPaneListeners.clone();
475 int iSize = vListeners.size();
476 for( int iIndex = 0; iIndex < iSize; iIndex++ ) {
477 ((ViewPaneListener)vListeners.get( iIndex )).paneClosed( new ViewPaneEvent( ViewPane.this ) );
478 }
479 }
480
481 /**
482 Set the <code>Preferences</code> node for the view area.
483 The preferences object handles the state of the view area.
484 Specifically it stores the layout of the dividers and panes.
485 */
486 public void setPreferences( Preferences aoPreferences, Preferences aoDefaultPreferences ) {
487 if( aoPreferences == moPreferences ) return;
488 moPreferences = aoPreferences;
489 if( aoPreferences != null ) {
490 //loadPreferences( aoPreferences, aoDefaultPreferences );
491 moPreferenceChangeHandler.init( aoPreferences, aoDefaultPreferences );
492 }
493 }
494
495 /**
496 Get the <code>Preferences</code> node for the view area.
497 The preferences object handles the state of the view area.
498 Specifically it stores the layout of the dividers and panes.
499 */
500 public Preferences getPreferences() {
501 return moPreferences;
502 }
503
504 /**
505 Load the state from the <code>Preferences</code> node.
506 */
507 private void loadPreferences( Preferences aoPreferences, Preferences aoDefaultPreferences ) {
508 }
509
510 /**
511 The maximize action.
512 */
513 private class MaximizeAction extends AbstractAction {
514 public void actionPerformed( ActionEvent aoEvent ) {
515 try {
516 maximize();
517 } catch( ViewPaneVetoException aoException ) {
518 Log.write( Log.ERROR, aoException );
519 }
520 }
521 }
522
523 /**
524 The restore action.
525 */
526 private class RestoreAction extends AbstractAction {
527 public void actionPerformed( ActionEvent aoEvent ) {
528 try {
529 restore();
530 } catch( ViewPaneVetoException aoException ) {
531 Log.write( Log.ERROR, aoException );
532 }
533 }
534 }
535
536 /**
537 The close action.
538 */
539 private class CloseAction extends AbstractAction {
540 public void actionPerformed( ActionEvent aoEvent ) {
541 try {
542 close();
543 } catch( ViewPaneVetoException aoException ) {
544 Log.write( Log.ERROR, aoException );
545 }
546 }
547 }
548
549 /**
550 Listenes for changes to important preferences.
551 */
552 private class PreferenceChangeHandler implements PreferenceChangeListener {
553
554 /**
555 Initialize the preferences.
556 */
557 public void init( Preferences aoPreferences, Preferences aoDefaultPreferences ) {
558 aoPreferences.addPreferenceChangeListener( this );
559 //PreferenceEngine.get().initPreference( aoPreferences, "viewpane", this, aoDefaultPreferences );
560 }
561
562 /**
563 Called when a preference changes.
564 */
565 public void preferenceChange( PreferenceChangeEvent aoEvent ) {
566 Preferences oPreferences = aoEvent.getNode();
567
568 String sPath = oPreferences.absolutePath();
569 String sKey = aoEvent.getKey();
570 String sValue = aoEvent.getNewValue();
571
572 if( oPreferences == moPreferences ) {
573 //if( "viewpane".equals( sKey ) ) {
574 //
575 //}
576 }
577 }
578
579 }
580
581 }