1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.mlc.swing.layout;
31
32 import java.awt.BorderLayout;
33 import java.awt.Color;
34 import java.awt.Component;
35 import java.awt.Container;
36 import java.awt.Font;
37 import java.awt.Frame;
38 import java.awt.Insets;
39 import java.awt.Point;
40 import java.awt.Rectangle;
41 import java.awt.event.*;
42 import java.util.*;
43
44 import javax.swing.*;
45 import javax.swing.border.*;
46 import javax.swing.event.*;
47 import javax.swing.table.DefaultTableCellRenderer;
48
49 import com.jgoodies.forms.factories.Borders;
50 import com.jgoodies.forms.factories.DefaultComponentFactory;
51 import com.jgoodies.forms.layout.CellConstraints;
52
53 /***
54 * This is the main panel that is used in LayoutFrame serving as the user
55 * interface for the builder. This is a pretty juicy file because there is a lot
56 * going on here. Better docs to come...
57 *
58 * @author Michael Connor mlconnor@yahoo.com
59 */
60 @SuppressWarnings("serial")
61 public class FormEditor extends JPanel
62 {
63 String[] verticalAlignmentList = { LayoutConstraintsManager.DEFAULT,
64 LayoutConstraintsManager.FILL, LayoutConstraintsManager.CENTER,
65 LayoutConstraintsManager.TOP, LayoutConstraintsManager.BOTTOM };
66
67 String[] horizontalAlignmentList = { LayoutConstraintsManager.DEFAULT,
68 LayoutConstraintsManager.FILL, LayoutConstraintsManager.CENTER,
69 LayoutConstraintsManager.LEFT, LayoutConstraintsManager.RIGHT };
70
71 ColSpanSpinnerModel colSpinnerModel = new ColSpanSpinnerModel();
72
73 RowSpanSpinnerModel rowSpinnerModel = new RowSpanSpinnerModel();
74
75 Action newComponentAction = new NewComponentAction();
76
77 Action removeComponentAction = new RemoveComponentAction();
78
79 Action insertRowBeforeAction = new InsertRowBeforeAction();
80
81 Action insertRowAfterAction = new InsertRowAfterAction();
82
83 Action deleteRowAction = new DeleteRowAction();
84
85 Action insertColumnBeforeAction = new InsertColumnBeforeAction();
86
87 Action insertColumnAfterAction = new InsertColumnAfterAction();
88
89 Action deleteColumnAction = new DeleteColumnAction();
90
91 JComboBox verticalAlignmentCombo = new JComboBox(verticalAlignmentList);
92
93 JComboBox horizontalAlignmentCombo = new JComboBox(horizontalAlignmentList);
94
95 JSpinner rowSpanSpinner = new JSpinner(rowSpinnerModel);
96
97 JSpinner columnSpanSpinner = new JSpinner(colSpinnerModel);
98
99 JLabel columnSpanLabel = new JLabel("Column Span");
100
101 JLabel horizontalAlignmentLabel = new JLabel("Horizontal Alignment");
102
103 JLabel rowSpanLabel = new JLabel("Row Span");
104
105 JLabel verticalAlignmentLabel = new JLabel("Vertical Alignment");
106
107 JPanel contentPanel = new JPanel();
108
109 JPanel insetsPanel = new JPanel();
110
111 SpinnerNumberModel rightInsetSpinnerModel = new SpinnerNumberModel(0, 0,
112 Integer.MAX_VALUE, 1);
113
114 SpinnerNumberModel topInsetSpinnerModel = new SpinnerNumberModel(0, 0,
115 Integer.MAX_VALUE, 1);
116
117 SpinnerNumberModel bottomInsetSpinnerModel = new SpinnerNumberModel(0, 0,
118 Integer.MAX_VALUE, 1);
119
120 SpinnerNumberModel leftInsetSpinnerModel = new SpinnerNumberModel(0, 0,
121 Integer.MAX_VALUE, 1);
122
123 JSpinner rightInsetSpinner = new JSpinner(rightInsetSpinnerModel);
124
125 JSpinner bottomInsetSpinner = new JSpinner(bottomInsetSpinnerModel);
126
127 JSpinner leftInsetSpinner = new JSpinner(leftInsetSpinnerModel);
128
129 JSpinner topInsetSpinner = new JSpinner(topInsetSpinnerModel);
130
131 GridTableModel tableModel = new GridTableModel();
132
133 JLabel insetsLabel = new JLabel("Insets");
134
135 JLabel componentsLabel = new JLabel("Components (Drag n Drop)");
136
137 JLabel componentPaletteLabel = new JLabel("Palette (Drag n Drop)");
138
139 ComponentPaletteListModel componentPaletteListModel = new ComponentPaletteListModel();
140
141
142 DndList componentPalette = new DndList(this, componentPaletteListModel);
143
144 JScrollPane componentPaletteScrollPane = new JScrollPane(componentPalette);
145
146 ComponentSelectionListModel componentSelectionListModel = new ComponentSelectionListModel();
147
148 DndList componentList = new DndList(this, componentSelectionListModel);
149
150 JScrollPane componentListScrollPane = new JScrollPane(componentList);
151
152 ComponentListCellRenderer componentListCellRenderer = new ComponentListCellRenderer();
153
154 Component constraintsSeparator = DefaultComponentFactory.getInstance()
155 .createSeparator("Component Constraints");
156
157 Component positionsSeparator = DefaultComponentFactory.getInstance()
158 .createSeparator("Component Positions (Drag n Drop)");
159
160 JPanel componentsPanel = new JPanel();
161
162 JPanel propertiesPanel = new JPanel();
163
164 JSplitPane componentsSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
165 componentsPanel, propertiesPanel);
166
167 JTextField colSpecField = new JTextField();
168
169 JTextField rowSpecField = new JTextField();
170
171 Set<Component> newComponents = new HashSet<Component>();
172
173 LayoutConstraintsManager layoutConstraintsManager;
174
175 JToolBar toolbar = new JToolBar();
176
177 JButton newComponentButton = new JButton(newComponentAction);
178
179 JButton removeComponentButton = new JButton(removeComponentAction);
180
181 JButton columnDeleteButton = new JButton(deleteColumnAction);
182
183 JButton columnInsertAfterButton = new JButton(insertColumnAfterAction);
184
185 JButton columnInsertBeforeButton = new JButton(insertColumnBeforeAction);
186
187 JButton rowDeleteButton = new JButton(deleteRowAction);
188
189 JButton rowInsertBeforeButton = new JButton(insertRowBeforeAction);
190
191 JButton rowInsertAfterButton = new JButton(insertRowAfterAction);
192
193 Container container;
194
195 ContainerLayout containerLayout;
196
197 LayoutFrame layoutFrame;
198 DnDTable table = null;
199 JScrollPane tableScrollPane = null;
200 JSplitPane constraintsSplitPane = null;
201
202 Component topComponent = null;
203
204 boolean suspendConstraintControlUpdates = false;
205
206 void setContainer(Container container)
207 {
208 java.awt.LayoutManager layoutManager = container.getLayout();
209 if (!(layoutManager instanceof ContainerLayout))
210 throw new RuntimeException(
211 "Container layout must be of type ContainerLayout");
212 this.container = container;
213 }
214
215 public FormEditor(LayoutFrame layoutFrame, ContainerLayout layout,
216 Container container)
217 {
218 super();
219
220 this.layoutFrame = layoutFrame;
221 table = new DnDTable(layoutFrame, this);
222 tableScrollPane = new JScrollPane(table);
223 constraintsSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
224 tableScrollPane, componentsSplitPane);
225
226 setContainer(container);
227 containerLayout = layout;
228
229 table.setBackground(java.awt.Color.white);
230 table.setSelectionBackground(new Color(220, 220, 255));
231 table.setSelectionForeground(Color.black);
232
233 table.setDefaultRenderer(Object.class, new ConstraintTableCellRenderer());
234 table.setRowHeight(20);
235 table.setModel(tableModel);
236 table.setCellSelectionEnabled(true);
237 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
238
239
240
241 if (tableModel.getRowCount() > 1 && tableModel.getColumnCount() > 1)
242 {
243
244 setSelectedCell(1, 1, false);
245 }
246
247 componentList.setCellRenderer(componentListCellRenderer);
248
249
250 componentsLabel.setLabelFor(componentListScrollPane);
251
252 verticalAlignmentLabel.setLabelFor(verticalAlignmentCombo);
253 verticalAlignmentLabel.setDisplayedMnemonic(KeyEvent.VK_V);
254 horizontalAlignmentLabel.setLabelFor(horizontalAlignmentCombo);
255 horizontalAlignmentLabel.setDisplayedMnemonic(KeyEvent.VK_H);
256 columnSpanLabel.setLabelFor(columnSpanSpinner);
257 columnSpanLabel.setDisplayedMnemonic(KeyEvent.VK_C);
258 rowSpanLabel.setLabelFor(rowSpanSpinner);
259 rowSpanLabel.setDisplayedMnemonic(KeyEvent.VK_R);
260
261 columnInsertAfterButton.setToolTipText("Insert a column after this column");
262 columnInsertBeforeButton
263 .setToolTipText("Insert a column before this column");
264 columnDeleteButton.setToolTipText("Delete this column");
265 rowInsertBeforeButton.setToolTipText("Insert a row before this row");
266 rowInsertAfterButton.setToolTipText("Insert a row after this row");
267
268
269 toolbar.add(newComponentButton);
270 toolbar.add(removeComponentButton);
271 toolbar.addSeparator();
272 toolbar.add(columnDeleteButton);
273 toolbar.add(columnInsertBeforeButton);
274 toolbar.add(columnInsertAfterButton);
275 toolbar.addSeparator();
276 toolbar.add(rowDeleteButton);
277 toolbar.add(rowInsertBeforeButton);
278 toolbar.add(rowInsertAfterButton);
279
280 setFormComponent(null);
281
282 layoutConstraintsManager = LayoutConstraintsManager
283 .getLayoutConstraintsManager(FormEditor.class.getResourceAsStream(
284 "editableLayoutConstraints.xml"));
285
286 layoutConstraintsManager.setLayout("mainLayout", contentPanel);
287 layoutConstraintsManager.setLayout("insetsLayout", insetsPanel);
288 layoutConstraintsManager.setLayout("componentsLayout", componentsPanel);
289 layoutConstraintsManager.setLayout("propertiesLayout", propertiesPanel);
290
291 insetsPanel.add(rightInsetSpinner, "rightInsetSpinner");
292 insetsPanel.add(leftInsetSpinner, "leftInsetSpinner");
293 insetsPanel.add(topInsetSpinner, "topInsetSpinner");
294 insetsPanel.add(bottomInsetSpinner, "bottomInsetSpinner");
295
296 componentsPanel.add(componentListScrollPane, "componentListScrollPane");
297 componentsPanel.add(componentsLabel, "componentsLabel");
298 propertiesPanel.add(componentPaletteScrollPane,
299 "componentPaletteScrollPane");
300 componentPalette.setCellRenderer(new ComponentPaletteListRenderer());
301 propertiesPanel.add(componentPaletteLabel, "componentPaletteLabel");
302
303 contentPanel.add(rowSpanLabel, "rowSpanLabel");
304 contentPanel.add(horizontalAlignmentCombo, "horizontalAlignmentCombo");
305 contentPanel.add(horizontalAlignmentLabel, "horizontalAlignmentLabel");
306 contentPanel.add(rowSpanSpinner, "rowSpanSpinner");
307 contentPanel.add(verticalAlignmentCombo, "verticalAlignmentCombo");
308 contentPanel.add(columnSpanLabel, "columnSpanLabel");
309 contentPanel.add(verticalAlignmentLabel, "verticalAlignmentLabel");
310 contentPanel.add(columnSpanSpinner, "columnSpanSpinner");
311 contentPanel.add(insetsPanel, "insetsPanel");
312 contentPanel.add(insetsLabel, "insetsLabel");
313 contentPanel.add(constraintsSeparator, "constraintsSeparator");
314 contentPanel.add(positionsSeparator, "positionsSeparator");
315 contentPanel.add(toolbar, "toolbar");
316 contentPanel.add(constraintsSplitPane, "constraintsSplitPane");
317
318 constraintsSplitPane.setDividerLocation(605);
319
320 contentPanel.setBorder(Borders.DIALOG_BORDER);
321
322 setLayout(new BorderLayout());
323 add(contentPanel, BorderLayout.CENTER);
324
325 setupListeners();
326 }
327
328 private void setupListeners()
329 {
330
331 verticalAlignmentCombo.addActionListener(new ActionListener()
332 {
333 public void actionPerformed(ActionEvent e)
334 {
335 Component component = table.getSelectedControl();
336 if (component != null)
337 {
338 CellConstraints cellConstraints = getComponentConstraints(component);
339 cellConstraints.vAlign = LayoutConstraintsManager
340 .getAlignment((String) verticalAlignmentCombo.getSelectedItem());
341 updateLayout(component);
342 }
343 }
344 });
345
346 horizontalAlignmentCombo.addActionListener(new ActionListener()
347 {
348 public void actionPerformed(ActionEvent e)
349 {
350 Component component = table.getSelectedControl();
351 if (component != null)
352 {
353 CellConstraints cellConstraints = getComponentConstraints(component);
354 cellConstraints.hAlign = LayoutConstraintsManager
355 .getAlignment((String) horizontalAlignmentCombo.getSelectedItem());
356 updateLayout(component);
357 }
358 }
359 });
360
361 topInsetSpinnerModel.addChangeListener(new ChangeListener()
362 {
363 public void stateChanged(ChangeEvent e)
364 {
365 if (!suspendConstraintControlUpdates)
366 {
367 Component component = table.getSelectedControl();
368 CellConstraints constraints = getComponentConstraints(component);
369 Insets insets = new Insets(topInsetSpinnerModel.getNumber()
370 .intValue(), constraints.insets.left, constraints.insets.bottom,
371 constraints.insets.right);
372 constraints.insets = insets;
373 updateLayout(component);
374 }
375 }
376 });
377
378 leftInsetSpinnerModel.addChangeListener(new ChangeListener()
379 {
380 public void stateChanged(ChangeEvent e)
381 {
382 if (!suspendConstraintControlUpdates)
383 {
384 Component component = table.getSelectedControl();
385 CellConstraints constraints = getComponentConstraints(component);
386 Insets insets = new Insets(constraints.insets.top,
387 leftInsetSpinnerModel.getNumber().intValue(),
388 constraints.insets.bottom, constraints.insets.right);
389 constraints.insets = insets;
390 updateLayout(component);
391 }
392 }
393 });
394
395 rightInsetSpinnerModel.addChangeListener(new ChangeListener()
396 {
397 public void stateChanged(ChangeEvent e)
398 {
399 if (!suspendConstraintControlUpdates)
400 {
401 Component component = table.getSelectedControl();
402 CellConstraints constraints = getComponentConstraints(component);
403 Insets insets = new Insets(constraints.insets.top,
404 constraints.insets.left, constraints.insets.bottom,
405 rightInsetSpinnerModel.getNumber().intValue());
406 constraints.insets = insets;
407 updateLayout(component);
408 }
409 }
410 });
411
412 bottomInsetSpinnerModel.addChangeListener(new ChangeListener()
413 {
414 public void stateChanged(ChangeEvent e)
415 {
416 if (!suspendConstraintControlUpdates)
417 {
418 Component component = table.getSelectedControl();
419 CellConstraints constraints = getComponentConstraints(component);
420 Insets insets = new Insets(constraints.insets.top,
421 constraints.insets.left, bottomInsetSpinnerModel.getNumber()
422 .intValue(), constraints.insets.right);
423 constraints.insets = insets;
424 updateLayout(component);
425 }
426 }
427 });
428
429 table.addMouseListener(new MouseAdapter()
430 {
431 public void mouseClicked(MouseEvent e)
432 {
433 if (e.getClickCount() == 2)
434 {
435 Point p = e.getPoint();
436 int row = table.rowAtPoint(p);
437 int col = table.columnAtPoint(p);
438
439 Component component = table.getSelectedControl();
440 if ( component == null)
441 return;
442
443
444 String name = getComponentName(component);
445 ComponentDef componentDef = containerLayout.getComponentDef(name);
446 if ( componentDef != null )
447 {
448 editComponent(componentDef, component, new CellConstraints(col, row));
449 }
450 }
451 }
452 });
453 componentList.addListSelectionListener(new ListSelectionListener()
454 {
455 public void valueChanged(ListSelectionEvent e)
456 {
457 if (!e.getValueIsAdjusting())
458 {
459
460
461 Component thisComponent = (Component) componentList.getSelectedValue();
462
463 CellConstraints constraints = getComponentConstraints(thisComponent);
464 if (constraints == null)
465 throw new RuntimeException(
466 "Unable to find constraints for component " + thisComponent
467 + " in layout " + containerLayout.getName());
468 int col = constraints.gridX;
469 int row = constraints.gridY;
470
471 table.changeSelection(row, col, false, false);
472 topComponent = thisComponent;
473 }
474 }
475 });
476
477 componentList.addMouseListener(new MouseAdapter()
478 {
479 public void mouseClicked(MouseEvent e)
480 {
481 if (e.getClickCount() == 2)
482 {
483 int index = componentList.locationToIndex(e.getPoint());
484 if ( index == -1 )
485 return;
486
487
488 ListModel lm = ((DndList)e.getSource()).getModel();
489 Component thisComponent = (Component)lm.getElementAt(index);
490
491 String name = getComponentName(thisComponent);
492 ComponentDef compDef = containerLayout.getComponentDef(name);
493 CellConstraints constraints = getComponentConstraints(thisComponent);
494 if (constraints == null)
495 throw new RuntimeException(
496 "Unable to find constraints for component " + thisComponent
497 + " in layout " + containerLayout.getName());
498 editComponent(compDef,thisComponent,constraints);
499 }
500 }
501 } );
502 }
503
504 String getComponentName(Component control)
505 {
506 return containerLayout.getComponentName(control);
507 }
508
509 CellConstraints getComponentConstraints(Component component)
510 {
511 return containerLayout.getComponentConstraints(component);
512 }
513
514 private void specsChanged()
515 {
516 updateLayouts();
517
518
519 Component[] children = container.getComponents();
520 for (int index = 0; index < children.length; index++)
521 {
522 Component component = children[index];
523 if (component instanceof Container)
524 ((Container) component).doLayout();
525 }
526 }
527
528 void updateLayouts()
529 {
530 container.validate();
531 container.doLayout();
532
533 Container parent = container;
534
535 while (parent != null)
536 {
537 parent.validate();
538 parent = parent.getParent();
539 }
540 }
541
542 private void setSelectedCell(int columnIndex, int rowIndex,
543 boolean forceVisible)
544 {
545
546 table.getSelectionModel().setSelectionInterval(rowIndex, rowIndex);
547 table.getColumnModel().getSelectionModel().setSelectionInterval(
548 columnIndex, columnIndex);
549
550 if (forceVisible)
551 {
552
553 JViewport viewport = (JViewport) table.getParent();
554 Rectangle rect = table.getCellRect(rowIndex, columnIndex, true);
555 Point pt = viewport.getViewPosition();
556 rect.setLocation(rect.x - pt.x, rect.y - pt.y);
557 viewport.scrollRectToVisible(rect);
558 }
559 }
560
561 @SuppressWarnings("serial")
562 private class ComponentSelectionListModel extends
563 javax.swing.AbstractListModel
564 {
565
566
567 List<Component> sortedComponents = new ArrayList<Component>();
568
569 public ComponentSelectionListModel()
570 {
571 super();
572 }
573
574
575
576
577
578
579
580
581 public Object getElementAt(int index)
582 {
583 Component component = sortedComponents.get(index);
584 return component;
585 }
586
587 public int getSize()
588 {
589 sortedComponents = new ArrayList<Component>();
590
591 if (container != null)
592 {
593 Component[] containerComponents = container.getComponents();
594 for (int index = 0; index < containerComponents.length; index++)
595 {
596 Component insertComponent = containerComponents[index];
597 String insertComponentName = getComponentName(insertComponent);
598
599 int insertIndex = 0;
600 while (insertIndex < sortedComponents.size()
601 && insertComponentName != null)
602 {
603 Component testComponent = sortedComponents.get(insertIndex);
604 String testName = getComponentName(testComponent);
605 if (testName != null)
606 testName = testName.toUpperCase();
607 if (insertComponentName.toUpperCase().compareTo(testName) <= 0)
608 break;
609 else
610 insertIndex++;
611 }
612 sortedComponents.add(insertIndex, insertComponent);
613 }
614 }
615
616 return container != null ? container.getComponentCount() : 0;
617 }
618
619 public void fireDelete()
620 {
621 super.fireContentsChanged(this, 0, Math.max(0,
622 container.getComponents().length - 1));
623 }
624
625 public void fireInsert()
626 {
627 super.fireContentsChanged(this, 0, Math.max(0,
628 container.getComponents().length - 1));
629 }
630 }
631
632 class ComponentListCellRenderer extends JLabel implements ListCellRenderer
633 {
634 private static final long serialVersionUID = 1L;
635 Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
636
637 public ComponentListCellRenderer()
638 {
639 super();
640 setOpaque(true);
641 }
642
643 public Component getListCellRendererComponent(JList list, Object value,
644 int index, boolean isSelected, boolean cellHasFocus)
645 {
646 Component component = (Component) value;
647 String name = getComponentName(component);
648
649 setComponentOrientation(list.getComponentOrientation());
650 if (isSelected)
651 {
652 setBackground(list.getSelectionBackground());
653 setForeground(list.getSelectionForeground());
654 }
655 else
656 {
657 setBackground(list.getBackground());
658 setForeground(list.getForeground());
659 }
660
661 setText(name != null ? name : "(Untitled)");
662
663 setEnabled(list.isEnabled());
664 Font font = list.getFont();
665 setFont(font.deriveFont(component.isVisible() ? Font.PLAIN : Font.BOLD));
666 setBorder((cellHasFocus) ? UIManager
667 .getBorder("List.focusCellHighlightBorder") : noFocusBorder);
668
669 return this;
670 }
671 }
672
673 private void insertColumn(int column)
674 {
675 for (int index = 0; index < container.getComponentCount(); index++)
676 {
677 Component component = container.getComponent(index);
678 CellConstraints constraints = getComponentConstraints(component);
679 if (constraints.gridX > column)
680 constraints.gridX++;
681 }
682
683 try
684 {
685 containerLayout.addColumnSpec(column, "pref");
686 tableModel.fireTableStructureChanged();
687 setSelectedCell(column + 1, 0, true);
688 specsChanged();
689 }
690 catch (IllegalArgumentException iae)
691 {
692 JOptionPane.showMessageDialog(FormEditor.this, iae.getMessage(),
693 "Invalid Layout", JOptionPane.ERROR_MESSAGE);
694 }
695 }
696
697 private void insertRow(int rowIndex)
698 {
699 for (int index = 0; index < container.getComponentCount(); index++)
700 {
701 Component component = container.getComponent(index);
702 CellConstraints constraints = getComponentConstraints(component);
703 if (constraints.gridY > rowIndex)
704 constraints.gridY++;
705 }
706
707 try
708 {
709 containerLayout.addRowSpec(rowIndex, "pref");
710 tableModel.fireTableStructureChanged();
711 setSelectedCell(0, rowIndex + 1, true);
712 specsChanged();
713 }
714 catch (IllegalArgumentException iae)
715 {
716 JOptionPane.showMessageDialog(FormEditor.this, iae.getMessage(),
717 "Invalid Layout", JOptionPane.ERROR_MESSAGE);
718 }
719 }
720
721 Component formComponent = null;
722
723
724
725 public void setFormComponent(Component component)
726 {
727
728
729
730
731 formComponent = component;
732
733 CellConstraints constraints = formComponent != null ?
734 getComponentConstraints(formComponent) : null;
735
736 suspendConstraintControlUpdates = true;
737
738 if (formComponent != null)
739 {
740 rowSpinnerModel.setComponent(formComponent);
741 colSpinnerModel.setComponent(formComponent);
742 verticalAlignmentCombo.setSelectedItem(LayoutConstraintsManager
743 .getAlignment(constraints.vAlign));
744 horizontalAlignmentCombo.setSelectedItem(LayoutConstraintsManager
745 .getAlignment(constraints.hAlign));
746 topInsetSpinnerModel.setValue(new Integer(constraints.insets.top));
747 bottomInsetSpinnerModel.setValue(new Integer(constraints.insets.bottom));
748 rightInsetSpinnerModel.setValue(new Integer(constraints.insets.right));
749 leftInsetSpinnerModel.setValue(new Integer(constraints.insets.left));
750 }
751
752 verticalAlignmentCombo.setEnabled(constraints != null);
753 horizontalAlignmentCombo.setEnabled(constraints != null);
754 rightInsetSpinner.setEnabled(constraints != null);
755 leftInsetSpinner.setEnabled(constraints != null);
756 topInsetSpinner.setEnabled(constraints != null);
757 bottomInsetSpinner.setEnabled(constraints != null);
758 rowSpanSpinner.setEnabled(constraints != null);
759 columnSpanSpinner.setEnabled(constraints != null);
760
761 int col = table.getSelectedColumn();
762 int row = table.getSelectedRow();
763
764
765 newComponentAction.setEnabled(col > 0 && row > 0 && formComponent == null);
766 removeComponentAction.setEnabled(constraints != null);
767 columnDeleteButton.setEnabled(row == 0 && col > 0 && containerLayout.getColumnCount() > 1);
768 columnInsertAfterButton.setEnabled(col > -1);
769 columnInsertBeforeButton.setEnabled(col > 0);
770 rowDeleteButton.setEnabled(col == 0 && row > 0 && containerLayout.getRowCount() > 1);
771 rowInsertBeforeButton.setEnabled(row > 0);
772 rowInsertAfterButton.setEnabled(row > -1);
773
774 suspendConstraintControlUpdates = false;
775 }
776
777 public void updateLayout(Component component)
778 {
779 if (suspendConstraintControlUpdates)
780 return;
781
782 CellConstraints constraints = getComponentConstraints(component);
783
784
785
786
787 String name = getComponentName(component);
788
789 containerLayout.setCellConstraints(name, constraints);
790
791
792
793
794 container.invalidate();
795 container.doLayout();
796
797
798
799 container.validate();
800 container.repaint();
801
802 if (component instanceof Container)
803 {
804 Container cContainer = (Container) component;
805 cContainer.invalidate();
806 cContainer.doLayout();
807 }
808 }
809
810 private class ColSpanSpinnerModel extends AbstractSpinnerModel
811 {
812 CellConstraints constraints;
813
814 Component component;
815
816 public ColSpanSpinnerModel()
817 {
818 }
819
820 public void setComponent(Component component)
821 {
822 this.component = component;
823 if (component != null)
824 {
825 constraints = getComponentConstraints(component);
826 fireStateChanged();
827 }
828 else
829 {
830 constraints = null;
831 }
832 }
833
834 public Object getNextValue()
835 {
836 if (constraints == null)
837 return null;
838 Integer next = constraints.gridX + constraints.gridWidth - 1 < containerLayout
839 .getColumnCount() ? new Integer(constraints.gridWidth + 1) : null;
840 return next;
841 }
842
843 public Object getPreviousValue()
844 {
845 if (constraints == null)
846 return null;
847 else
848 {
849 Integer previous = constraints.gridWidth > 1 ? new Integer(
850 constraints.gridWidth - 1) : null;
851 return previous;
852 }
853 }
854
855 public Object getValue()
856 {
857 if (constraints == null)
858 return "";
859 else
860 return new Integer(constraints.gridWidth);
861 }
862
863 public void setValue(Object value)
864 {
865 if (constraints == null || value == null)
866 return;
867
868
869 constraints.gridWidth = ((Number) value).intValue();
870 super.fireStateChanged();
871 updateLayout(component);
872
873
874
875 int col = table.getSelectedColumn();
876 int row = table.getSelectedRow();
877 tableModel.fireTableDataChanged();
878 setSelectedCell(col, row, true);
879 }
880 }
881
882 private class RowSpanSpinnerModel extends AbstractSpinnerModel
883 {
884 CellConstraints constraints;
885
886 Component component;
887
888 public RowSpanSpinnerModel()
889 {
890 }
891
892 public void setComponent(Component component)
893 {
894 this.component = component;
895 if (component != null)
896 {
897 constraints = getComponentConstraints(component);
898 fireStateChanged();
899 }
900 else
901 {
902 constraints = null;
903 }
904 }
905
906 public Object getNextValue()
907 {
908 if (constraints == null)
909 return null;
910 else
911 {
912 Integer next = constraints.gridY + constraints.gridHeight - 1 < containerLayout
913 .getRowCount() ? new Integer(constraints.gridHeight + 1) : null;
914 return next;
915 }
916 }
917
918 public Object getPreviousValue()
919 {
920 if (constraints == null)
921 return null;
922 else
923 {
924 Integer previous = constraints.gridHeight > 1 ? new Integer(
925 constraints.gridHeight - 1) : null;
926 return previous;
927 }
928 }
929
930 public Object getValue()
931 {
932 if (constraints == null)
933 return "";
934 else
935 return new Integer(constraints.gridHeight);
936 }
937
938 public void setValue(Object value)
939 {
940 if (constraints == null || value == null)
941 return;
942
943 constraints.gridHeight = ((Number) value).intValue();
944 super.fireStateChanged();
945 updateLayout(component);
946
947
948
949 int col = table.getSelectedColumn();
950 int row = table.getSelectedRow();
951 tableModel.fireTableDataChanged();
952 setSelectedCell(col, row, true);
953 }
954 }
955
956 /***
957 * Returns true if the named component was created by hand in this session
958 */
959 public boolean isNewComponent(Component component)
960 {
961 return newComponents.contains(component);
962 }
963
964 @SuppressWarnings("serial")
965 private class NewComponentDialog0 extends JDialog
966 {
967 JTextField nameField = new JTextField();
968
969 JLabel nameLabel = new JLabel("Name");
970
971 JLabel typeLabel = new JLabel("Type");
972
973 JButton okButton = new JButton("OK");
974
975 JButton cancelButton = new JButton("Cancel");
976
977 JComboBox typeCombo = new JComboBox();
978
979 PropertyTableModel propertyTableModel = new PropertyTableModel();
980
981 JTable propertyTable = new JTable();
982
983 JScrollPane propertyScrollPane = new JScrollPane(propertyTable);
984
985 boolean wasSuccessful = false;
986
987 Component component = null;
988
989 Map<String, Object> controlProperties = new HashMap<String, Object>();
990
991 public NewComponentDialog0(Frame owner) throws Exception
992 {
993 super(owner, "Add Component", true);
994
995 okButton.setMnemonic(KeyEvent.VK_O);
996 cancelButton.setMnemonic(KeyEvent.VK_C);
997 nameLabel.setDisplayedMnemonic(KeyEvent.VK_N);
998 typeLabel.setDisplayedMnemonic(KeyEvent.VK_T);
999 nameLabel.setLabelFor(nameField);
1000 typeLabel.setLabelFor(typeCombo);
1001
1002
1003
1004 JPanel content = new JPanel();
1005 content.setBorder(Borders.DIALOG_BORDER);
1006 layoutConstraintsManager.setLayout("newComponentContent", content);
1007 getContentPane().setLayout(new BorderLayout());
1008 getContentPane().add(content, BorderLayout.CENTER);
1009
1010 content.add(typeCombo, "typeCombo");
1011 content.add(nameField, "nameField");
1012 content.add(typeLabel, "typeLabel");
1013 content.add(nameLabel, "nameLabel");
1014 content.add(propertyScrollPane, "propertyScrollPane");
1015 content.add(com.jgoodies.forms.factories.ButtonBarFactory
1016 .buildRightAlignedBar(new JButton[] { okButton, cancelButton }),
1017 "buttonPanel");
1018
1019 propertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
1020 propertyTable.setModel(propertyTableModel);
1021
1022 pack();
1023
1024 typeCombo.addItem(new DefaultComponentBuilder(javax.swing.JButton.class,
1025 new String[] { "text" }));
1026 typeCombo.addItem(new DefaultComponentBuilder(
1027 javax.swing.JCheckBox.class, new String[] { "text" }));
1028 typeCombo
1029 .addItem(new DefaultComponentBuilder(javax.swing.JComboBox.class));
1030 typeCombo.addItem(new DefaultComponentBuilder(javax.swing.JLabel.class,
1031 new String[] { "text" }));
1032 typeCombo.addItem(new JListComponentBuilder());
1033 typeCombo.addItem(new DefaultComponentBuilder(javax.swing.JPanel.class));
1034 typeCombo.addItem(new DefaultComponentBuilder(
1035 javax.swing.JPasswordField.class));
1036 typeCombo.addItem(new DefaultComponentBuilder(
1037 javax.swing.JRadioButton.class, new String[] { "text" }));
1038 typeCombo.addItem(new DefaultComponentBuilder(
1039 javax.swing.JScrollPane.class));
1040 typeCombo
1041 .addItem(new DefaultComponentBuilder(javax.swing.JSpinner.class));
1042 typeCombo.addItem(new JTableComponentBuilder());
1043 typeCombo
1044 .addItem(new DefaultComponentBuilder(javax.swing.JTextArea.class));
1045 typeCombo.addItem(new DefaultComponentBuilder(
1046 javax.swing.JTextField.class));
1047 typeCombo.addItem(new JToolBarComponentBuilder());
1048 typeCombo.addItem(new JTreeComponentBuilder());
1049 typeCombo.addItem(new SeparatorComponentBuilder());
1050 typeCombo.addItem(new ButtonBarComponentBuilder());
1051
1052 typeCombo.addActionListener(new ActionListener()
1053 {
1054 public void actionPerformed(ActionEvent e)
1055 {
1056 controlProperties = new HashMap<String, Object>();
1057 propertyTableModel.fireTableDataChanged();
1058 }
1059 });
1060
1061 okButton.addActionListener(new ActionListener()
1062 {
1063 public void actionPerformed(ActionEvent e)
1064 {
1065
1066 try
1067 {
1068 if (nameField.getText().trim().length() == 0)
1069 throw new Exception("The name field is required");
1070
1071
1072
1073
1074 ComponentBuilder builder = (ComponentBuilder) typeCombo
1075 .getSelectedItem();
1076 component = builder.getInstance(controlProperties);
1077
1078 wasSuccessful = true;
1079 dispose();
1080
1081 }
1082 catch (Exception exception)
1083 {
1084 exception.printStackTrace();
1085 wasSuccessful = false;
1086 JOptionPane.showMessageDialog(null, exception.getMessage(),
1087 "Error Creating Component", JOptionPane.ERROR_MESSAGE);
1088 }
1089 }
1090 });
1091
1092 cancelButton.addActionListener(new ActionListener()
1093 {
1094 public void actionPerformed(ActionEvent e)
1095 {
1096 wasSuccessful = false;
1097 dispose();
1098 }
1099 });
1100 }
1101
1102 public boolean wasSuccessful()
1103 {
1104 return wasSuccessful;
1105 }
1106
1107 public String getComponentName()
1108 {
1109 return nameField.getText();
1110 }
1111
1112 public String getComponentDeclaration()
1113 {
1114 ComponentBuilder builder = (ComponentBuilder) typeCombo.getSelectedItem();
1115 return builder.getDeclaration(getComponentName(), controlProperties);
1116 }
1117
1118 public boolean isUsingLayoutComponent()
1119 {
1120 ComponentBuilder builder = (ComponentBuilder) typeCombo.getSelectedItem();
1121 return builder.isComponentALayoutContainer();
1122 }
1123
1124 public Component getComponent()
1125 {
1126 return component;
1127 }
1128
1129 public ComponentDef getComponentDef()
1130 {
1131 ComponentBuilder builder = (ComponentBuilder) typeCombo.getSelectedItem();
1132 return builder.getComponentDef(getComponentName(), controlProperties);
1133 }
1134
1135 private class PropertyTableModel extends
1136 javax.swing.table.AbstractTableModel
1137 {
1138 public int getColumnCount()
1139 {
1140 return 2;
1141 }
1142
1143 public int getRowCount()
1144 {
1145 ComponentBuilder builder = (ComponentBuilder) typeCombo
1146 .getSelectedItem();
1147 return builder != null ? builder.getProperties().size() : 0;
1148 }
1149
1150 public boolean isCellEditable(int row, int col)
1151 {
1152 return col == 1;
1153 }
1154
1155 public String getColumnName(int col)
1156 {
1157 return col == 0 ? "Property" : "Value";
1158 }
1159
1160 public void setValueAt(Object aValue, int row, int col)
1161 {
1162 ComponentBuilder builder = (ComponentBuilder) typeCombo
1163 .getSelectedItem();
1164 List<BeanProperty> properties = builder.getProperties();
1165 BeanProperty property = properties.get(row);
1166 controlProperties.put(property.getName(), aValue);
1167 }
1168
1169 public Object getValueAt(int rowIndex, int columnIndex)
1170 {
1171 ComponentBuilder builder = (ComponentBuilder) typeCombo
1172 .getSelectedItem();
1173 List<BeanProperty> properties = builder.getProperties();
1174 BeanProperty property = properties.get(rowIndex);
1175
1176 return columnIndex == 0 ? property.getName() : controlProperties
1177 .get(property.getName());
1178 }
1179
1180 public Component getComponent() throws Exception
1181 {
1182 ComponentBuilder builder = (ComponentBuilder) typeCombo
1183 .getSelectedItem();
1184 Component instance = builder.getInstance(controlProperties);
1185 return instance;
1186 }
1187 }
1188 }
1189
1190 @SuppressWarnings("serial")
1191 private class ConstraintTableCellRenderer extends DefaultTableCellRenderer
1192 {
1193 public Component getTableCellRendererComponent(JTable table, Object value,
1194 boolean isSelected, boolean hasFocus, int row, int column)
1195 {
1196 String stringValue = null;
1197 if (value != null)
1198 {
1199 if (value instanceof Component)
1200 {
1201 String name = getComponentName((Component) value);
1202 stringValue = name == null ? "(Untitled)" : name;
1203 }
1204 else
1205 {
1206
1207 stringValue = (String) value;
1208 }
1209 }
1210
1211 return super.getTableCellRendererComponent(table, stringValue,
1212 isSelected, hasFocus, row, column);
1213 }
1214 }
1215
1216 @SuppressWarnings("serial")
1217 private class GridTableModel extends javax.swing.table.AbstractTableModel
1218 {
1219
1220 public int getColumnCount()
1221 {
1222 return containerLayout != null ? containerLayout.getColumnCount() + 1 : 1;
1223 }
1224
1225 public int getRowCount()
1226 {
1227 return containerLayout != null ? containerLayout.getRowCount() + 1 : 1;
1228 }
1229
1230 public boolean isCellEditable(int row, int col)
1231 {
1232 return (row == 0 || col == 0) && !(row == 0 && col == 0);
1233 }
1234
1235 public String getColumnName(int col)
1236 {
1237 return col == 0 ? "*" : "" + col;
1238 }
1239
1240 public void setValueAt(Object aValue, int row, int col)
1241 {
1242 String value = (String) aValue;
1243 if (row == 0)
1244 {
1245 try
1246 {
1247 containerLayout.setColumnSpec(col - 1, value);
1248 specsChanged();
1249 }
1250 catch (IllegalArgumentException iae)
1251 {
1252 JOptionPane.showMessageDialog(FormEditor.this, iae.getMessage(),
1253 "Invalid Layout", JOptionPane.ERROR_MESSAGE);
1254 }
1255 }
1256 else if (col == 0)
1257 {
1258 try
1259 {
1260 containerLayout.setRowSpec(row - 1, value);
1261 specsChanged();
1262 }
1263 catch (Exception e)
1264 {
1265 JOptionPane.showMessageDialog(null, e.getMessage(),
1266 "Invalid row specification", JOptionPane.ERROR_MESSAGE);
1267 }
1268 }
1269 }
1270
1271 public Object getValueAt(int rowIndex, int columnIndex)
1272 {
1273 if (rowIndex == 0 && columnIndex == 0)
1274 return null;
1275 if (rowIndex == 0)
1276 return containerLayout.getColumnSpec(columnIndex - 1);
1277 if (columnIndex == 0)
1278 return containerLayout.getRowSpec(rowIndex - 1);
1279
1280 Component component = null;
1281
1282 for (int index = 0; index < container.getComponentCount(); index++)
1283 {
1284 Component thisComponent = container.getComponent(index);
1285
1286
1287
1288
1289 if (thisComponent.isVisible())
1290 {
1291 CellConstraints constraints = getComponentConstraints(thisComponent);
1292 if (constraints == null)
1293 throw new RuntimeException(
1294 "Unable to find constraints for component " + thisComponent
1295 + " in layout " + containerLayout.getName());
1296 if (columnIndex >= constraints.gridX
1297 && columnIndex < constraints.gridX + constraints.gridWidth
1298 && rowIndex >= constraints.gridY
1299 && rowIndex < constraints.gridY + constraints.gridHeight)
1300 {
1301 component = thisComponent;
1302 if (component == topComponent)
1303 break;
1304 }
1305 }
1306 }
1307
1308 return component;
1309 }
1310 }
1311
1312 @SuppressWarnings("serial")
1313 private class RemoveComponentAction extends AbstractAction
1314 {
1315 public RemoveComponentAction()
1316 {
1317 super();
1318 putValue(Action.SHORT_DESCRIPTION, "Remove the component (Alt+D)");
1319 putValue(Action.LONG_DESCRIPTION, "Remove the component (Alt+D)");
1320 putValue(Action.SMALL_ICON, new ImageIcon(FormEditor.class
1321 .getResource("Remove24.gif")));
1322 putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_D,
1323 KeyEvent.CTRL_MASK));
1324 }
1325
1326 public void actionPerformed(ActionEvent e)
1327 {
1328 Component selectedControl = table.getSelectedControl();
1329 String controlName = getComponentName(selectedControl);
1330 container.remove(selectedControl);
1331 tableModel.fireTableDataChanged();
1332
1333 if (selectedControl instanceof Container
1334 && layoutFrame.hasContainer(controlName))
1335 {
1336 layoutFrame.removeContainer(controlName);
1337 }
1338 container.doLayout();
1339 container.repaint();
1340 componentSelectionListModel.fireDelete();
1341
1342 setFormComponent(null);
1343 table.requestFocus();
1344 }
1345 }
1346
1347 @SuppressWarnings("serial")
1348 private class NewComponentAction extends AbstractAction
1349 {
1350 public NewComponentAction()
1351 {
1352 super();
1353 putValue(Action.SHORT_DESCRIPTION, "Create a new component (Alt+N)");
1354 putValue(Action.LONG_DESCRIPTION, "Create a new component (Alt+N)");
1355 putValue(Action.SMALL_ICON, new ImageIcon(FormEditor.class
1356 .getResource("New24.gif")));
1357 putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_N));
1358 }
1359
1360 public void actionPerformed(ActionEvent e)
1361 {
1362 Frame frame = (Frame) SwingUtilities.getAncestorOfClass(Frame.class,
1363 FormEditor.this);
1364
1365 NewComponentDialog0 newComponentDialog = null;
1366 int columnIndex = table.getSelectedColumn();
1367 int rowIndex = table.getSelectedRow();
1368
1369 try
1370 {
1371 newComponentDialog = new NewComponentDialog0(frame);
1372 newComponentDialog.setVisible(true);
1373 }
1374 catch (Exception ex)
1375 {
1376 ex.printStackTrace();
1377 }
1378
1379 if (newComponentDialog.wasSuccessful())
1380 {
1381 String controlName = newComponentDialog.getComponentName();
1382 Component newControl = newComponentDialog.getComponent();
1383 ComponentDef newCD = newComponentDialog.getComponentDef();
1384
1385 if (containerLayout.getCellConstraints(controlName) != null)
1386 {
1387 JOptionPane.showMessageDialog(FormEditor.this, "A component named '"
1388 + controlName + "' already exists", "Error",
1389 JOptionPane.ERROR_MESSAGE);
1390 }
1391 else
1392 {
1393
1394
1395
1396
1397
1398 CellConstraints newConstraints = new CellConstraints(columnIndex,
1399 rowIndex);
1400 if ( newCD != null )
1401 containerLayout.addComponent(controlName, newCD, newConstraints);
1402 containerLayout.getCellConstraints().put(controlName, newConstraints);
1403 container.add(newControl, controlName);
1404
1405
1406
1407
1408
1409
1410
1411
1412 if (newComponentDialog.isUsingLayoutComponent())
1413 {
1414 Container newContainer = (Container) newControl;
1415 layoutFrame.addContainer(controlName, newContainer);
1416 }
1417
1418 componentSelectionListModel.fireInsert();
1419
1420 table.changeSelection(newConstraints.gridY, newConstraints.gridX,
1421 false, false);
1422 updateLayout(newControl);
1423 updateLayouts();
1424
1425 newComponents.add(newControl);
1426 }
1427 }
1428
1429 table.requestFocus();
1430 }
1431 }
1432
1433 @SuppressWarnings("serial")
1434 private class InsertRowBeforeAction extends AbstractAction
1435 {
1436 public InsertRowBeforeAction()
1437 {
1438 super();
1439 putValue(Action.SHORT_DESCRIPTION,
1440 "Inserts a row before the selected row");
1441 putValue(Action.LONG_DESCRIPTION, "Inserts a row before the selected row");
1442 putValue(Action.SMALL_ICON, new ImageIcon(FormEditor.class
1443 .getResource("RowInsertBefore24.gif")));
1444 putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_I));
1445 }
1446
1447 public void actionPerformed(ActionEvent e)
1448 {
1449 int row = table.getSelectedRow();
1450 insertRow(row - 1);
1451 table.requestFocus();
1452 }
1453 }
1454
1455 @SuppressWarnings("serial")
1456 private class InsertRowAfterAction extends AbstractAction
1457 {
1458 public InsertRowAfterAction()
1459 {
1460 super();
1461 putValue(Action.SHORT_DESCRIPTION, "Inserts a row after the selected row");
1462 putValue(Action.LONG_DESCRIPTION, "Inserts a row after the selected row");
1463 putValue(Action.SMALL_ICON, new ImageIcon(FormEditor.class
1464 .getResource("RowInsertAfter24.gif")));
1465 putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_O));
1466 }
1467
1468 public void actionPerformed(ActionEvent e)
1469 {
1470 int row = table.getSelectedRow();
1471 insertRow(row);
1472 table.requestFocus();
1473 }
1474 }
1475
1476 @SuppressWarnings("serial")
1477 private class InsertColumnBeforeAction extends AbstractAction
1478 {
1479 public InsertColumnBeforeAction()
1480 {
1481 super();
1482 putValue(Action.SHORT_DESCRIPTION,
1483 "Inserts a column before the selected column");
1484 putValue(Action.LONG_DESCRIPTION,
1485 "Inserts a column before the selected column");
1486 putValue(Action.SMALL_ICON, new ImageIcon(FormEditor.class
1487 .getResource("ColumnInsertBefore24.gif")));
1488 putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_K));
1489 }
1490
1491 public void actionPerformed(ActionEvent e)
1492 {
1493 int column = table.getSelectedColumn();
1494 insertColumn(column - 1);
1495 table.requestFocus();
1496 }
1497 }
1498
1499 @SuppressWarnings("serial")
1500 private class InsertColumnAfterAction extends AbstractAction
1501 {
1502 public InsertColumnAfterAction()
1503 {
1504 super();
1505 putValue(Action.SHORT_DESCRIPTION,
1506 "Inserts a column after the selected column");
1507 putValue(Action.LONG_DESCRIPTION,
1508 "Inserts a column after the selected column");
1509 putValue(Action.SMALL_ICON, new ImageIcon(FormEditor.class
1510 .getResource("ColumnInsertAfter24.gif")));
1511 putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_L));
1512 }
1513
1514 public void actionPerformed(ActionEvent e)
1515 {
1516 int column = table.getSelectedColumn();
1517 insertColumn(column);
1518 table.requestFocus();
1519 }
1520 }
1521
1522 @SuppressWarnings("serial")
1523 private class DeleteRowAction extends AbstractAction
1524 {
1525 public DeleteRowAction()
1526 {
1527 super();
1528 putValue(Action.SHORT_DESCRIPTION, "Deletes the selected row");
1529 putValue(Action.LONG_DESCRIPTION, "Deletes the selected row");
1530 putValue(Action.SMALL_ICON, new ImageIcon(FormEditor.class
1531 .getResource("RowDelete24.gif")));
1532 putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_D));
1533 }
1534
1535 public void actionPerformed(ActionEvent e)
1536 {
1537 int rowIndex = table.getSelectedRow();
1538
1539
1540
1541 for (int index = 0; index < container.getComponentCount(); index++)
1542 {
1543 Component component = container.getComponent(index);
1544 CellConstraints constraints = getComponentConstraints(component);
1545
1546 if (constraints.gridY >= rowIndex && constraints.gridY > 1)
1547 {
1548 constraints.gridY--;
1549 }
1550 else
1551 {
1552
1553
1554
1555 if (constraints.gridY + constraints.gridHeight - 1 >= rowIndex
1556 && constraints.gridHeight > 1)
1557 constraints.gridHeight--;
1558 }
1559 }
1560
1561 containerLayout.removeRowSpec(rowIndex - 1);
1562
1563 tableModel.fireTableRowsDeleted(rowIndex, rowIndex);
1564 table.changeSelection(Math.min(rowIndex, containerLayout.getRowCount()),
1565 0, false, false);
1566 specsChanged();
1567 table.requestFocus();
1568 }
1569 }
1570
1571 @SuppressWarnings("serial")
1572 private class DeleteColumnAction extends AbstractAction
1573 {
1574 public DeleteColumnAction()
1575 {
1576 super();
1577 putValue(Action.SHORT_DESCRIPTION, "Deletes the selected column");
1578 putValue(Action.LONG_DESCRIPTION, "Deletes the selected column");
1579 putValue(Action.SMALL_ICON, new ImageIcon(FormEditor.class
1580 .getResource("ColumnDelete24.gif")));
1581 putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_C));
1582 }
1583
1584 public void actionPerformed(ActionEvent e)
1585 {
1586 int columnIndex = table.getSelectedColumn();
1587
1588 for (int index = 0; index < container.getComponentCount(); index++)
1589 {
1590 Component component = container.getComponent(index);
1591 CellConstraints constraints = getComponentConstraints(component);
1592
1593 if (constraints.gridX >= columnIndex && constraints.gridX > 1)
1594 constraints.gridX--;
1595 else
1596 {
1597
1598
1599
1600 if (constraints.gridX + constraints.gridWidth - 1 >= columnIndex
1601 && constraints.gridWidth > 1)
1602 constraints.gridWidth--;
1603 }
1604 }
1605
1606 containerLayout.removeColumnSpec(columnIndex - 1);
1607 tableModel.fireTableStructureChanged();
1608 table.changeSelection(0, Math.min(columnIndex, containerLayout
1609 .getColumnCount()), false, false);
1610 specsChanged();
1611 table.requestFocus();
1612 }
1613 }
1614
1615 @SuppressWarnings("serial")
1616 class ComponentPaletteListModel extends AbstractListModel
1617 {
1618 List<ComponentDef> componentDefs = ComponentDef.createComponentDefs();
1619
1620 public int getSize()
1621 {
1622 return componentDefs.size();
1623 }
1624
1625 public Object getElementAt(int index)
1626 {
1627 return componentDefs.get(index);
1628 }
1629 }
1630
1631 @SuppressWarnings("serial")
1632 class ComponentPaletteListRenderer extends JLabel implements ListCellRenderer
1633 {
1634 public ComponentPaletteListRenderer()
1635 {
1636 setOpaque(true);
1637 }
1638
1639
1640
1641
1642
1643 public Component getListCellRendererComponent(JList list, Object value,
1644 int index, boolean isSelected, boolean cellHasFocus)
1645 {
1646 ComponentDef componentDef = (ComponentDef) value;
1647 setIcon(componentDef.icon != null ? componentDef.icon : null);
1648 setText(componentDef.name);
1649 if (isSelected)
1650 {
1651 setBackground(list.getSelectionBackground());
1652 setForeground(list.getSelectionForeground());
1653 }
1654 else
1655 {
1656 setBackground(list.getBackground());
1657 setForeground(list.getForeground());
1658 }
1659 return this;
1660 }
1661 }
1662
1663 public void updateList()
1664 {
1665 componentSelectionListModel.fireInsert();
1666 }
1667 public String uniqueName(String name, Component comp)
1668 {
1669
1670
1671 String newname = name;
1672 int suffix = 1;
1673 for (;;)
1674 {
1675 Component temp = containerLayout.getComponentByName(newname);
1676
1677 if ( temp == null || temp == comp )
1678 break;
1679
1680 newname = name + "_" + suffix;
1681 suffix++;
1682 }
1683 return newname;
1684 }
1685
1686 public boolean editComponent(ComponentDef componentDef,
1687 Component component,
1688 CellConstraints cellConstraints)
1689 {
1690 if ( componentDef.isContainer )
1691 return false;
1692
1693
1694 String name = getComponentName(component);
1695
1696 NewComponentDialog dlg =
1697 NewComponentDialog.editDialog(layoutFrame,componentDef);
1698 if (!dlg.succeeded())
1699 return false;
1700
1701 componentDef.name = uniqueName(dlg.getComponentName(),component);
1702 String newname = componentDef.name;
1703
1704 Component newcomponent = dlg.getInstance();
1705 containerLayout.removeLayoutComponent(component);
1706 containerLayout.addComponent(newname, componentDef, cellConstraints);
1707
1708 container.remove(component);
1709 container.add(newcomponent,newname);
1710
1711 newComponents.remove(component);
1712 newComponents.add(newcomponent);
1713
1714 if (componentDef.isContainer)
1715 {
1716 /*** @todo losing components INSIDE the container!! */
1717
1718 layoutFrame.removeContainer(name);
1719 layoutFrame.addContainer(newname, (Container)newcomponent);
1720 }
1721
1722 updateLayout(newcomponent);
1723 updateList();
1724 updateLayouts();
1725 repaint();
1726 return true;
1727 }
1728 }