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 }