2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.form.layoutsupport;
48
import org.openide.nodes.*;
50
import org.netbeans.modules.form.*;
51
import org.netbeans.modules.form.codestructure.*;
52
import org.netbeans.modules.form.layoutsupport.delegates.NullLayoutSupport;
53
import org.netbeans.modules.form.fakepeer.FakePeerSupport;
56
* Main class of general layout support infrastructure. Connects form editor
57
* metadata with specialized LayoutSupportDelegate implementations (layout
58
* specific functionality is delegated to the right LayoutSupportDelegate).
63
public final class LayoutSupportManager implements LayoutSupportContext {
65
// possible component resizing directions (bit flag constants)
66
public static final int RESIZE_UP = 1;
67
public static final int RESIZE_DOWN = 2;
68
public static final int RESIZE_LEFT = 4;
69
public static final int RESIZE_RIGHT = 8;
71
private LayoutSupportDelegate layoutDelegate;
72
private boolean needInit;
73
private boolean initializeFromInstance;
74
private boolean initializeFromCode;
76
private Node.PropertySet[] propertySets;
78
private LayoutListener layoutListener;
80
private RADVisualContainer metaContainer;
82
private Container primaryContainer; // bean instance from metaContainer
83
private Container primaryContainerDelegate; // container delegate for it
85
private CodeStructure codeStructure;
87
private CodeExpression containerCodeExpression;
88
private CodeExpression containerDelegateCodeExpression;
93
// initialization for a new container, layout delegate is set to null
94
public LayoutSupportManager(RADVisualContainer container,
95
CodeStructure codeStructure)
97
this.metaContainer = container;
98
this.codeStructure = codeStructure;
102
* Creation and initialization of a layout delegate for a new container.
103
* @return false if suitable layout delegate is not found
104
* @throw IllegalArgumentException if the container instance is not empty
106
public boolean prepareLayoutDelegate(boolean fromCode, boolean initialize)
109
LayoutSupportDelegate delegate = null;
110
LayoutManager lmInstance = null;
112
FormModel formModel = metaContainer.getFormModel();
113
LayoutSupportRegistry layoutRegistry =
114
LayoutSupportRegistry.getRegistry(formModel);
116
// first try to find a dedicated layout delegate (for the container)
117
Class layoutDelegateClass = layoutRegistry.getSupportClassForContainer(
118
metaContainer.getBeanClass());
120
if (layoutDelegateClass != null) {
121
delegate = LayoutSupportRegistry.createSupportInstance(layoutDelegateClass);
122
if (!fromCode && !delegate.checkEmptyContainer(getPrimaryContainer())) {
123
RuntimeException ex = new IllegalArgumentException();
124
org.openide.ErrorManager.getDefault().annotate(
125
ex, AbstractLayoutSupport.getBundle().getString(
126
"MSG_ERR_NonEmptyContainer")); // NOI18N
131
// find a general layout delegate (for LayoutManager of the container)
132
if (fromCode) { // initialization from code
133
Iterator it = CodeStructure.getDefinedStatementsIterator(
134
getContainerDelegateCodeExpression());
135
CodeStatement[] statements =
136
CodeStructure.filterStatements(
137
it, AbstractLayoutSupport.getSetLayoutMethod());
139
if (statements.length > 0) { // setLayout method found
140
CodeExpressionOrigin layoutOrigin =
141
statements[0].getStatementParameters()[0].getOrigin();
142
delegate = layoutRegistry.createSupportForLayout(
143
layoutOrigin.getType());
144
// handle special case of null layout
145
if (delegate == null)
146
if (layoutOrigin.getType() == LayoutManager.class
147
&& layoutOrigin.getCreationParameters().length == 0
148
&& layoutOrigin.getParentExpression() == null
149
&& "null".equals(layoutOrigin.getJavaCodeString( // NOI18N
152
delegate = new NullLayoutSupport();
158
if (delegate == null) { // initialization from LayoutManager instance
159
Container contDel = getPrimaryContainerDelegate();
160
if (contDel.getComponentCount() == 0) {
161
// we can still handle only empty containers ...
162
lmInstance = contDel.getLayout();
163
delegate = lmInstance != null ?
164
layoutRegistry.createSupportForLayout(lmInstance.getClass()) :
165
new NullLayoutSupport();
168
RuntimeException ex = new IllegalArgumentException();
169
org.openide.ErrorManager.getDefault().annotate(
170
ex, AbstractLayoutSupport.getBundle().getString(
171
"MSG_ERR_NonEmptyContainer")); // NOI18N
177
if (delegate == null)
181
setLayoutDelegate(delegate, fromCode);
184
layoutDelegate = delegate;
186
initializeFromInstance = lmInstance != null;
187
initializeFromCode = fromCode;
193
public void initializeLayoutDelegate() throws Exception {
194
if (layoutDelegate != null && needInit) {
195
LayoutManager lmInstance = initializeFromInstance ?
196
getPrimaryContainerDelegate().getLayout() : null;
197
layoutDelegate.initialize(this, lmInstance, initializeFromCode);
199
getPropertySets(); // force properties and listeners creation
204
public void setLayoutDelegate(LayoutSupportDelegate newDelegate,
208
LayoutConstraints[] oldConstraints;
209
LayoutSupportDelegate oldDelegate = layoutDelegate;
211
if (layoutDelegate != null
212
&& (layoutDelegate != newDelegate || !fromCode))
213
oldConstraints = removeLayoutDelegate(true);
215
oldConstraints = null;
217
layoutDelegate = newDelegate;
221
if (layoutDelegate != null) {
223
layoutDelegate.initialize(this, null, fromCode);
225
fillLayout(oldConstraints);
226
getPropertySets(); // force properties and listeners creation
228
catch (Exception ex) {
229
removeLayoutDelegate(false);
230
layoutDelegate = oldDelegate;
231
if (layoutDelegate != null)
238
public LayoutSupportDelegate getLayoutDelegate() {
239
return layoutDelegate;
242
public void setUnknownLayoutDelegate(boolean fromCode) {
244
setLayoutDelegate(new UnknownLayoutSupport(), fromCode);
246
catch (Exception ex) { // nothing should happen, ignore
247
ex.printStackTrace();
251
public boolean isUnknownLayout() {
252
return layoutDelegate == null
253
|| layoutDelegate instanceof UnknownLayoutSupport;
256
// copy layout delegate from another container
257
public void copyLayoutDelegateFrom(
258
LayoutSupportManager sourceLayoutSupport,
259
RADVisualComponent[] newMetaComps)
261
LayoutSupportDelegate sourceDelegate =
262
sourceLayoutSupport.getLayoutDelegate();
264
int componentCount = sourceDelegate.getComponentCount();
266
Container cont = getPrimaryContainer();
267
Container contDel = getPrimaryContainerDelegate();
269
if (layoutDelegate != null)
270
removeLayoutDelegate(false);
272
CodeExpression[] compExps = new CodeExpression[componentCount];
273
Component[] primaryComps = new Component[componentCount];
275
for (int i=0; i < componentCount; i++) {
276
RADVisualComponent metacomp = newMetaComps[i];
277
compExps[i] = metacomp.getCodeExpression();
278
primaryComps[i] = (Component) metacomp.getBeanInstance();
279
ensureFakePeerAttached(primaryComps[i]);
282
LayoutSupportDelegate newDelegate =
283
sourceDelegate.cloneLayoutSupport(this, compExps);
285
newDelegate.setLayoutToContainer(cont, contDel);
286
newDelegate.addComponentsToContainer(cont, contDel, primaryComps, 0);
288
layoutDelegate = newDelegate;
290
// Ensure correct propagation of copied properties (issue 50011, 72351)
292
layoutDelegate.acceptContainerLayoutChange(null);
293
} catch (PropertyVetoException pvex) {
298
public void clearPrimaryContainer() {
299
layoutDelegate.clearContainer(getPrimaryContainer(),
300
getPrimaryContainerDelegate());
303
public RADVisualContainer getMetaContainer() {
304
return metaContainer;
307
// public boolean supportsArranging() {
308
// return layoutDelegate instanceof LayoutSupportArranging;
311
private LayoutConstraints[] removeLayoutDelegate(
312
boolean extractConstraints)
314
CodeGroup code = layoutDelegate.getLayoutCode();
316
CodeStructure.removeStatements(code.getStatementsIterator());
318
int componentCount = layoutDelegate.getComponentCount();
319
LayoutConstraints[] constraints = null;
321
if (componentCount > 0) {
322
RADVisualComponent[] metacomps = metaContainer.getSubComponents();
323
if (metacomps.length == componentCount) { // robustness: might be called after failed layout initialization
324
if (extractConstraints)
325
constraints = new LayoutConstraints[componentCount];
327
for (int i=0; i < componentCount; i++) {
328
LayoutConstraints constr = layoutDelegate.getConstraints(i);
329
if (extractConstraints)
330
constraints[i] = constr;
332
metacomps[i].setLayoutConstraints(layoutDelegate.getClass(),
334
code = layoutDelegate.getComponentCode(i);
336
CodeStructure.removeStatements(code.getStatementsIterator());
341
layoutDelegate.removeAll();
342
layoutDelegate.clearContainer(getPrimaryContainer(),
343
getPrimaryContainerDelegate());
344
layoutDelegate = null;
349
private void fillLayout(LayoutConstraints[] oldConstraints) {
350
RADVisualComponent[] metacomps = metaContainer.getSubComponents();
351
int componentCount = metacomps.length;
353
CodeExpression[] compExps = new CodeExpression[componentCount];
354
Component[] designComps = new Component[componentCount];
355
Component[] primaryComps = new Component[componentCount];
356
LayoutConstraints[] newConstraints = new LayoutConstraints[componentCount];
358
FormDesigner designer = FormEditor.getFormDesigner(metaContainer.getFormModel());
360
for (int i=0; i < componentCount; i++) {
361
RADVisualComponent metacomp = metacomps[i];
363
compExps[i] = metacomp.getCodeExpression();
364
primaryComps[i] = (Component) metacomp.getBeanInstance();
365
ensureFakePeerAttached(primaryComps[i]);
366
newConstraints[i] = metacomp.getLayoutConstraints(
367
layoutDelegate.getClass());
369
Component comp = designer != null ?
370
(Component) designer.getComponent(metacomp) : null;
371
designComps[i] = comp != null ?
372
comp : (Component) metacomp.getBeanInstance();
375
if (oldConstraints != null)
376
layoutDelegate.convertConstraints(oldConstraints,
380
if (componentCount > 0) {
381
layoutDelegate.acceptNewComponents(compExps, newConstraints, 0);
382
layoutDelegate.addComponents(compExps, newConstraints, 0);
384
for (int i=0; i < componentCount; i++)
385
metacomps[i].resetConstraintsProperties();
388
// setup primary container
389
Container cont = getPrimaryContainer();
390
Container contDel = getPrimaryContainerDelegate();
391
// layoutDelegate.clearContainer(cont, contDel);
392
layoutDelegate.setLayoutToContainer(cont, contDel);
393
if (componentCount > 0)
394
layoutDelegate.addComponentsToContainer(cont, contDel,
399
// public API delegated to LayoutSupportDelegate
401
public boolean isDedicated() {
402
return layoutDelegate.isDedicated();
405
public Class getSupportedClass() {
406
return layoutDelegate.getSupportedClass();
410
public boolean shouldHaveNode() {
411
return layoutDelegate.shouldHaveNode();
414
public String getDisplayName() {
415
return layoutDelegate.getDisplayName();
418
public Image getIcon(int type) {
419
return layoutDelegate.getIcon(type);
422
// properties and customizer
423
public Node.PropertySet[] getPropertySets() {
424
if (propertySets == null) {
425
if (layoutDelegate == null) return new Node.PropertySet[0]; // Issue 63916
426
propertySets = layoutDelegate.getPropertySets();
428
for (int i=0; i < propertySets.length; i++) {
429
Node.Property[] props = propertySets[i].getProperties();
430
for (int j=0; j < props.length; j++)
431
if (props[j] instanceof FormProperty) {
432
FormProperty prop = (FormProperty) props[j];
433
prop.addVetoableChangeListener(getLayoutListener());
434
prop.addPropertyChangeListener(getLayoutListener());
441
public Node.Property[] getAllProperties() {
442
if (layoutDelegate instanceof AbstractLayoutSupport)
443
return ((AbstractLayoutSupport)layoutDelegate).getAllProperties();
445
java.util.List<Node.Property> allPropsList = new ArrayList<Node.Property>();
446
for (int i=0; i < propertySets.length; i++) {
447
Node.Property[] props = propertySets[i].getProperties();
448
for (int j=0; j < props.length; j++)
449
allPropsList.add(props[j]);
452
Node.Property[] allProperties = new Node.Property[allPropsList.size()];
453
allPropsList.toArray(allProperties);
454
return allProperties;
457
public Node.Property getLayoutProperty(String name) {
458
if (layoutDelegate instanceof AbstractLayoutSupport)
459
return ((AbstractLayoutSupport)layoutDelegate).getProperty(name);
461
Node.Property[] properties = getAllProperties();
462
for (int i=0; i < properties.length; i++)
463
if (name.equals(properties[i].getName()))
464
return properties[i];
469
public Class getCustomizerClass() {
470
return layoutDelegate.getCustomizerClass();
473
public Component getSupportCustomizer() {
474
return layoutDelegate.getSupportCustomizer();
478
public CodeGroup getLayoutCode() {
479
return layoutDelegate.getLayoutCode();
482
public CodeGroup getComponentCode(int index) {
483
return layoutDelegate.getComponentCode(index);
486
public CodeGroup getComponentCode(RADVisualComponent metacomp) {
487
int index = metaContainer.getIndexOf(metacomp);
488
return index >= 0 && index < layoutDelegate.getComponentCount() ?
489
layoutDelegate.getComponentCode(index) : null;
492
public int getComponentCount() {
493
return layoutDelegate.getComponentCount();
497
public void acceptNewComponents(RADVisualComponent[] components,
498
LayoutConstraints[] constraints,
501
CodeExpression[] compExps = new CodeExpression[components.length];
502
for (int i=0; i < components.length; i++)
503
compExps[i] = components[i].getCodeExpression();
505
layoutDelegate.acceptNewComponents(compExps, constraints, index);
508
// components adding/removing
509
public void addComponents(RADVisualComponent[] components,
510
LayoutConstraints[] constraints,
513
CodeExpression[] compExps = new CodeExpression[components.length];
514
Component[] comps = new Component[components.length];
516
for (int i=0; i < components.length; i++) {
517
compExps[i] = components[i].getCodeExpression();
518
comps[i] = (Component) components[i].getBeanInstance();
519
ensureFakePeerAttached(comps[i]);
523
index = layoutDelegate.getComponentCount();
525
layoutDelegate.addComponents(compExps, constraints, index);
527
for (int i=0; i < components.length; i++)
528
components[i].resetConstraintsProperties();
530
layoutDelegate.addComponentsToContainer(getPrimaryContainer(),
531
getPrimaryContainerDelegate(),
535
public void removeComponent(RADVisualComponent metacomp, int index) {
536
// first store constraints in the meta component
537
LayoutConstraints constr = layoutDelegate.getConstraints(index);
539
metacomp.setLayoutConstraints(layoutDelegate.getClass(), constr);
542
CodeStructure.removeStatements(
543
layoutDelegate.getComponentCode(index).getStatementsIterator());
545
// remove the component from layout
546
layoutDelegate.removeComponent(index);
548
// remove the component instance from the primary container instance
549
if (!layoutDelegate.removeComponentFromContainer(
550
getPrimaryContainer(),
551
getPrimaryContainerDelegate(),
552
(Component)metacomp.getBeanInstance()))
553
{ // layout delegate does not support removing individual components,
554
// so we clear the container and add the remaining components again
555
layoutDelegate.clearContainer(getPrimaryContainer(),
556
getPrimaryContainerDelegate());
558
RADVisualComponent[] metacomps = metaContainer.getSubComponents();
559
if (metacomps.length > 1) {
560
// we rely on that metacomp was not removed from the model yet
561
Component[] comps = new Component[metacomps.length-1];
562
for (int i=0; i < metacomps.length; i++) {
564
Component comp = (Component) metacomps[i].getBeanInstance();
565
ensureFakePeerAttached(comp);
566
comps[i < index ? i : i-1] = comp;
569
layoutDelegate.addComponentsToContainer(
570
getPrimaryContainer(),
571
getPrimaryContainerDelegate(),
578
public void removeAll() {
579
// first store constraints in meta components
580
RADVisualComponent[] components = metaContainer.getSubComponents();
581
for (int i=0; i < components.length; i++) {
582
LayoutConstraints constr =
583
layoutDelegate.getConstraints(i);
585
components[i].setLayoutConstraints(layoutDelegate.getClass(),
589
// remove code of all components
590
for (int i=0, n=layoutDelegate.getComponentCount(); i < n; i++)
591
CodeStructure.removeStatements(
592
layoutDelegate.getComponentCode(i).getStatementsIterator());
594
// remove components from layout
595
layoutDelegate.removeAll();
597
// clear the primary container instance
598
layoutDelegate.clearContainer(getPrimaryContainer(),
599
getPrimaryContainerDelegate());
602
public boolean isLayoutChanged() {
603
Container defaultContainer = (Container)
604
BeanSupport.getDefaultInstance(metaContainer.getBeanClass());
605
Container defaultContDelegate =
606
metaContainer.getContainerDelegate(defaultContainer);
608
return layoutDelegate.isLayoutChanged(defaultContainer,
609
defaultContDelegate);
612
// managing constraints
613
public LayoutConstraints getConstraints(int index) {
614
return layoutDelegate.getConstraints(index);
617
public LayoutConstraints getConstraints(RADVisualComponent metacomp) {
618
if (layoutDelegate == null)
621
int index = metaContainer.getIndexOf(metacomp);
622
return index >= 0 && index < layoutDelegate.getComponentCount() ?
623
layoutDelegate.getConstraints(index) : null;
626
public static LayoutConstraints storeConstraints(
627
RADVisualComponent metacomp)
629
RADVisualContainer parent = metacomp.getParentContainer();
633
LayoutSupportManager layoutSupport = parent.getLayoutSupport();
634
if (layoutSupport == null)
636
LayoutConstraints constr = layoutSupport.getConstraints(metacomp);
638
metacomp.setLayoutConstraints(
639
layoutSupport.getLayoutDelegate().getClass(),
644
public LayoutConstraints getStoredConstraints(RADVisualComponent metacomp) {
645
return metacomp.getLayoutConstraints(layoutDelegate.getClass());
648
// managing live components
649
public void setLayoutToContainer(Container container,
650
Container containerDelegate)
652
layoutDelegate.setLayoutToContainer(container, containerDelegate);
655
public void addComponentsToContainer(Container container,
656
Container containerDelegate,
657
Component[] components,
660
layoutDelegate.addComponentsToContainer(container, containerDelegate,
664
public boolean removeComponentFromContainer(Container container,
665
Container containerDelegate,
668
return layoutDelegate.removeComponentFromContainer(
669
container, containerDelegate, component);
672
public boolean clearContainer(Container container,
673
Container containerDelegate)
675
return layoutDelegate.clearContainer(container, containerDelegate);
678
// drag and drop support
679
public LayoutConstraints getNewConstraints(Container container,
680
Container containerDelegate,
687
LayoutConstraints constraints = layoutDelegate.getNewConstraints(container, containerDelegate,
689
posInCont, posInComp);
690
String context = null;
691
Object[] params = null;
692
if (layoutDelegate instanceof AbstractLayoutSupport) {
693
AbstractLayoutSupport support = (AbstractLayoutSupport)layoutDelegate;
694
context = support.getAssistantContext();
695
params = support.getAssistantParams();
697
context = (context == null) ? "generalPosition" : context; // NOI18N
698
FormEditor.getAssistantModel(metaContainer.getFormModel()).setContext(context, params);
702
public int getNewIndex(Container container,
703
Container containerDelegate,
709
return layoutDelegate.getNewIndex(container, containerDelegate,
711
posInCont, posInComp);
714
public boolean paintDragFeedback(Container container,
715
Container containerDelegate,
717
LayoutConstraints newConstraints,
721
return layoutDelegate.paintDragFeedback(container, containerDelegate,
723
newConstraints, newIndex,
728
public int getResizableDirections(Container container,
729
Container containerDelegate,
733
return layoutDelegate.getResizableDirections(container,
738
public LayoutConstraints getResizedConstraints(Container container,
739
Container containerDelegate,
742
Rectangle originalBounds,
746
return layoutDelegate.getResizedConstraints(container,
755
public void processMouseClick(Point p,
757
Container contDelegate)
759
layoutDelegate.processMouseClick(p, cont, contDelegate);
763
public void selectComponent(int index) {
764
layoutDelegate.selectComponent(index);
768
public void arrangeContainer(Container container,
769
Container containerDelegate)
771
layoutDelegate.arrangeContainer(container, containerDelegate);
775
// API for layout delegates (LayoutSupportContext implementation)
777
public CodeStructure getCodeStructure() {
778
return codeStructure;
781
public CodeExpression getContainerCodeExpression() {
782
if (containerCodeExpression == null) {
783
containerCodeExpression = metaContainer.getCodeExpression();
784
containerDelegateCodeExpression = null;
786
return containerCodeExpression;
789
public CodeExpression getContainerDelegateCodeExpression() {
790
if (containerDelegateCodeExpression == null) {
791
containerDelegateCodeExpression =
792
containerDelegateCodeExpression(metaContainer, codeStructure);
795
return containerDelegateCodeExpression;
798
public static CodeExpression containerDelegateCodeExpression(
799
RADVisualContainer metaContainer,
800
CodeStructure codeStructure)
802
CodeExpression containerCodeExpression = metaContainer.getCodeExpression();
803
CodeExpression containerDelegateCodeExpression;
804
java.lang.reflect.Method delegateGetter =
805
metaContainer.getContainerDelegateMethod();
807
if (delegateGetter != null) { // there should be a container delegate
808
Iterator it = CodeStructure.getDefinedExpressionsIterator(
809
containerCodeExpression);
810
CodeExpression[] expressions = CodeStructure.filterExpressions(
812
if (expressions.length > 0) {
813
// the expresion for the container delegate already exists
814
containerDelegateCodeExpression = expressions[0];
816
else { // create a new expresion for the container delegate
817
CodeExpressionOrigin origin = CodeStructure.createOrigin(
818
containerCodeExpression,
821
containerDelegateCodeExpression =
822
codeStructure.createExpression(origin);
825
else // no special container delegate
826
containerDelegateCodeExpression = containerCodeExpression;
827
return containerDelegateCodeExpression;
830
// return container instance of meta container
831
public Container getPrimaryContainer() {
832
return (Container) metaContainer.getBeanInstance();
835
// return container delegate of container instance of meta container
836
public Container getPrimaryContainerDelegate() {
837
Container defCont = (Container) metaContainer.getBeanInstance();
838
if (primaryContainerDelegate == null || primaryContainer != defCont) {
839
primaryContainer = defCont;
840
primaryContainerDelegate =
841
metaContainer.getContainerDelegate(defCont);
843
return primaryContainerDelegate;
846
// return component instance of meta component
847
public Component getPrimaryComponent(int index) {
848
return (Component) metaContainer.getSubComponent(index).getBeanInstance();
851
public void updatePrimaryContainer() {
852
Container cont = getPrimaryContainer();
853
Container contDel = getPrimaryContainerDelegate();
855
layoutDelegate.clearContainer(cont, contDel);
856
layoutDelegate.setLayoutToContainer(cont, contDel);
858
RADVisualComponent[] components = metaContainer.getSubComponents();
859
if (components.length > 0) {
860
Component[] comps = new Component[components.length];
861
for (int i=0; i < components.length; i++) {
862
comps[i] = (Component) components[i].getBeanInstance();
863
ensureFakePeerAttached(comps[i]);
866
layoutDelegate.addComponentsToContainer(cont, contDel, comps, 0);
870
public void containerLayoutChanged(PropertyChangeEvent ev)
871
throws PropertyVetoException
873
if (ev != null && ev.getPropertyName() != null) {
874
layoutDelegate.acceptContainerLayoutChange(getEventWithValues(ev));
876
FormModel formModel = metaContainer.getFormModel();
877
formModel.fireContainerLayoutChanged(metaContainer,
878
ev.getPropertyName(),
882
else propertySets = null;
884
LayoutNode node = metaContainer.getLayoutNodeReference();
886
// propagate the change to node
887
if (ev != null && ev.getPropertyName() != null)
888
node.fireLayoutPropertiesChange();
890
node.fireLayoutPropertySetsChange();
894
public void componentLayoutChanged(int index, PropertyChangeEvent ev)
895
throws PropertyVetoException
897
RADVisualComponent metacomp = metaContainer.getSubComponent(index);
899
if (ev != null && ev.getPropertyName() != null) {
900
layoutDelegate.acceptComponentLayoutChange(index,
901
getEventWithValues(ev));
903
FormModel formModel = metaContainer.getFormModel();
904
formModel.fireComponentLayoutChanged(metacomp,
905
ev.getPropertyName(),
909
if (metacomp.getNodeReference() != null) // propagate the change to node
910
metacomp.getNodeReference().firePropertyChangeHelper(
911
// null, null, null);
912
ev.getPropertyName(),
917
if (metacomp.getNodeReference() != null) // propagate the change to node
918
metacomp.getNodeReference().fireComponentPropertySetsChange();
919
metacomp.resetConstraintsProperties();
923
private static PropertyChangeEvent getEventWithValues(PropertyChangeEvent ev) {
924
Object oldVal = ev.getOldValue();
925
Object newVal = ev.getNewValue();
926
if (oldVal instanceof FormProperty.ValueWithEditor)
927
ev = new PropertyChangeEvent(
929
ev.getPropertyName(),
930
((FormProperty.ValueWithEditor)oldVal).getValue(),
931
((FormProperty.ValueWithEditor)newVal).getValue());
937
private LayoutListener getLayoutListener() {
938
if (layoutListener == null)
939
layoutListener = new LayoutListener();
940
return layoutListener;
943
private class LayoutListener implements VetoableChangeListener,
944
PropertyChangeListener
946
public void vetoableChange(PropertyChangeEvent ev)
947
throws PropertyVetoException
949
Object source = ev.getSource();
950
String eventName = ev.getPropertyName();
951
if (source instanceof FormProperty
952
&& (FormProperty.PROP_VALUE.equals(eventName)
953
|| FormProperty.PROP_VALUE_AND_EDITOR.equals(eventName)))
955
ev = new PropertyChangeEvent(layoutDelegate,
956
((FormProperty)source).getName(),
960
containerLayoutChanged(ev);
964
public void propertyChange(PropertyChangeEvent ev) {
965
Object source = ev.getSource();
966
if (source instanceof FormProperty
967
&& FormProperty.CURRENT_EDITOR.equals(ev.getPropertyName()))
969
ev = new PropertyChangeEvent(layoutDelegate,
972
containerLayoutChanged(ev);
974
catch (PropertyVetoException ex) {} // should not happen
979
private static void ensureFakePeerAttached(Component comp) {
980
// This method is called for components to be added to a container.
981
// It might happen that the component is still in another container
982
// (by error) and then when removed from this container before adding
983
// to the new one, the peer would be null-ed. Trying to prevent this by
984
// removing the component before attaching the fake peer. (For bug 115431.)
985
if (comp != null && comp.getParent() != null) {
986
comp.getParent().remove(comp);
988
FakePeerSupport.attachFakePeer(comp);
989
if (comp instanceof Container)
990
FakePeerSupport.attachFakePeerRecursively((Container)comp);