001 package org.springframework.richclient.form.builder;
002
003 import com.jgoodies.forms.factories.FormFactory;
004 import com.jgoodies.forms.layout.CellConstraints;
005 import com.jgoodies.forms.layout.FormLayout;
006 import com.jgoodies.forms.layout.RowSpec;
007 import org.springframework.binding.form.FormModel;
008 import org.springframework.binding.form.support.NestedPropertyChangeListener;
009 import org.springframework.richclient.form.binding.Binding;
010 import org.springframework.richclient.form.binding.BindingFactory;
011 import org.springframework.richclient.form.binding.swing.SwingBindingFactory;
012
013 import javax.swing.*;
014 import javax.swing.border.Border;
015 import java.beans.PropertyChangeEvent;
016 import java.beans.PropertyChangeListener;
017 import java.util.ArrayList;
018 import java.util.Collections;
019 import java.util.List;
020 import java.util.Map;
021
022 /**
023 * <p>
024 * Layout builder based on the <a href="http://www.jgoodies.com">JGoodies</a> Framework.
025 * </p>
026 * <p/>
027 * <p>
028 * Shortcuts have been provided to directly place a local and a component. For this, you provide the coordinates
029 * for the label (x, y), and the component will be places (x + 2, y). If width or height spanning is provided,
030 * this will be applied to the component.
031 * </p>
032 * <p/>
033 * <pre>
034 * FormBuilder builder = new FormBuilder(getBindingFactory(), myLayout);
035 * //... add everything ...
036 * JPanel myFirstPanel = builder.getPanel();
037 * // set new layout, new panel
038 * builder.setPanel(mySecondLayout);
039 * //... add everything ...
040 * JPanel mySecondPanel = builder.getPanel();
041 * </pre>
042 *
043 * @author jh
044 */
045 public class FormLayoutFormBuilder extends AbstractFormBuilder
046 {
047
048 public static final String ALIGN_LEFT_TOP = "left, top";
049 public static final String ALIGN_LEFT_CENTER = "left, center";
050 public static final String ALIGN_LEFT_BOTTOM = "left, bottom";
051 public static final String ALIGN_RIGHT_TOP = "right, top";
052 public static final String ALIGN_RIGHT_CENTER = "right, center";
053 public static final String ALIGN_RIGHT_BOTTOM = "right, bottom";
054
055 private FormLayout layout;
056 private JPanel panel;
057 private CellConstraints cc;
058 private String labelAttributes = ALIGN_LEFT_CENTER;
059 private String componentAttributes = null;
060
061 private int row;
062
063 private static final int DEFAULT_ROW_INCREMENT = 2;
064
065 /**
066 * Constructor.
067 *
068 * @param bindingFactory BindingFactory.
069 * @param layout JGoodies FormLayout
070 */
071 public FormLayoutFormBuilder(BindingFactory bindingFactory, FormLayout layout)
072 {
073 this(bindingFactory, layout, new JPanel());
074 }
075
076 /**
077 * Constructor.
078 *
079 * @param bindingFactory BindingFactory.
080 * @param layout JGoodies FormLayout
081 * @param panel JPanel on which the builder will place the components.
082 */
083 public FormLayoutFormBuilder(BindingFactory bindingFactory, FormLayout layout, JPanel panel)
084 {
085 super(bindingFactory);
086 setLayout(layout, panel);
087 }
088
089 /**
090 * Move to the next line, minding the line gap
091 *
092 * @return This FormBuilder
093 */
094 public FormLayoutFormBuilder nextRow()
095 {
096 return nextRow(FormFactory.DEFAULT_ROWSPEC);
097 }
098
099 public FormLayoutFormBuilder nextRow(String rowSpec)
100 {
101 return nextRow(RowSpec.decode(rowSpec));
102 }
103
104 public FormLayoutFormBuilder nextRow(RowSpec rowSpec)
105 {
106 row += DEFAULT_ROW_INCREMENT;
107 correctNumberOfRows(row, rowSpec);
108 return this;
109 }
110
111 private void correctNumberOfRows(int requiredNrOfRows)
112 {
113 correctNumberOfRows(requiredNrOfRows, FormFactory.DEFAULT_ROWSPEC);
114 }
115
116 private void correctNumberOfRows(int requiredNrOfRows, RowSpec rowSpec)
117 {
118 int rowCount = layout.getRowCount();
119 // if not initialized, set on first row
120 if (row == -1 && requiredNrOfRows == -1)
121 {
122 requiredNrOfRows = 1;
123 row = 1;
124 }
125
126 if (requiredNrOfRows > rowCount)
127 {
128 for (int i = rowCount; i < requiredNrOfRows; i = i + DEFAULT_ROW_INCREMENT)
129 {
130 if (i != 0)
131 layout.appendRow(FormFactory.LINE_GAP_ROWSPEC);
132 layout.appendRow(rowSpec);
133 }
134 }
135 }
136
137 /**
138 * Returns the current row. If the layout is initialized, the row is set to -1. Calling getRow() will
139 * result in setting the row to 1 to allow direct usage of getRow().
140 *
141 * @return the current row
142 */
143 public int getRow()
144 {
145 if (row == -1) // init row
146 row = 1;
147
148 return row;
149 }
150
151 /**
152 * Sets the current row
153 *
154 * @param row The current row
155 */
156 public void setRow(int row)
157 {
158 this.row = row;
159 correctNumberOfRows(row);
160 }
161
162 /**
163 * Create a new panel with the provided layout en default DIALOG_BORDER.
164 *
165 * @param layout JGoodies FormLayout
166 */
167 public void setLayout(FormLayout layout)
168 {
169 setLayout(layout, new JPanel());
170 }
171
172 /**
173 * Set a panel with the provided layout layout.
174 *
175 * @param layout JGoodies FormLayout
176 * @param panel JPanel on which the builder will place the components.
177 */
178 public void setLayout(FormLayout layout, JPanel panel)
179 {
180 this.panel = panel;
181 this.layout = layout;
182 panel.setLayout(layout);
183 cc = new CellConstraints();
184 row = -1;
185 }
186
187 /**
188 * Set the border for the panel.
189 *
190 * @param border The border for the panel
191 */
192 public void setBorder(Border border)
193 {
194 this.panel.setBorder(border);
195 }
196
197 /**
198 * Add a binder to column 1 and the current row. Equals to builder.addBinding(component, 1,
199 * builder.getRow()).
200 *
201 * @param binding The binding to add
202 * @see #addBinding(Binding, int, int)
203 */
204 public JComponent addBinding(Binding binding)
205 {
206 return addBinding(binding, 1, row);
207 }
208
209 /**
210 * Add a binder to a column and the current row. Equals to builder.addBinding(component, column,
211 * builder.getRow()).
212 *
213 * @param binding The binding to add
214 * @param column The column on which the binding must be added
215 * @return The component produced by the binding
216 * @see #addBinding(Binding, int, int)
217 */
218 public JComponent addBinding(Binding binding, int column)
219 {
220 return addBinding(binding, column, row);
221 }
222
223 /**
224 * Add a binder to a column and a row. Equals to builder.addBinding(component, column,
225 * row).
226 *
227 * @param binding The binding to add
228 * @param column The column on which the binding must be added
229 * @param column The row on which the binding must be added
230 * @return The component produced by the binding
231 * @see #addBinding(Binding, int, int, int, int)
232 */
233 public JComponent addBinding(Binding binding, int column, int row)
234 {
235 return this.addBinding(binding, column, row, 1, 1);
236 }
237
238 /**
239 * Add a binder to a column and a row with width and height spanning.
240 */
241 public JComponent addBinding(Binding binding, int column, int row, int widthSpan, int heightSpan)
242 {
243 ((SwingBindingFactory) getBindingFactory()).interceptBinding(binding);
244 JComponent component = binding.getControl();
245 addComponent(component, column, row, widthSpan, heightSpan);
246 return component;
247 }
248
249 /**
250 * Add a property to column 1 and the current row. Equals to builder.addBinding(component, 1,
251 * builder.getRow()).
252 *
253 * @see #addProperty(String, int, int)
254 */
255 public JComponent addProperty(String property)
256 {
257 return addProperty(property, 1, row);
258 }
259
260 /**
261 * Add a property to a column and the current row. Equals to builder.addBinding(component, column,
262 * builder.getRow()).
263 *
264 * @see #addProperty(String, int, int)
265 */
266 public JComponent addProperty(String property, int column)
267 {
268 return addProperty(property, column, row);
269 }
270
271 public JComponent addProperty(String property, String binderId)
272 {
273 return addProperty(property, binderId, 1, row);
274 }
275
276 public JComponent addProperty(String property, String binderId, Map<?, ?> contextMap)
277 {
278 return addProperty(property, binderId, contextMap, 1, row);
279 }
280
281 public JComponent addProperty(String property, String binderId, int column)
282 {
283 return addProperty(property, binderId, column, row);
284 }
285
286 public JComponent addProperty(String property, String binderId, Map<?, ?> contextMap, int column)
287 {
288 return addProperty(property, binderId, contextMap, column, row);
289 }
290
291 public JComponent addProperty(String property, int column, int row)
292 {
293 return this.addProperty(property, column, row, 1, 1);
294 }
295
296 public JComponent addProperty(String property, String binderId, int column, int row)
297 {
298 return this.addProperty(property, binderId, column, row, 1, 1);
299 }
300
301 public JComponent addProperty(String property, String binderId, Map<?, ?> contextMap, int column, int row)
302 {
303 return this.addProperty(property, binderId, contextMap, column, row, 1, 1);
304 }
305
306 public JComponent addProperty(String property, int column, int row, int widthSpan, int heightSpan)
307 {
308 JComponent propertyComponent = createDefaultBinding(property).getControl();
309 addComponent(propertyComponent, column, row, widthSpan, heightSpan);
310 return propertyComponent;
311 }
312
313 public JComponent addProperty(String property, String binderId, int column, int row, int widthSpan,
314 int heightSpan)
315 {
316 return addProperty(property, binderId, Collections.EMPTY_MAP, column, row, widthSpan, heightSpan);
317 }
318
319 public JComponent addProperty(String property, String binderId, Map<?, ?> contextMap, int column, int row, int widthSpan,
320 int heightSpan)
321 {
322 JComponent propertyComponent = ((SwingBindingFactory) getBindingFactory()).createBinding(property,
323 binderId, contextMap).getControl();
324 addComponent(propertyComponent, column, row, widthSpan, heightSpan);
325 return propertyComponent;
326 }
327
328 public JLabel addLabel(String property)
329 {
330 return addLabel(property, 1, row);
331 }
332
333 public JLabel addLabel(String property, int column)
334 {
335 return addLabel(property, column, row);
336 }
337
338 public JLabel addLabel(String property, int column, int row)
339 {
340 return addLabel(property, null, column, row);
341 }
342
343 public JLabel addLabel(String property, int column, int row, String attributes)
344 {
345 return addLabel(property, null, column, row, 1, 1, attributes);
346 }
347
348 public JLabel addLabel(String property, JComponent forComponent, int column, int row)
349 {
350 return addLabel(property, forComponent, column, row, 1, 1, this.labelAttributes);
351 }
352
353 public JLabel addLabel(String property, JComponent forComponent, int column, int row, int widthSpan,
354 int heightSpan, String attributes)
355 {
356 JLabel labelComponent = createLabelFor(property, forComponent);
357 this.row = row;
358 if (this.row == -1)
359 {
360 this.row = 1;
361 }
362 correctNumberOfRows(this.row);
363 this.panel.add(labelComponent, cc.xywh(column, this.row, widthSpan, heightSpan, attributes));
364 return labelComponent;
365 }
366
367 public void addComponent(JComponent component)
368 {
369 addComponent(component, 1, row, 1, 1);
370 }
371
372 public void addComponent(JComponent component, int column)
373 {
374 addComponent(component, column, row, 1, 1);
375 }
376
377 public void addComponent(JComponent component, int column, int row)
378 {
379 addComponent(component, column, row, 1, 1);
380 }
381
382 public void addComponent(JComponent component, int column, int row, int widthSpan, int heightSpan)
383 {
384 addComponent(component, column, row, widthSpan, heightSpan, this.componentAttributes);
385 }
386
387 public void addComponent(JComponent component, int column, int row, int widthSpan, int heightSpan,
388 String attributes)
389 {
390 this.row = row;
391 if (this.row == -1)
392 {
393 this.row = 1;
394 }
395 correctNumberOfRows(this.row);
396 if (attributes == null)
397 this.panel.add(component, cc.xywh(column, this.row, widthSpan, heightSpan));
398 else
399 this.panel.add(component, cc.xywh(column, this.row, widthSpan, heightSpan, attributes));
400 }
401
402 public JComponent[] addPropertyAndLabel(String property)
403 {
404 return addPropertyAndLabel(property, 1, row, this.labelAttributes);
405 }
406
407 public JComponent[] addPropertyAndLabel(String property, int column)
408 {
409 return addPropertyAndLabel(property, column, row, this.labelAttributes);
410 }
411
412 public JComponent[] addPropertyAndLabel(String property, String binderId)
413 {
414 return addPropertyAndLabel(property, binderId, 1, row, this.labelAttributes);
415 }
416
417 public JComponent[] addPropertyAndLabel(String property, int column, String binderId)
418 {
419 return addPropertyAndLabel(property, binderId, column, row, this.labelAttributes);
420 }
421
422 public JComponent[] addPropertyAndLabel(String property, int column, int row)
423 {
424 return addPropertyAndLabel(property, column, row, this.labelAttributes);
425 }
426
427 public JComponent[] addPropertyAndLabel(String property, String binderId, int column, int row)
428 {
429 return addPropertyAndLabel(property, binderId, column, row, this.labelAttributes);
430 }
431
432 public JComponent[] addPropertyAndLabel(String property, int column, int row, String attributes)
433 {
434 return addPropertyAndLabel(property, column, row, 1, attributes);
435 }
436
437 public JComponent[] addPropertyAndLabel(String property, String binderId, int column, int row,
438 String attributes)
439 {
440 return addPropertyAndLabel(property, binderId, column, row, 1, attributes);
441 }
442
443 public JComponent[] addPropertyAndLabel(String property, int column, int row, int widthSpan)
444 {
445 return addPropertyAndLabel(property, column, row, widthSpan, this.labelAttributes);
446 }
447
448 public JComponent[] addPropertyAndLabel(String property, int column, int row, int widthSpan,
449 String attributes)
450 {
451 return addPropertyAndLabel(property, column, row, widthSpan, 1, attributes);
452 }
453
454 public JComponent[] addPropertyAndLabel(String property, String binderId, int column, int row,
455 int widthSpan, String attributes)
456 {
457 return addPropertyAndLabel(property, binderId, column, row, widthSpan, 1, attributes);
458 }
459
460 public JComponent[] addPropertyAndLabel(String property, int column, int row, int widthSpan,
461 int heightSpan)
462 {
463 return addPropertyAndLabel(property, column, row, widthSpan, heightSpan, this.labelAttributes);
464 }
465
466 public JComponent[] addPropertyAndLabel(String property, String binderId, int column, int row,
467 int widthSpan, int heightSpan)
468 {
469 return addPropertyAndLabel(property, binderId, column, row, widthSpan, heightSpan,
470 this.labelAttributes);
471 }
472
473 public JComponent[] addPropertyAndLabel(String property, int column, int row, int widthSpan,
474 int heightSpan, String attributes)
475 {
476 JComponent component = addProperty(property, column + 2, row, widthSpan, heightSpan);
477 JLabel label = addLabel(property, component, column, row, 1, 1, attributes);
478 return new JComponent[]{label, component};
479 }
480
481 public JComponent[] addPropertyAndLabel(String property, String binderId, int column, int row,
482 int widthSpan, int heightSpan, String attributes)
483 {
484 JComponent component = addProperty(property, binderId, column + 2, row, widthSpan, heightSpan);
485 JLabel label = addLabel(property, component, column, row, 1, 1, attributes);
486 return new JComponent[]{label, component};
487 }
488
489 public JPanel getPanel()
490 {
491 getBindingFactory().getFormModel().revert();
492 return this.panel;
493 }
494
495 public void setLabelAttributes(String attributes)
496 {
497 this.labelAttributes = attributes;
498 }
499
500 public void setComponentAttributes(String attributes)
501 {
502 this.componentAttributes = attributes;
503 }
504
505 public JComponent[] addTextArea(String propertyName, int column, int row)
506 {
507 return addTextArea(propertyName, column, row, 1, 1);
508 }
509
510 public JComponent[] addTextArea(String propertyName, int column)
511 {
512 return addTextArea(propertyName, column, row, 1, 1);
513 }
514
515 public JComponent[] addTextArea(String propertyName)
516 {
517 return addTextArea(propertyName, 1, row, 1, 1);
518 }
519
520 public JComponent[] addTextArea(String propertyName, int column, int row, int widthSpan, int heightSpan)
521 {
522 return addTextArea(propertyName, column, row, widthSpan, heightSpan,
523 ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
524 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
525 }
526
527 public JComponent[] addTextArea(String propertyName, int column, int row, int widthSpan, int heightSpan,
528 int vsbPolicy, int hsbPolicy)
529 {
530 JComponent textArea = createTextArea(propertyName);
531 createBinding(propertyName, textArea);
532 JScrollPane scrollPane = new JScrollPane(textArea, vsbPolicy, hsbPolicy);
533 addComponent(scrollPane, column, row, widthSpan, heightSpan);
534 return new JComponent[]{textArea, scrollPane};
535 }
536
537 public JComponent[] addTextAreaAndLabel(String propertyName, int column, int row)
538 {
539 return addTextAreaAndLabel(propertyName, column, row, 1, 1, this.labelAttributes);
540 }
541
542 public JComponent[] addTextAreaAndLabel(String propertyName, int column, int row, String attributes)
543 {
544 return addTextAreaAndLabel(propertyName, column, row, 1, 1, attributes);
545 }
546
547 public JComponent[] addTextAreaAndLabel(String propertyName, int column, int row, int widthSpan,
548 int heightSpan)
549 {
550 return addTextAreaAndLabel(propertyName, column, row, widthSpan, heightSpan, this.labelAttributes);
551 }
552
553 public JComponent[] addTextAreaAndLabel(String propertyName, int column, int row, int widthSpan,
554 int heightSpan, String attributes)
555 {
556 JLabel label = addLabel(propertyName, column, row, attributes);
557 JComponent[] components = addTextArea(propertyName, column + 2, row, widthSpan, heightSpan);
558 return new JComponent[]{label, components[0], components[1]};
559 }
560
561 public JComponent addPasswordField(String propertyName, int column)
562 {
563 return addPasswordField(propertyName, column, row, 1, 1);
564 }
565
566 public JComponent addPasswordField(String propertyName)
567 {
568 return addPasswordField(propertyName, 1, row);
569 }
570
571 public JComponent addPasswordField(String propertyName, int column, int row)
572 {
573 return addPasswordField(propertyName, column, row, 1, 1);
574 }
575
576 public JComponent addPasswordField(String propertyName, int column, int row, int widthSpan, int heightSpan)
577 {
578 JComponent passwordField = createBinding(propertyName, createPasswordField(propertyName))
579 .getControl();
580 addComponent(passwordField, column, row, widthSpan, heightSpan);
581 return passwordField;
582 }
583
584 public JComponent[] addPasswordFieldAndLabel(String propertyName, int column)
585 {
586 return addPasswordFieldAndLabel(propertyName, column, row, 1, 1);
587 }
588
589 public JComponent[] addPasswordFieldAndLabel(String propertyName)
590 {
591 return addPasswordFieldAndLabel(propertyName, 1, row);
592 }
593
594 public JComponent[] addPasswordFieldAndLabel(String propertyName, int column, int row)
595 {
596 return addPasswordFieldAndLabel(propertyName, column, row, 1, 1, this.labelAttributes);
597 }
598
599 public JComponent[] addPasswordFieldAndLabel(String propertyName, int column, int row, String attributes)
600 {
601 return addPasswordFieldAndLabel(propertyName, column, row, 1, 1, attributes);
602 }
603
604 public JComponent[] addPasswordFieldAndLabel(String propertyName, int column, int row, int widthSpan,
605 int heightSpan)
606 {
607 return addPasswordFieldAndLabel(propertyName, column, row, widthSpan, heightSpan,
608 this.labelAttributes);
609 }
610
611 public JComponent[] addPasswordFieldAndLabel(String propertyName, int column, int row, int widthSpan,
612 int heightSpan, String attributes)
613 {
614 JLabel label = addLabel(propertyName, column, row, attributes);
615 JComponent component = addPasswordField(propertyName, column + 2, row, widthSpan, heightSpan);
616 return new JComponent[]{label, component};
617 }
618
619 public void addHorizontalSeparator(int column, int row, int widthSpan)
620 {
621 addComponent(new JSeparator(), column, row, widthSpan, 1);
622 }
623
624 public void addHorizontalSeparator()
625 {
626 addComponent(new JSeparator(), 1, row, 1, 1);
627 }
628
629 public void addHorizontalSeparator(int widthSpan)
630 {
631 addComponent(new JSeparator(), 1, row, widthSpan, 1);
632 }
633
634 public void addHorizontalSeparator(int column, int widthSpan)
635 {
636 addComponent(new JSeparator(), column, row, widthSpan, 1);
637 }
638
639 public void addHorizontalSeparator(String text)
640 {
641 addComponent(getComponentFactory().createLabeledSeparator(text), 1, row, 1, 1);
642 }
643
644 public void addHorizontalSeparator(String text, int widthSpan)
645 {
646 addComponent(getComponentFactory().createLabeledSeparator(text), 1, row, widthSpan, 1);
647 }
648
649 public void addHorizontalSeparator(String text, int column, int widthSpan)
650 {
651 addComponent(getComponentFactory().createLabeledSeparator(text), column, row, widthSpan, 1);
652 }
653
654 public void addVerticalSeparator(int column, int row, int heightSpan)
655 {
656 addComponent(new JSeparator(SwingConstants.VERTICAL), column, row, 1, heightSpan);
657 }
658
659 public void addVerticalSeparator()
660 {
661 addComponent(new JSeparator(SwingConstants.VERTICAL), 1, row, 1, 1);
662 }
663
664 public void addVerticalSeparator(int heightSpan)
665 {
666 addComponent(new JSeparator(SwingConstants.VERTICAL), 1, row, 1, heightSpan);
667 }
668
669 public void addVerticalSeparator(int column, int heightSpan)
670 {
671 addComponent(new JSeparator(SwingConstants.VERTICAL), column, row, 1, heightSpan);
672 }
673
674 public JComponent addNestedPropertyReadOnly(String property, String nestedProperty)
675 {
676 return addNestedPropertyReadOnly(property, nestedProperty, 1, row);
677 }
678
679 public JComponent addNestedPropertyReadOnly(String property, String nestedProperty, int column)
680 {
681 return addNestedPropertyReadOnly(property, nestedProperty, column, row);
682 }
683
684 public JComponent addNestedPropertyReadOnly(String property, String nestedProperty, int column, int row)
685 {
686 return addNestedPropertyReadOnly(property, nestedProperty, column, row, 1, 1);
687 }
688
689 public JComponent addNestedPropertyReadOnly(String property, String nestedProperty, int column, int row,
690 int widthSpan, int heightSpan)
691 {
692 final JTextField nestedPropertyField = new JTextField();
693 nestedPropertyField.setEditable(false);
694 getFormModel().getValueModel(property).addValueChangeListener(
695 new NestedPropertyChangeListener(nestedPropertyField, nestedProperty));
696 getFormModelEnabledListener().add(nestedPropertyField);
697 addComponent(nestedPropertyField, column, row, widthSpan, heightSpan);
698 return nestedPropertyField;
699 }
700
701 public JComponent[] addNestedPropertyReadOnlyAndLabel(String property, String nestedProperty)
702 {
703 return addNestedPropertyReadOnlyAndLabel(property, nestedProperty, 1, row);
704 }
705
706 public JComponent[] addNestedPropertyReadOnlyAndLabel(String property, String nestedProperty, int column)
707 {
708 return addNestedPropertyReadOnlyAndLabel(property, nestedProperty, column, row);
709 }
710
711 public JComponent[] addNestedPropertyReadOnlyAndLabel(String property, String nestedProperty, int column, int row)
712 {
713 return addNestedPropertyReadOnlyAndLabel(property, nestedProperty, column, row, 1, 1);
714 }
715
716 public JComponent[] addNestedPropertyReadOnlyAndLabel(String property, String nestedProperty, int column, int row,
717 int widthSpan, int heightSpan)
718 {
719 final JTextField nestedPropertyField = new JTextField();
720 nestedPropertyField.setEditable(false);
721 getFormModel().getValueModel(property).addValueChangeListener(
722 new NestedPropertyChangeListener(nestedPropertyField, nestedProperty));
723 getFormModelEnabledListener().add(nestedPropertyField);
724 JComponent comp = addNestedPropertyReadOnly(property, nestedProperty, column + 2, row, widthSpan, heightSpan);
725 JLabel label = addLabel(property + "." + nestedProperty, comp, column, row, 1, 1, this.labelAttributes);
726 return new JComponent[] { label, comp };
727 }
728
729 private FormModelEnabledListener formModelEnabledListener;
730
731 public FormModelEnabledListener getFormModelEnabledListener()
732 {
733 if (formModelEnabledListener == null)
734 {
735 formModelEnabledListener = new FormModelEnabledListener();
736 getFormModel().addPropertyChangeListener(FormModel.ENABLED_PROPERTY, formModelEnabledListener);
737 }
738 return formModelEnabledListener;
739 }
740
741 public static class FormModelEnabledListener implements PropertyChangeListener
742 {
743
744 private List<JComponent> components = new ArrayList<JComponent>();
745
746 public void propertyChange(PropertyChangeEvent evt)
747 {
748 for (JComponent component : components)
749 {
750 component.setEnabled((Boolean) evt.getNewValue());
751 }
752 }
753
754 public void add(JComponent component)
755 {
756 components.add(component);
757 }
758
759 }
760 }