KickJava   Java API By Example, From Geeks To Geeks.

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


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.Debug;
25 import org.netbeans.core.windows.ModeStructureSnapshot;
26 import org.netbeans.core.windows.ModeStructureSnapshot.ElementSnapshot;
27 import org.netbeans.core.windows.WindowSystemSnapshot;
28
29 import java.util.*;
30 import org.netbeans.core.windows.model.ModelElement;
31
32
33
34 /**
35  * This class converts snapshot to accessor structure, which is a 'model'
36  * of view (GUI) structure window system has to display to user.
37  * It reflects the specific view implementation (the difference from snapshot)
38  * e.g. merging of split panes with the same orientation, accomodates for split
39  * panes with only one visible child etc.
40  *
41  * @author Peter Zavadsky
42  */

43 final class ViewHelper {
44     
45     /** Debugging flag. */
46     private static final boolean DEBUG = Debug.isLoggable(ViewHelper.class);
47     
48     
49     /** Creates a new instance of ViewHelper */
50     private ViewHelper() {
51     }
52     
53     
54     public static WindowSystemAccessor createWindowSystemAccessor(
55         WindowSystemSnapshot wss
56     ) {
57         // PENDING When hiding is null.
58
if(wss == null) {
59             return null;
60         }
61         
62         WindowSystemAccessorImpl wsa = new WindowSystemAccessorImpl();
63
64         ModeStructureAccessorImpl msa = createModeStructureAccessor(wss.getModeStructureSnapshot());
65         wsa.setModeStructureAccessor(msa);
66
67         ModeStructureSnapshot.ModeSnapshot activeSnapshot = wss.getActiveModeSnapshot();
68         wsa.setActiveModeAccessor(activeSnapshot == null ? null : msa.findModeAccessor(activeSnapshot.getName()));
69         
70         ModeStructureSnapshot.ModeSnapshot maximizedSnapshot = wss.getMaximizedModeSnapshot();
71         wsa.setMaximizedModeAccessor(maximizedSnapshot == null ? null : msa.findModeAccessor(maximizedSnapshot.getName()));
72
73         wsa.setMainWindowBoundsJoined(wss.getMainWindowBoundsJoined());
74         wsa.setMainWindowBoundsSeparated(wss.getMainWindowBoundsSeparated());
75         wsa.setEditorAreaBounds(wss.getEditorAreaBounds());
76         wsa.setEditorAreaState(wss.getEditorAreaState());
77         wsa.setEditorAreaFrameState(wss.getEditorAreaFrameState());
78         wsa.setMainWindowFrameStateJoined(wss.getMainWindowFrameStateJoined());
79         wsa.setMainWindowFrameStateSeparated(wss.getMainWindowFrameStateSeparated());
80         wsa.setToolbarConfigurationName(wss.getToolbarConfigurationName());
81         return wsa;
82     }
83     
84     private static ModeStructureAccessorImpl createModeStructureAccessor(ModeStructureSnapshot mss) {
85         ElementAccessor splitRoot = createVisibleAccessor(mss.getSplitRootSnapshot());
86         Set<ModeAccessor> separateModes = createSeparateModeAccessors(mss.getSeparateModeSnapshots());
87         Set<SlidingAccessor> slidingModes = createSlidingModeAccessors(mss.getSlidingModeSnapshots());
88         
89         ModeStructureAccessorImpl msa = new ModeStructureAccessorImpl(splitRoot, separateModes, slidingModes);
90         return msa;
91     }
92     
93     private static Set<ModeAccessor> createSeparateModeAccessors(ModeStructureSnapshot.ModeSnapshot[] separateModeSnapshots) {
94         Set<ModeAccessor> s = new HashSet<ModeAccessor>();
95         for(int i = 0; i < separateModeSnapshots.length; i++) {
96             ModeStructureSnapshot.ModeSnapshot snapshot = separateModeSnapshots[i];
97             if(snapshot.isVisibleSeparate()) {
98                 s.add(new ModeStructureAccessorImpl.ModeAccessorImpl(
99                     snapshot.getOriginator(),
100                     snapshot));
101             }
102         }
103         
104         return s;
105     }
106     
107     private static Set<SlidingAccessor> createSlidingModeAccessors(ModeStructureSnapshot.SlidingModeSnapshot[] slidingModeSnapshots) {
108         Set<SlidingAccessor> s = new HashSet<SlidingAccessor>();
109         ModeStructureSnapshot.SlidingModeSnapshot snapshot;
110         for(int i = 0; i < slidingModeSnapshots.length; i++) {
111             snapshot = slidingModeSnapshots[i];
112             s.add(new ModeStructureAccessorImpl.SlidingAccessorImpl(
113                 snapshot.getOriginator(),
114                 snapshot,
115                 snapshot.getSide(),
116                 snapshot.getSlideInSizes()
117             ));
118         }
119         
120         return s;
121     }
122
123     /** */
124     private static ElementAccessor createVisibleAccessor(ModeStructureSnapshot.ElementSnapshot snapshot) {
125         if(snapshot == null) {
126             return null;
127         }
128
129         if(snapshot instanceof ModeStructureSnapshot.EditorSnapshot) { // Is always visible.
130
ModeStructureSnapshot.EditorSnapshot editorSnapshot = (ModeStructureSnapshot.EditorSnapshot)snapshot;
131             return new ModeStructureAccessorImpl.EditorAccessorImpl(
132                 editorSnapshot.getOriginator(),
133                 editorSnapshot,
134                 createVisibleAccessor(editorSnapshot.getEditorAreaSnapshot()),
135                 editorSnapshot.getResizeWeight());
136         }
137         
138         if(snapshot.isVisibleInSplit()) {
139             if(snapshot instanceof ModeStructureSnapshot.SplitSnapshot) {
140                 ModeStructureSnapshot.SplitSnapshot splitSnapshot = (ModeStructureSnapshot.SplitSnapshot)snapshot;
141                 return createSplitAccessor(splitSnapshot);
142             } else if(snapshot instanceof ModeStructureSnapshot.ModeSnapshot) {
143                 ModeStructureSnapshot.ModeSnapshot modeSnapshot = (ModeStructureSnapshot.ModeSnapshot)snapshot;
144                 return new ModeStructureAccessorImpl.ModeAccessorImpl(
145                     modeSnapshot.getOriginator(),
146                     modeSnapshot);
147             }
148         } else {
149             if(snapshot instanceof ModeStructureSnapshot.SplitSnapshot) {
150                 //the split has only one visible child, so create an accessor for this child
151
ModeStructureSnapshot.SplitSnapshot splitSnapshot = (ModeStructureSnapshot.SplitSnapshot)snapshot;
152                 for(Iterator it = splitSnapshot.getChildSnapshots().iterator(); it.hasNext(); ) {
153                     ModeStructureSnapshot.ElementSnapshot child = (ModeStructureSnapshot.ElementSnapshot)it.next();
154                     if(child.hasVisibleDescendant()) {
155                         return createVisibleAccessor(child);
156                     }
157                 }
158             }
159         }
160         
161         return null;
162     }
163     
164     private static ElementAccessor createSplitAccessor(ModeStructureSnapshot.SplitSnapshot splitSnapshot) {
165         List visibleChildren = splitSnapshot.getVisibleChildSnapshots();
166         
167         ArrayList<ElementAccessor> children = new ArrayList<ElementAccessor>( visibleChildren.size() );
168         ArrayList<Double JavaDoc> weights = new ArrayList<Double JavaDoc>( visibleChildren.size() );
169         
170         int index = 0;
171         for( Iterator i=visibleChildren.iterator(); i.hasNext(); index++ ) {
172             ModeStructureSnapshot.ElementSnapshot child = (ModeStructureSnapshot.ElementSnapshot)i.next();
173             ElementAccessor childAccessor = createVisibleAccessor( child );
174             double weight = splitSnapshot.getChildSnapshotSplitWeight( child );
175             //double weight = getSplitWeight( splitSnapshot, child );
176
if( childAccessor instanceof SplitAccessor
177                 && ((SplitAccessor)childAccessor).getOrientation() == splitSnapshot.getOrientation() ) {
178                 //merge nested splits with the same orientation into one big split
179
//e.g. (A | B | C) where B is a nested split (X | Y | Z)
180
//will be merged into -> (A | X | Y | Z | C)
181
SplitAccessor subSplit = (SplitAccessor)childAccessor;
182                 ElementAccessor[] childrenToMerge = subSplit.getChildren();
183                 double[] weightsToMerge = subSplit.getSplitWeights();
184                 for( int j=0; j<childrenToMerge.length; j++ ) {
185                     children.add( childrenToMerge[j] );
186                     weights.add( Double.valueOf( weightsToMerge[j] * weight ) );
187                 }
188             } else {
189                 children.add( childAccessor );
190                 weights.add( Double.valueOf( weight ) );
191             }
192         }
193         
194         ElementAccessor[] childrenAccessors = new ElementAccessor[children.size()];
195         double[] splitWeights = new double[children.size()];
196         for( int i=0; i<children.size(); i++ ) {
197             ElementAccessor ea = (ElementAccessor)children.get( i );
198             Double JavaDoc weight = (Double JavaDoc)weights.get( i );
199             childrenAccessors[i] = ea;
200             splitWeights[i] = weight.doubleValue();
201         }
202         
203         return new ModeStructureAccessorImpl.SplitAccessorImpl(
204                 splitSnapshot.getOriginator(),
205                 splitSnapshot,
206                 splitSnapshot.getOrientation(),
207                 splitWeights,
208                 childrenAccessors,
209                 splitSnapshot.getResizeWeight());
210     }
211     
212     /**
213      * Update the model with new split weights when user moved a splitter bar or
214      * when the main window has been resized.
215      *
216      * @param splitAccessor The split parent that has been modified.
217      * @param children Split children.
218      * @param splitWeights New split weights.
219      * @param controllerHandler
220      *
221      */

222     public static void setSplitWeights(SplitAccessor splitAccessor,
223         ElementAccessor[] children, double[] splitWeights, ControllerHandler controllerHandler) {
224         
225         ModeStructureSnapshot.SplitSnapshot splitSnapshot = (ModeStructureSnapshot.SplitSnapshot)splitAccessor.getSnapshot();
226
227         if(splitSnapshot == null) {
228             return;
229         }
230         
231         ModelElement[] elements = new ModelElement[ children.length ];
232         for( int i=0; i<children.length; i++ ) {
233             //the split child may belong to another splitter that has only one visible child
234
//so we must set new split weight for its actual parent
235
//e.g. the 'S' = (A | X | C) and X's parent is B -> (X | Y | Z) but Y and Z are not visible
236
//so instead of setting split weight of X in splitter B we must set split weight of B in 'S'
237
//see also method createVisibleAccessor()
238
ModeStructureSnapshot.ElementSnapshot snapshot = findVisibleSplitSnapshot( children[i].getSnapshot() );
239             elements[ i ] = snapshot.getOriginator();
240             //if this splitter has been merged with a nested splitter with the same orientation
241
//then the nested split child split weight must be corrected according to its parent
242
splitWeights[ i ] = correctNestedSplitWeight( snapshot.getParent(), splitWeights[i] );
243         }
244
245         controllerHandler.userChangedSplit( elements, splitWeights );
246     }
247     
248     /**
249      * Recalculate the given child split weight if the given split is nested in a parent
250      * split with the same orientation.
251      * e.g. If this split X is (A | B) with weights 0.5 and 0.5 and is nested in a parent
252      * split (X | Y | Z) with split weights 0.5, 0.25 and 0.25 then the accessors
253      * look like this (A | B | Y | Z) with split weights 0.25, 0.25, 0.25, and 0.25
254      * If the new split weight for A being corrected is 0.3 then the corrected value will be (0.3 / 0.5)
255      *
256      * Another problems is that the parent split may have a different orientation
257      * but contains one visible child only (i.e. does not show in the split hierarchy).
258      * In this case the split weight must be corrected in one level up in the split hierarchy.
259      *
260      * @return New split weight corrected as described above or the original value if the
261      * split does not have a parent split with the same orientation.
262      */

263     private static double correctNestedSplitWeight( ModeStructureSnapshot.SplitSnapshot split, double splitWeight ) {
264         int nestedSplitOrientation = split.getOrientation();
265         ModeStructureSnapshot.SplitSnapshot parentSplit = split.getParent();
266         while( null != parentSplit && !parentSplit.isVisibleInSplit() ) { //issue #59103
267
split = parentSplit;
268             parentSplit = parentSplit.getParent();
269         }
270         if( null != parentSplit && parentSplit.getOrientation() == nestedSplitOrientation ) {
271             double parentSplitWeight = parentSplit.getChildSnapshotSplitWeight( split );
272             if( parentSplit.getVisibleChildSnapshots().size() > 1 && parentSplitWeight > 0.0 )
273                 splitWeight /= parentSplitWeight;
274             
275             return correctNestedSplitWeight( parentSplit, splitWeight );
276         }
277         return splitWeight;
278     }
279     
280     /**
281      * Find the topmost split parent of the given snapshot that is visible in split hierarchy
282      * (i.e. has at least two visible children).
283      */

284     private static ModeStructureSnapshot.ElementSnapshot findVisibleSplitSnapshot( ModeStructureSnapshot.ElementSnapshot snapshot ) {
285         ModeStructureSnapshot.SplitSnapshot parent = snapshot.getParent();
286         if( null != parent ) {
287             List visibleChildren = parent.getVisibleChildSnapshots();
288             if( visibleChildren.size() == 1 ) {
289                 return findVisibleSplitSnapshot( parent );
290             }
291         }
292         return snapshot;
293     }
294
295     private static void debugLog(String JavaDoc message) {
296         Debug.log(ViewHelper.class, message);
297     }
298
299 }
300
301
Popular Tags