KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > windows > view > ViewHierarchy


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20
21 package org.netbeans.core.windows.view;
22
23
24 import org.netbeans.core.windows.Constants;
25 import org.netbeans.core.windows.view.dnd.WindowDnDManager;
26 import org.netbeans.core.windows.view.ui.DesktopImpl;
27 import org.netbeans.core.windows.view.ui.EditorAreaFrame;
28 import org.netbeans.core.windows.view.ui.MainWindow;
29 import org.netbeans.core.windows.view.ui.slides.SlideOperation;
30
31 import javax.swing.*;
32 import java.awt.*;
33 import java.awt.event.*;
34 import java.util.*;
35 import java.util.List JavaDoc;
36
37 import org.netbeans.core.windows.Debug;
38 import org.openide.windows.TopComponent;
39
40 /**
41  * Class which manages GUI components.
42  *
43  * @author Peter Zavadsky
44  */

45 final class ViewHierarchy {
46
47     /** Observes user changes to view hierarchy. */
48     private final Controller controller;
49     
50     private final WindowDnDManager windowDnDManager;
51
52     /** desktop component maintainer */
53     private DesktopImpl desktop = new DesktopImpl();
54     /** Map of separate mode views (view <-> accessor). */
55     private final Map<ModeView, ModeAccessor> separateModeViews =
56             new HashMap<ModeView, ModeAccessor>(10);
57     /** Map of sliding mode views (view <-> accessor) */
58     private final Map<SlidingView, SlidingAccessor> slidingModeViews =
59             new HashMap<SlidingView, SlidingAccessor>(10);
60     
61     /** Component in which is editor area, when the editor state is separated. */
62     private EditorAreaFrame editorAreaFrame;
63
64     /** Active mode view. */
65     private ModeView activeModeView;
66     /** Maximized mode view. */
67     private ModeView maximizedModeView;
68     private ViewElement currentSplitRoot;
69     
70     /** Last non sliding mode view that were active in the past, or null if no such exists */
71     private ModeView lastNonSlidingActive;
72     
73     /** */
74     private final Map<ElementAccessor,ViewElement> accessor2view =
75             new HashMap<ElementAccessor,ViewElement>(10);
76     /** */
77     private final Map<ViewElement,ElementAccessor> view2accessor =
78             new HashMap<ViewElement,ElementAccessor>(10);
79     
80     private MainWindow mainWindow;
81
82     private final MainWindowListener mainWindowListener;
83     
84     
85     
86     /** Creates a new instance of ViewHierarchy. */
87     public ViewHierarchy(Controller controller, WindowDnDManager windowDnDManager) {
88         this.controller = controller;
89         this.windowDnDManager = windowDnDManager;
90         
91         this.mainWindowListener = new MainWindowListener(controller, this);
92     }
93     
94
95     public boolean isDragInProgress() {
96         return windowDnDManager.isDragging();
97     }
98     
99     public MainWindow getMainWindow() {
100         if (mainWindow == null) {
101             mainWindow = new MainWindow();
102         }
103         return mainWindow;
104     }
105     
106     public void installMainWindowListeners() {
107         mainWindow.addComponentListener(mainWindowListener);
108         mainWindow.addWindowStateListener(mainWindowListener);
109     }
110     
111     public void uninstallMainWindowListeners() {
112         mainWindow.removeComponentListener(mainWindowListener);
113         mainWindow.removeWindowStateListener(mainWindowListener);
114     }
115     
116     /** Updates the view hierarchy according to new structure. */
117     public void updateViewHierarchy(ModeStructureAccessor modeStructureAccessor) {
118         updateAccessors(modeStructureAccessor);
119         //(re)create gridsplit model
120
currentSplitRoot = updateViewForAccessor(modeStructureAccessor.getSplitRootAccessor());
121 // System.out.println("updateViewHierarchy... elem=" + elem);
122
// if (maximizedModeView == null) {
123
//// System.out.println("updateViewHierarchy...splitoroot=" + elem);
124
// setSplitRootIntoDesktop(elem);
125
// } else {
126
//// System.out.println("updateViewHierarchy...mazimized=" + maximizedModeView);
127
// setMaximizedViewIntoDesktop(maximizedModeView);
128
// }
129
if (desktop.getSplitRoot() == null) {
130             setSplitRootIntoDesktop(currentSplitRoot);
131         }
132         updateSeparateViews(modeStructureAccessor.getSeparateModeAccessors());
133         updateSlidingViews(modeStructureAccessor.getSlidingModeAccessors());
134     }
135     
136     /** Puts new instances of accessors in and reuses the old relevant views. */
137     public void updateAccessors(ModeStructureAccessor modeStructureAccessor) {
138         Map<ElementAccessor,ViewElement> a2v =
139                 new HashMap<ElementAccessor,ViewElement>(accessor2view);
140         
141         accessor2view.clear();
142         view2accessor.clear();
143
144         Set<ElementAccessor> accessors = getAllAccessorsForTree(modeStructureAccessor.getSplitRootAccessor());
145         accessors.addAll(Arrays.asList(modeStructureAccessor.getSeparateModeAccessors()));
146         accessors.addAll(Arrays.asList(modeStructureAccessor.getSlidingModeAccessors()));
147         
148         for(ElementAccessor accessor: accessors) {
149             ElementAccessor similar = findSimilarAccessor(accessor, a2v);
150             if(similar != null) {
151                 ViewElement view = a2v.get(similar);
152                 accessor2view.put(accessor, view);
153                 view2accessor.put(view, accessor);
154             }
155         }
156     }
157     
158     private Set<ElementAccessor> getAllAccessorsForTree(ElementAccessor accessor) {
159         Set<ElementAccessor> s = new HashSet<ElementAccessor>();
160         if(accessor instanceof ModeAccessor) {
161             s.add(accessor);
162         } else if(accessor instanceof SplitAccessor) {
163             SplitAccessor sa = (SplitAccessor)accessor;
164             s.add(sa);
165             ElementAccessor[] children = sa.getChildren();
166             for( int i=0; i<children.length; i++ ) {
167                 s.addAll(getAllAccessorsForTree(children[i]));
168             }
169         } else if(accessor instanceof EditorAccessor) {
170             EditorAccessor ea = (EditorAccessor)accessor;
171             s.add(ea);
172             s.addAll(getAllAccessorsForTree(ea.getEditorAreaAccessor()));
173         }
174         
175         return s;
176     }
177     
178     private ElementAccessor findSimilarAccessor(ElementAccessor accessor, Map a2v) {
179         for(Iterator it = a2v.keySet().iterator(); it.hasNext(); ) {
180             ElementAccessor next = (ElementAccessor)it.next();
181             if(accessor.originatorEquals(next)) {
182                 return next;
183             }
184         }
185         
186         return null;
187     }
188
189     
190     private ViewElement updateViewForAccessor(ElementAccessor patternAccessor) {
191         if(patternAccessor == null) {
192             return null;
193         }
194         
195         ViewElement view = accessor2view.get(patternAccessor);
196         
197         if(view != null) {
198             if(patternAccessor instanceof SplitAccessor) {
199                 SplitAccessor sa = (SplitAccessor)patternAccessor;
200                 ElementAccessor[] childAccessors = sa.getChildren();
201                 ArrayList<ViewElement> childViews = new ArrayList<ViewElement>( childAccessors.length );
202                 for( int i=0; i<childAccessors.length; i++ ) {
203                     childViews.add( updateViewForAccessor( childAccessors[i] ) );
204                 }
205                 double[] splitWeights = sa.getSplitWeights();
206                 ArrayList<Double JavaDoc> weights = new ArrayList<Double JavaDoc>( splitWeights.length );
207                 for( int i=0; i<splitWeights.length; i++ ) {
208                     weights.add( Double.valueOf( splitWeights[i] ) );
209                 }
210                 SplitView sv = (SplitView)view;
211                 sv.setOrientation( sa.getOrientation() );
212                 sv.setSplitWeights( weights );
213                 sv.setChildren( childViews );
214                 return sv;
215             } else if(patternAccessor instanceof EditorAccessor) {
216                 EditorAccessor ea = (EditorAccessor)patternAccessor;
217                 EditorView ev = (EditorView)view;
218                 ev.setEditorArea(updateViewForAccessor(ea.getEditorAreaAccessor()));
219                 return ev;
220             } else if(patternAccessor instanceof SlidingAccessor) {
221                 SlidingAccessor sa = (SlidingAccessor)patternAccessor;
222                 SlidingView sv = (SlidingView)view;
223                 sv.setTopComponents(sa.getOpenedTopComponents(), sa.getSelectedTopComponent());
224                 sv.setSlideBounds(sa.getBounds());
225                 sv.setSlideInSizes(sa.getSlideInSizes());
226                 return sv;
227             } else if(patternAccessor instanceof ModeAccessor) {
228                 // It is a ModeView.
229
ModeAccessor ma = (ModeAccessor)patternAccessor;
230                 ModeView mv = (ModeView)view;
231                 mv.setTopComponents(ma.getOpenedTopComponents(), ma.getSelectedTopComponent());
232                 if(ma.getState() == Constants.MODE_STATE_SEPARATED) {
233                     mv.setFrameState(ma.getFrameState());
234                 }
235                 return mv;
236             }
237         } else {
238             if(patternAccessor instanceof SplitAccessor) {
239                 SplitAccessor sa = (SplitAccessor)patternAccessor;
240                 ArrayList<Double JavaDoc> weights = new ArrayList<Double JavaDoc>( sa.getSplitWeights().length );
241                 for( int i=0; i<sa.getSplitWeights().length; i++ ) {
242                     weights.add( Double.valueOf( sa.getSplitWeights()[i]) );
243                 }
244                 ArrayList<ViewElement> children = new ArrayList<ViewElement>( sa.getChildren().length );
245                 for( int i=0; i<sa.getChildren().length; i++ ) {
246                     children.add( updateViewForAccessor( sa.getChildren()[i] ) );
247                 }
248                 SplitView sv = new SplitView(controller, sa.getResizeWeight(),
249                     sa.getOrientation(), weights, children );
250                 accessor2view.put(patternAccessor, sv);
251                 view2accessor.put(sv, patternAccessor);
252                 return sv;
253             } else if(patternAccessor instanceof SlidingAccessor) {
254                 SlidingAccessor sa = (SlidingAccessor)patternAccessor;
255                 SlidingView sv = new SlidingView(controller, windowDnDManager,
256                             sa.getOpenedTopComponents(),sa.getSelectedTopComponent(),
257                             sa.getSide(),
258                             sa.getSlideInSizes());
259                 sv.setSlideBounds(sa.getBounds());
260                 accessor2view.put(patternAccessor, sv);
261                 view2accessor.put(sv, patternAccessor);
262                 return sv;
263             } else if(patternAccessor instanceof ModeAccessor) {
264                 ModeAccessor ma = (ModeAccessor)patternAccessor;
265                 ModeView mv;
266                 if(ma.getState() == Constants.MODE_STATE_JOINED) {
267                     mv = new ModeView(controller, windowDnDManager, ma.getResizeWeight(), ma.getKind(),
268                             ma.getOpenedTopComponents(), ma.getSelectedTopComponent());
269                 } else {
270                     mv = new ModeView(controller, windowDnDManager, ma.getBounds(), ma.getKind(), ma.getFrameState(),
271                             ma.getOpenedTopComponents(), ma.getSelectedTopComponent());
272                 }
273                 accessor2view.put(patternAccessor, mv);
274                 view2accessor.put(mv, patternAccessor);
275                 return mv;
276             } else if(patternAccessor instanceof EditorAccessor) {
277                 // Editor accesssor indicates there is a editor area (possible split subtree of editor modes).
278
EditorAccessor editorAccessor = (EditorAccessor)patternAccessor;
279                 EditorView ev = new EditorView(controller, windowDnDManager,
280                                 editorAccessor.getResizeWeight(), updateViewForAccessor(editorAccessor.getEditorAreaAccessor()));
281                 accessor2view.put(patternAccessor, ev);
282                 view2accessor.put(ev, patternAccessor);
283                 return ev;
284             }
285         }
286         
287         throw new IllegalStateException JavaDoc("Unknown accessor type, accessor=" + patternAccessor); // NOI18N
288
}
289     
290     
291     private void updateSeparateViews(ModeAccessor[] separateModeAccessors) {
292         Map<ModeView, ModeAccessor> newViews = new HashMap<ModeView, ModeAccessor>();
293         for(int i = 0; i < separateModeAccessors.length; i++) {
294             ModeAccessor ma = separateModeAccessors[i];
295             ModeView mv = (ModeView)updateViewForAccessor(ma);
296             newViews.put(mv, ma);
297         }
298         
299         Set<ModeView> oldViews = new HashSet<ModeView>(separateModeViews.keySet());
300         oldViews.removeAll(newViews.keySet());
301         
302         separateModeViews.clear();
303         separateModeViews.putAll(newViews);
304         
305         // Close all old views.
306
for(Iterator it = oldViews.iterator(); it.hasNext(); ) {
307             ModeView mv = (ModeView)it.next();
308             Component comp = mv.getComponent();
309             if(comp.isVisible()) {
310                 comp.setVisible(false);
311             }
312             ((Window) comp).dispose();
313         }
314         
315         // Open all new views.
316
for(Iterator it = newViews.keySet().iterator(); it.hasNext(); ) {
317             ModeView mv = (ModeView)it.next();
318             Component comp = mv.getComponent();
319             // #37463, it is needed to provide a check, otherwise the window would
320
// get fronted each time.
321
if(!comp.isVisible()) {
322                 comp.setVisible(true);
323             }
324         }
325     }
326     
327     private void updateSlidingViews(SlidingAccessor[] slidingModeAccessors) {
328         Map<SlidingView, SlidingAccessor> newViews = new HashMap<SlidingView, SlidingAccessor>();
329         for(int i = 0; i < slidingModeAccessors.length; i++) {
330             SlidingAccessor sa = slidingModeAccessors[i];
331             SlidingView sv = (SlidingView)updateViewForAccessor(sa);
332             newViews.put(sv, sa);
333         }
334         
335         Set<SlidingView> oldViews = new HashSet<SlidingView>(slidingModeViews.keySet());
336         oldViews.removeAll(newViews.keySet());
337     
338         Set<SlidingView> addedViews = new HashSet<SlidingView>(newViews.keySet());
339         addedViews.removeAll(slidingModeViews.keySet());
340
341         slidingModeViews.clear();
342         slidingModeViews.putAll(newViews);
343         
344         // remove old views.
345
for(SlidingView curSv: oldViews) {
346             desktop.removeSlidingView(curSv);
347         }
348         // add all new views.
349
for(SlidingView curSv: addedViews) {
350             desktop.addSlidingView(curSv);
351         }
352     }
353     
354     
355     
356     public ModeView getModeViewForAccessor(ModeAccessor modeAccessor) {
357         return (ModeView)accessor2view.get(modeAccessor);
358     }
359     
360     public ElementAccessor getAccessorForView(ViewElement view) {
361         return (ElementAccessor)view2accessor.get(view);
362     }
363
364     public void activateMode(ModeAccessor activeModeAccessor) {
365         ModeView activeModeV = getModeViewForAccessor(activeModeAccessor);
366         activateModeView(activeModeV);
367     }
368
369     private void activateModeView(ModeView modeView) {
370         setActiveModeView(modeView);
371         if(modeView != null) {
372             modeView.focusSelectedTopComponent();
373             // remember last non sliding active view
374
if (!(modeView instanceof SlidingView)) {
375                 lastNonSlidingActive = modeView;
376             }
377         }
378     }
379     
380     /** Set active mode view. */
381     private void setActiveModeView(ModeView modeView) {
382         //#39729 fix - when main window has focus, do not discard (in SDI the actual component can be hidden
383
if(modeView == activeModeView && activeModeView != null && activeModeView.isActive()) {
384             return;
385         }
386         if(activeModeView != null && modeView != activeModeView) {
387             activeModeView.setActive(false);
388         }
389         
390         activeModeView = modeView;
391         
392         if(activeModeView != null) {
393             activeModeView.setActive(true);
394         }
395     }
396
397     /** Gets active mode view. */
398     public ModeView getActiveModeView() {
399         return activeModeView;
400     }
401     
402     /** Gets last non sliding mode view that was active in the past or null
403      * if no such exists
404      */

405     ModeView getLastNonSlidingActiveModeView() {
406         return lastNonSlidingActive;
407     }
408     
409     public void setMaximizedModeView(ModeView modeView) {
410         if(modeView == maximizedModeView) {
411             return;
412         }
413
414         maximizedModeView = modeView;
415     }
416     
417     public ModeView getMaximizedModeView() {
418         return maximizedModeView;
419     }
420     
421     public void removeModeView(ModeView modeView) {
422         if(!view2accessor.containsKey(modeView)) {
423             return;
424         }
425         
426         Object JavaDoc accessor = view2accessor.remove(modeView);
427         accessor2view.remove(accessor);
428
429         if(separateModeViews.keySet().contains(modeView)) {
430             separateModeViews.keySet().remove(modeView);
431             modeView.getComponent().setVisible(false);
432             return;
433         }
434         
435         setSplitRootIntoDesktop((SplitView)removeModeViewFromElement(desktop.getSplitRoot(), modeView));
436     }
437     
438     /** Gets set of all mode view components. */
439     public Set<Component> getModeComponents() {
440         Set<Component> set = new HashSet<Component>();
441         for(ViewElement next:view2accessor.keySet()) {
442             if(next instanceof ModeView) {
443                 ModeView modeView = (ModeView)next;
444                 set.add(modeView.getComponent());
445             }
446         }
447         
448         return set;
449     }
450     
451     public Component getSlidingModeComponent(String JavaDoc side) {
452         Iterator it = slidingModeViews.keySet().iterator();
453         while (it.hasNext()) {
454             SlidingView mod = (SlidingView)it.next();
455             if (mod.getSide().equals(side)) {
456                 return mod.getComponent();
457             }
458         }
459         return null;
460     }
461     
462     /** Gets set of separate mode view frames and editor frame (if separated). */
463     public Set<Component> getSeparateModeFrames() {
464         Set<Component> s = new HashSet<Component>();
465         for(ModeView modeView: separateModeViews.keySet()) {
466             s.add(modeView.getComponent());
467         }
468         
469         if(editorAreaFrame != null) {
470             s.add(editorAreaFrame);
471         }
472         
473         return s;
474     }
475     
476     
477     private ViewElement removeModeViewFromElement(ViewElement view, ModeView modeView) {
478         if(view == modeView) {
479             return null;
480         } else if(view instanceof SplitView) {
481             SplitView sv = (SplitView)view;
482             List JavaDoc<ViewElement> children = sv.getChildren();
483             ArrayList<ViewElement> newChildren = new ArrayList<ViewElement>( children.size() );
484             ViewElement removedView = null;
485             for(ViewElement child: children) {
486                 ViewElement newChild = removeModeViewFromElement( child, modeView );
487                 if( newChild != child ) {
488                     removedView = child;
489                 }
490                 if( null != newChild )
491                     newChildren.add( newChild );
492             }
493             if( newChildren.size() == 0 ) {
494                 //the view is not split anymore
495
return newChildren.get( 0 );
496             }
497             if( null != removedView ) {
498                 sv.remove( removedView );
499             }
500             sv.setChildren( newChildren );
501             return sv;
502         } else if(view instanceof EditorView) {
503             EditorView ev = (EditorView)view;
504             ev.setEditorArea(removeModeViewFromElement(ev.getEditorArea(), modeView));
505             return ev;
506         }
507         
508         return view;
509     }
510     
511     private Component getDesktopComponent() {
512         return currentSplitRoot == null ? null : desktop.getDesktopComponent();
513     }
514
515     public ViewElement getSplitRootElement() {
516         return currentSplitRoot;
517 // return desktop.getSplitRoot();
518
}
519     
520     public void releaseAll() {
521         setSplitRootIntoDesktop(null);
522         separateModeViews.clear();
523         activeModeView = null;
524         accessor2view.clear();
525     }
526     
527     public void setSplitModesVisible(boolean visible) {
528         setVisibleModeElement(desktop.getSplitRoot(), visible);
529     }
530     
531     private static void setVisibleModeElement(ViewElement view, boolean visible) {
532         if(view instanceof ModeView) {
533             view.getComponent().setVisible(visible);
534         } else if(view instanceof SplitView) {
535             SplitView sv = (SplitView)view;
536             List JavaDoc children = sv.getChildren();
537             for( Iterator i=children.iterator(); i.hasNext(); ) {
538                 ViewElement child = (ViewElement)i.next();
539                 setVisibleModeElement( child, visible );
540             }
541         } else if(view instanceof EditorView) {
542             setVisibleModeElement(((EditorView)view).getEditorArea(), visible);
543         }
544     }
545     
546     public void setSeparateModesVisible(boolean visible) {
547         if(editorAreaFrame != null) {
548             if (editorAreaFrame.isVisible() != visible) {
549                 //#48829 the visible check needed because of this issue
550
editorAreaFrame.setVisible(visible);
551             }
552         }
553         
554         for(ModeView mv: separateModeViews.keySet()) {
555             if (mv.getComponent().isVisible() != visible) {
556                 //#48829 the visible check needed because of this issue
557
mv.getComponent().setVisible(visible);
558             }
559         }
560     }
561
562     public void updateEditorAreaFrameState(int frameState) {
563         if(editorAreaFrame != null) {
564             editorAreaFrame.setExtendedState(frameState);
565         }
566     }
567     
568     public void updateFrameStates() {
569         for(ModeView mv: separateModeViews.keySet()) {
570             mv.updateFrameState();
571         }
572     }
573     
574     public void updateMainWindowBounds(WindowSystemAccessor wsa) {
575         if(wsa.getEditorAreaState() == Constants.EDITOR_AREA_JOINED) {
576             mainWindow.setBounds(wsa.getMainWindowBoundsJoined());
577         } else {
578             // #45832 clear the desktop when going to SDI,
579
setMainWindowDesktop(null);
580             // invalidate to recalculate the main window's preffered size..
581
mainWindow.invalidate();
582             mainWindow.setBounds(wsa.getMainWindowBoundsSeparated());
583         }
584         // #38146 So the updateSplit works with correct size.
585
mainWindow.validate();
586         // PENDING consider better handling this event so there is not doubled
587
// validation (one in MainWindow - needs to be provided here) and this as second one.
588
}
589     
590     private void setMaximizedViewIntoDesktop(ViewElement elem) {
591         boolean revalidate = elem.updateAWTHierarchy(desktop.getInnerPaneDimension());
592         
593         desktop.setMaximizedView(elem);
594         
595         if (revalidate) {
596             desktop.getDesktopComponent().invalidate();
597             ((JComponent)desktop.getDesktopComponent()).revalidate();
598             desktop.getDesktopComponent().repaint();
599         }
600     }
601     
602     
603     private void setSplitRootIntoDesktop(ViewElement root) {
604         boolean revalidate = false;
605         desktop.setSplitRoot(root);
606         if (root != null) {
607             Dimension dim = desktop.getInnerPaneDimension();
608 // debugLog("innerpanedidim=" + dim + " currentsize=" + root.getComponent().getSize());
609
revalidate = root.updateAWTHierarchy(dim);
610         }
611         
612         if (revalidate) {
613             desktop.getDesktopComponent().invalidate();
614             ((JComponent)desktop.getDesktopComponent()).revalidate();
615             desktop.getDesktopComponent().repaint();
616 // debugLog("revalidating..size=" + desktop.getDesktopComponent().getSize() + "innerpane=" + desktop.getInnerPaneDimension());
617
}
618     }
619
620     // PENDING Revise, updating desktop and editor area, bounds... separate this method.
621
public void updateDesktop(WindowSystemAccessor wsa) {
622         Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
623         List JavaDoc<Component> focusOwnerAWTHierarchyChain; // To find out whether there was a change in AWT hierarchy according to focusOwner.
624
if(focusOwner != null) {
625             focusOwnerAWTHierarchyChain = getComponentAWTHierarchyChain(focusOwner);
626         } else {
627             focusOwnerAWTHierarchyChain = Collections.emptyList();
628         }
629         
630         try {
631             if(wsa.getEditorAreaState() == Constants.EDITOR_AREA_JOINED) {
632                 if(maximizedModeView != null) {
633                     setMainWindowDesktop(getDesktopComponent());
634                     setMaximizedViewIntoDesktop(maximizedModeView);
635                     return;
636                 }
637             }
638             
639             int editorAreaState = wsa.getEditorAreaState();
640             if(editorAreaState == Constants.EDITOR_AREA_JOINED) {
641                 if(editorAreaFrame != null) {
642                     editorAreaFrame.setVisible(false);
643                     editorAreaFrame = null;
644                 }
645                 setMainWindowDesktop(getDesktopComponent());
646                 setSplitRootIntoDesktop(getSplitRootElement());
647                 
648             } else {
649                 boolean showEditorFrame = hasEditorAreaVisibleView();
650                 
651                 if(editorAreaFrame == null && showEditorFrame) {
652                     editorAreaFrame = createEditorAreaFrame();
653                     Rectangle editorAreaBounds = wsa.getEditorAreaBounds();
654                     if(editorAreaBounds != null) {
655                         editorAreaFrame.setBounds(editorAreaBounds);
656                     }
657                 } else if(editorAreaFrame != null && !showEditorFrame) { // XXX
658
editorAreaFrame.setVisible(false);
659                     editorAreaFrame = null;
660                 }
661                 
662                 setMainWindowDesktop(null);
663                 if(showEditorFrame) {
664                     setSplitRootIntoDesktop(getSplitRootElement());
665                     setEditorAreaDesktop(getDesktopComponent());
666                     // #39755 restore the framestate of the previously closed editorArea.
667
updateEditorAreaFrameState(wsa.getEditorAreaFrameState());
668                 }
669             }
670         } finally {
671             // XXX #37239, #37632 Preserve focus in case the focusOwner component
672
// was 'shifted' in AWT hierarchy. I.e. when removed/added it loses focus,
673
// but we need to keep it, e.g. for case when its parent split is removing.
674
if(focusOwner != null
675                 && !focusOwnerAWTHierarchyChain.equals(getComponentAWTHierarchyChain(focusOwner))
676                 /** #64189 */ && SwingUtilities.getAncestorOfClass(Window.class, focusOwner) != null) {
677                 focusOwner.requestFocus();
678             }
679         }
680     }
681     
682     public void updateDesktop() {
683         Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
684         List JavaDoc focusOwnerAWTHierarchyChain; // To find out whether there was a change in AWT hierarchy according to focusOwner.
685
if(focusOwner != null) {
686             focusOwnerAWTHierarchyChain = getComponentAWTHierarchyChain(focusOwner);
687         } else {
688             focusOwnerAWTHierarchyChain = Collections.EMPTY_LIST;
689         }
690         try {
691             // System.out.println("updatedesktop()");
692
if(mainWindow.hasDesktop()) {
693                 setMainWindowDesktop(getDesktopComponent());
694                 if(maximizedModeView != null) {
695                     // System.out.println("viewhierarchy: have maximized=" + maximizedModeView.getClass());
696
setMaximizedViewIntoDesktop(maximizedModeView);
697                     // setMainWindowDesktop();
698
} else {
699                     // System.out.println("viewhierarchy: no maximized");
700
setSplitRootIntoDesktop(getSplitRootElement());
701                     // setMainWindowDesktop(getDesktopComponent());
702
}
703             } else {
704                 boolean showEditorFrame = hasEditorAreaVisibleView();
705                 
706                 if(editorAreaFrame != null) {
707                     if(showEditorFrame) {
708                         editorAreaFrame.setDesktop(getDesktopComponent());
709                     } else { // XXX
710
editorAreaFrame.setVisible(false);
711                         editorAreaFrame = null;
712                     }
713                 }
714             }
715         } finally {
716             // XXX #37239, #37632 Preserve focus in case the focusOwner component
717
// was 'shifted' in AWT hierarchy. I.e. when removed/added it loses focus,
718
// but we need to keep it, e.g. for case when its parent split is removing.
719
if(focusOwner != null
720                 && !focusOwnerAWTHierarchyChain.equals(getComponentAWTHierarchyChain(focusOwner))
721                 /** #64189 */ && SwingUtilities.getAncestorOfClass(Window.class, focusOwner) != null) {
722                 focusOwner.requestFocus();
723             }
724         }
725     }
726     
727     public void performSlideIn(SlideOperation operation) {
728         desktop.performSlideIn(operation, getPureEditorAreaBounds());
729     }
730     
731     public void performSlideOut(SlideOperation operation) {
732         desktop.performSlideOut(operation, getPureEditorAreaBounds());
733     }
734     
735     public void performSlideIntoDesktop(SlideOperation operation) {
736         desktop.performSlideIntoDesktop(operation, getPureEditorAreaBounds());
737     }
738     
739     public void performSlideIntoEdge(SlideOperation operation) {
740         desktop.performSlideIntoEdge(operation, getPureEditorAreaBounds());
741     }
742     
743     public void performSlideResize(SlideOperation operation) {
744         desktop.performSlideResize(operation);
745     }
746     
747     public void performSlideToggleMaximize( TopComponent tc, String JavaDoc side ) {
748         desktop.performSlideToggleMaximize( tc, side, getPureEditorAreaBounds());
749     }
750     
751     private void setMainWindowDesktop(Component component) {
752         setDesktop(component, true);
753     }
754     
755     private void setEditorAreaDesktop(Component component) {
756         setDesktop(component, false);
757     }
758     
759     private void setDesktop(Component component, boolean toMainWindow) {
760         
761         if(toMainWindow) {
762             mainWindow.setDesktop(component);
763         } else {
764             editorAreaFrame.setDesktop(component);
765         }
766
767     }
768     
769     
770     private List JavaDoc<Component> getComponentAWTHierarchyChain(Component comp) {
771         List JavaDoc<Component> l = new ArrayList<Component>();
772         Component c = comp;
773         while(c != null) {
774             l.add(c);
775             c = c.getParent();
776         }
777         
778         Collections.reverse(l);
779         return l;
780     }
781     
782     private boolean hasEditorAreaVisibleView() {
783         //#41875 fix, checking for null EditorView, can be null when using the netbeans.winsys.hideEmptyDocArea command line property
784
EditorView view = findEditorAreaElement();
785         return (view != null ? (view.getEditorArea() != null) : false);
786     }
787     
788     
789     private EditorAreaFrame createEditorAreaFrame() {
790         final EditorAreaFrame frame = new EditorAreaFrame();
791         frame.addComponentListener(new ComponentAdapter() {
792             public void componentResized(ComponentEvent evt) {
793                 if(frame.getExtendedState() == Frame.MAXIMIZED_BOTH) {
794                     // Ignore changes when the frame is in maximized state.
795
return;
796                 }
797                 controller.userResizedEditorArea(frame.getBounds());
798             }
799             
800             public void componentMoved(ComponentEvent evt) {
801                 if(frame.getExtendedState() == Frame.MAXIMIZED_BOTH) {
802                     // Ignore changes when the frame is in maximized state.
803
return;
804                 }
805                 controller.userResizedEditorArea(frame.getBounds());
806             }
807         });
808         frame.setWindowActivationListener(controller);
809         
810         frame.addWindowListener(new WindowAdapter() {
811             public void windowClosing(WindowEvent evt) {
812                 closeEditorModes();
813             }
814         });
815         
816         frame.addWindowStateListener(new WindowStateListener() {
817             public void windowStateChanged(WindowEvent evt) {
818      // All the timestamping is a a workaround beause of buggy GNOME and of its kind who iconify the windows on leaving the desktop.
819
long currentStamp = System.currentTimeMillis();
820                 if (currentStamp > (frame.getUserStamp() + 500) && currentStamp > (frame.getMainWindowStamp() + 1000)) {
821                     controller.userChangedFrameStateEditorArea(evt.getNewState());
822                     long stamp = System.currentTimeMillis();
823                     frame.setUserStamp(stamp);
824                 } else {
825                     frame.setUserStamp(0);
826                     frame.setMainWindowStamp(0);
827                     frame.setExtendedState(evt.getOldState());
828                     //frame.setExtendedState(evt.getOldState());
829
}
830                 
831             }
832         });
833         
834         return frame;
835     }
836     
837     private void closeEditorModes() {
838         closeModeForView(findEditorAreaElement().getEditorArea());
839     }
840     
841     private void closeModeForView(ViewElement view) {
842         if(view instanceof ModeView) {
843             controller.userClosingMode((ModeView)view);
844         } else if(view instanceof SplitView) {
845             SplitView sv = (SplitView)view;
846             List JavaDoc children = sv.getChildren();
847             for( Iterator i=children.iterator(); i.hasNext(); ) {
848                 ViewElement child = (ViewElement)i.next();
849                 closeModeForView( child );
850             }
851         }
852     }
853     
854     
855     public void updateEditorAreaBounds(Rectangle bounds) {
856         if(editorAreaFrame != null) {
857             editorAreaFrame.setBounds(bounds);
858         }
859     }
860
861     // XXX
862
public Rectangle getPureEditorAreaBounds() {
863         EditorView editorView = findEditorAreaElement();
864         if(editorView == null) {
865             return new Rectangle();
866         } else {
867             return editorView.getPureBounds();
868         }
869     }
870     
871     private EditorView findEditorAreaElement() {
872         return findEditorViewForElement(getSplitRootElement());
873     }
874     
875     Component getEditorAreaComponent() {
876         EditorView editor = findEditorAreaElement();
877         if( null != editor )
878             return editor.getComponent();
879         return null;
880     }
881     
882     private EditorView findEditorViewForElement(ViewElement view) {
883         if(view instanceof EditorView) {
884             return (EditorView)view;
885         } else if(view instanceof SplitView) {
886             SplitView sv = (SplitView)view;
887             List JavaDoc children = sv.getChildren();
888             for( Iterator i=children.iterator(); i.hasNext(); ) {
889                 ViewElement child = (ViewElement)i.next();
890                 EditorView ev = findEditorViewForElement( child );
891                 if( null != ev )
892                     return ev;
893             }
894         }
895         
896         return null;
897     }
898     
899     public void updateUI() {
900         SwingUtilities.updateComponentTreeUI(mainWindow);
901         if(editorAreaFrame != null) {
902             SwingUtilities.updateComponentTreeUI(editorAreaFrame);
903         }
904         for(ModeView mv: separateModeViews.keySet()) {
905             SwingUtilities.updateComponentTreeUI(mv.getComponent());
906         }
907     }
908     
909     public Set<TopComponent> getShowingTopComponents() {
910         Set<TopComponent> s = new HashSet<TopComponent>();
911         for(ElementAccessor accessor: accessor2view.keySet()) {
912             if(accessor instanceof ModeAccessor) {
913                 s.add(((ModeAccessor)accessor).getSelectedTopComponent());
914             }
915         }
916         for(ModeAccessor accessor: separateModeViews.values()) {
917             s.add(accessor.getSelectedTopComponent());
918         }
919         
920         return s;
921     }
922     
923     public String JavaDoc toString() {
924         return dumpElement(desktop.getSplitRoot(), 0) + "\nseparateViews=" + separateModeViews.keySet(); // NOI18N
925
}
926     
927     private String JavaDoc dumpElement(ViewElement view, int indent) {
928         String JavaDoc indentString = createIndentString(indent);
929         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
930         
931         if(view instanceof ModeView) {
932             sb.append(indentString + view + "->" + view.getComponent().getClass() + "@" + view.getComponent().hashCode());
933         } else if(view instanceof EditorView) {
934             sb.append(indentString + view);
935             sb.append("\n" + dumpElement(((EditorView)view).getEditorArea(), ++indent));
936         } else if(view instanceof SplitView) {
937             sb.append(indentString + view + "->" + view.getComponent().getClass() + "@" + view.getComponent().hashCode());
938             indent++;
939             List JavaDoc children = ((SplitView)view).getChildren();
940             for( Iterator i=children.iterator(); i.hasNext(); ) {
941                 ViewElement child = (ViewElement)i.next();
942                 sb.append("\n" + dumpElement(child, indent));
943             }
944         }
945          
946         return sb.toString();
947     }
948     
949     private static String JavaDoc createIndentString(int indent) {
950         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(indent);
951         for(int i = 0; i < indent; i++) {
952             sb.append(" ");
953         }
954         
955         return sb.toString();
956     }
957
958     private String JavaDoc dumpAccessors() {
959         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
960         for(ElementAccessor accessor: accessor2view.keySet()) {
961             sb.append("accessor="+accessor + "\tview="+accessor2view.get(accessor) + "\n"); // NOI18N
962
}
963         
964         return sb.toString();
965     }
966
967     private void changeStateOfSeparateViews(boolean iconify) {
968      // All the timestamping is a a workaround beause of buggy GNOME and of its kind who iconify the windows on leaving the desktop.
969
long mainStamp = System.currentTimeMillis();
970         if(editorAreaFrame != null) {
971             if (iconify) {
972                 if (mainStamp < (editorAreaFrame.getUserStamp() + 500)) {
973                     int newState = editorAreaFrame.getExtendedState() & ~Frame.ICONIFIED;
974                     controller.userChangedFrameStateEditorArea(newState);
975                     editorAreaFrame.setExtendedState(newState);
976                 }
977             }
978             editorAreaFrame.setMainWindowStamp(mainStamp);
979             editorAreaFrame.setVisible(!iconify);
980         }
981         for(Iterator it = separateModeViews.keySet().iterator(); it.hasNext(); ) {
982             ModeView mv = (ModeView)it.next();
983             Component comp = mv.getComponent();
984             if(comp instanceof Frame) {
985                 Frame fr = (Frame)comp;
986                 if (iconify) {
987                     if (mainStamp < (mv.getUserStamp() + 500)) {
988                         int newState = fr.getExtendedState() & ~Frame.ICONIFIED;
989                         controller.userChangedFrameStateMode(mv, newState);
990                         mv.setFrameState(newState);
991                     }
992                 }
993                 mv.setMainWindowStamp(mainStamp);
994                 fr.setVisible(!iconify);
995             }
996         }
997     }
998
999     
1000    /** Main window listener. */
1001    private static class MainWindowListener extends ComponentAdapter
1002    implements WindowStateListener {
1003        
1004        private final Controller controller;
1005        private final ViewHierarchy hierarchy;
1006        
1007        public MainWindowListener(Controller controller, ViewHierarchy hierarchy) {
1008            this.controller = controller;
1009            this.hierarchy = hierarchy;
1010        }
1011        
1012        public void componentResized(ComponentEvent evt) {
1013            controller.userResizedMainWindow(evt.getComponent().getBounds());
1014        }
1015        
1016        public void componentMoved(ComponentEvent evt) {
1017            controller.userMovedMainWindow(evt.getComponent().getBounds());
1018        }
1019        
1020        public void windowStateChanged(WindowEvent evt) {
1021            int oldState = evt.getOldState();
1022            int newState = evt.getNewState();
1023            controller.userChangedFrameStateMainWindow(newState);
1024            
1025            if (((oldState & Frame.ICONIFIED) == 0) &&
1026                ((newState & Frame.ICONIFIED) == Frame.ICONIFIED)) {
1027                hierarchy.changeStateOfSeparateViews(true);
1028            } else if (((oldState & Frame.ICONIFIED) == Frame.ICONIFIED) &&
1029                       ((newState & Frame.ICONIFIED) == 0 )) {
1030                hierarchy.changeStateOfSeparateViews(false);
1031            }
1032        }
1033    } // End of main window listener.
1034

1035    
1036    private static void debugLog(String JavaDoc message) {
1037        Debug.log(ViewHierarchy.class, message);
1038    }
1039}
1040
1041
Popular Tags