View Javadoc

1   package org.devaki.nextobjects.ui.workspace.models.objects;
2   /*
3    *  nextobjects Copyright (C) 2001-2005 Emmanuel Florent
4    *  This program is free software; you can redistribute it and/or modify
5    *  it under the terms of the GNU General Public License as published by the
6    *  Free Software Foundation; either version 2 of the License, or (at your
7    *  option) any later version.
8    *  This program is distributed in the hope that it will
9    *  be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
10   *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   *  PURPOSE. See the GNU General Public License for more details.
12   *  You should have received a copy of the GNU General Public License along
13   *  with this program; if not, write to the Free Software Foundation, Inc., 59
14   *  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15   */
16  import java.awt.Component;
17  import java.awt.Dimension;
18  import java.awt.GridBagConstraints;
19  import java.awt.GridBagLayout;
20  import java.awt.Insets;
21  import java.awt.Rectangle;
22  import java.awt.event.ActionEvent;
23  import java.awt.event.ActionListener;
24  import java.awt.event.FocusAdapter;
25  import java.awt.event.FocusEvent;
26  import java.awt.event.MouseAdapter;
27  import java.awt.event.MouseEvent;
28  import javax.swing.ListModel;
29  import java.util.Vector;
30  import java.util.List;
31  import java.util.Iterator;
32  import javax.swing.BorderFactory;
33  import javax.swing.Icon;
34  import javax.swing.JCheckBox;
35  import javax.swing.JDialog;
36  import javax.swing.JLabel;
37  import javax.swing.JList;
38  import javax.swing.JPanel;
39  import javax.swing.JScrollPane;
40  import javax.swing.JTabbedPane;
41  import javax.swing.ListCellRenderer;
42  import javax.swing.ListSelectionModel;
43  import javax.swing.SwingConstants;
44  import javax.swing.UIManager;
45  import javax.swing.WindowConstants;
46  import javax.swing.border.EmptyBorder;
47  import javax.swing.event.DocumentEvent;
48  import javax.swing.event.DocumentListener;
49  import org.devaki.nextobjects.NextObjects;
50  import org.devaki.nextobjects.ui.components.CustomButton;
51  import org.devaki.nextobjects.ui.components.CustomTextArea;
52  import org.devaki.nextobjects.ui.components.CustomTextField;
53  import org.devaki.nextobjects.ui.components.CustomComboBox;
54  import org.devaki.nextobjects.workspace.models.objects.Constraint;
55  import org.devaki.nextobjects.workspace.models.objects.Table;
56  import org.devaki.nextobjects.workspace.models.columns.Column;
57  /***
58   *  This class is responsible for editing a constraint
59   *
60   * @author    <a href="mailto:eflorent@devaki.org">Emmanuel Florent</a>
61   */
62  public class ConstraintEdit extends JDialog
63  {
64      /***  The context constraint */
65      private Constraint myConstraint;
66      /***  the label to introduce the name */
67      private JLabel jLabelName = new JLabel("Name");
68      /***  the label to introduce the name */
69      private JLabel jLabelLink = new JLabel(" 1 ... * ");
70      /***  The label to introduce the description */
71      private JLabel jLabelDescription = new JLabel("Description");
72      /***  The label to intrroduce primary key */
73      private JLabel jLabelParent = new JLabel("Local");
74      /***  The label to introduce onUpdate */
75      private JLabel jLabelOnUpdate = new JLabel("On update");
76      /***  The label to introduce onDelete */
77      private JLabel jLabelOnDelete = new JLabel("On delete");
78      /***  The label to introduce the foreign key */
79      private JLabel jLabelChild = new JLabel("Reference");
80      /***  The textfield for setting an human readable name */
81      private CustomTextField jTextFieldName =
82          new CustomTextField("", "Name of the constraint in the schema", true);
83      /***  The textarea for setting a description */
84      private CustomTextArea jTextAreaDescription =
85          new CustomTextArea("", "Description of the contraint", true, true);
86      /***  The textarea for setting notes */
87      private CustomTextArea jTextAreaNotes =
88          new CustomTextArea("", "Notes about the constraint", true, true);
89      /***  The OK button */
90      private CustomButton jButtonOK = new CustomButton("OK", "", true, false);
91      /***  The cancel button */
92      private CustomButton jButtonCancel =
93          new CustomButton("Cancel", "", true, false);
94      /***  Jlist for setting the primary key */
95      private JList jListReference = new JList();
96      /***  JList for setting the foreign key */
97      private JList jListLocalKey = new JList();
98      /***  possible onUpdate values */
99      String[] onChanges = {"none", "cascade", "restrict", "setnull"};
100     /***  Combobox for setting the onUpdate */
101     private CustomComboBox jComboUpdate = new CustomComboBox(onChanges, 0, "On update", true);
102     /***  Combobox for setting the onDelete */
103     private CustomComboBox jComboDelete = new CustomComboBox(onChanges, 0, "On delete", true);
104     /***  The main tabbed pane */
105     private JTabbedPane jTabbedPane = new JTabbedPane(SwingConstants.TOP);
106     /***  The general panel */
107     private JPanel jPanelGeneral = new JPanel(new GridBagLayout());
108     /***  The properties panel */
109     private JPanel jPanelGeneralProperties = new JPanel(new GridBagLayout());
110     /***  The constraint panel */
111     private JPanel jPanelGeneralConstraint = new JPanel(new GridBagLayout());
112     /***  The notes panel */
113     private JPanel jPanelNotes = new JPanel(new GridBagLayout());
114 
115 
116     /***  Construct a new 'ConstraintEdit' object */
117     public ConstraintEdit()
118     {
119         super(NextObjects.getReference());
120         /***  Initialization * */
121         // Define the size of the window
122         this.setSize(new Dimension(457, 500));
123         // Center the window
124         this.setLocationRelativeTo(null);
125         // Specify that the window is modal
126         this.setModal(true);
127         // Specify that the window is not resizable
128         this.setResizable(false);
129         // Define what to do when closing this window
130         this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
131         /***  Components properties * */
132         // Panels
133         this.getContentPane().setLayout(new GridBagLayout());
134         this.jPanelGeneralProperties.setBorder(
135             BorderFactory.createTitledBorder("Properties"));
136         this.jPanelGeneralConstraint.setBorder(
137             BorderFactory.createTitledBorder("Constraint"));
138         /***  Listeners * */
139         // ACTION
140         this.jButtonOK.addActionListener(
141             new ActionListener()
142             {
143                 public final void actionPerformed(final ActionEvent e)
144                 {
145                     closingWindow(true);
146                 }
147             });
148         this.jButtonCancel.addActionListener(
149             new ActionListener()
150             {
151                 public final void actionPerformed(final ActionEvent e)
152                 {
153                     closingWindow(false);
154                 }
155             });
156         // FOCUS
157         this.jTextFieldName.addFocusListener(
158             new FocusAdapter()
159             {
160                 // Select the content of 'jTextFieldName' when it gained focus
161                 public final void focusGained(final FocusEvent e)
162                 {
163                     jTextFieldName.selectAll();
164                 }
165             });
166         // DOCUMENT
167         this
168             .jTextFieldName
169             .getDocument()
170             .addDocumentListener(
171             new DocumentListener()
172             {
173                 // Not implemented
174                 public final void changedUpdate(final DocumentEvent e)
175                 {
176                 }
177 
178 
179                 // When inserting text, call 'enablingOKButton'
180 
181                 public final void insertUpdate(final DocumentEvent e)
182                 {
183                     enablingOKButton();
184                 }
185 
186 
187                 // When removing text, call 'enablingOKButton'
188 
189                 public final void removeUpdate(final DocumentEvent e)
190                 {
191                     enablingOKButton();
192                 }
193             });
194         jListReference.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
195         jListReference.setCellRenderer(new CheckListRenderer());
196         jListReference.setBorder(new EmptyBorder(0, 4, 4, 0));
197         jListReference.addMouseListener(
198             new MouseAdapter()
199             {
200                 public final void mouseClicked(final MouseEvent e)
201                 {
202                 int index = jListReference.locationToIndex(e.getPoint());
203                 CheckableItem item =
204                         (CheckableItem) jListReference.getModel().getElementAt(
205                         index);
206 
207                     item.setSelected(!item.isSelected());
208 
209                 Rectangle rect = jListReference.getCellBounds(index, index);
210 
211                     jListReference.repaint(rect);
212                 }
213             });
214         jListLocalKey.setSelectionMode(
215             ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
216         jListLocalKey.setCellRenderer(new CheckListRenderer());
217         jListLocalKey.setBorder(new EmptyBorder(0, 0, 4, 4));
218         jListLocalKey.addMouseListener(
219             new MouseAdapter()
220             {
221                 public final void mouseClicked(final MouseEvent e)
222                 {
223                 int index = jListLocalKey.locationToIndex(e.getPoint());
224                 CheckableItem item =
225                         (CheckableItem) jListLocalKey.getModel().getElementAt(
226                         index);
227 
228                     item.setSelected(!item.isSelected());
229 
230                 Rectangle rect = jListLocalKey.getCellBounds(index, index);
231 
232                     jListLocalKey.repaint(rect);
233                 }
234             });
235 
236     JScrollPane spReference = new JScrollPane(jListReference);
237     JScrollPane spLocal = new JScrollPane(jListLocalKey);
238 
239         /***  Assembling components * */
240         // 'jPanelGeneralProperties'
241         this.jPanelGeneralProperties.add(
242             this.jLabelName,
243             new GridBagConstraints(
244             0,
245             0,
246             1,
247             1,
248             0.0,
249             0.0,
250             GridBagConstraints.WEST,
251             GridBagConstraints.NONE,
252             new Insets(5, 5, 0, 5),
253             0,
254             0));
255         this.jPanelGeneralProperties.add(
256             this.jTextFieldName,
257             new GridBagConstraints(
258             1,
259             0,
260             1,
261             1,
262             0.0,
263             0.0,
264             GridBagConstraints.CENTER,
265             GridBagConstraints.HORIZONTAL,
266             new Insets(5, 0, 0, 5),
267             0,
268             0));
269         this.jPanelGeneralProperties.add(
270             this.jLabelDescription,
271             new GridBagConstraints(
272             0,
273             1,
274             1,
275             1,
276             0.0,
277             0.0,
278             GridBagConstraints.NORTHWEST,
279             GridBagConstraints.NONE,
280             new Insets(5, 5, 0, 5),
281             0,
282             0));
283         this.jPanelGeneralProperties.add(
284             new JScrollPane(this.jTextAreaDescription),
285             new GridBagConstraints(
286             1,
287             1,
288             1,
289             1,
290             1.0,
291             1.0,
292             GridBagConstraints.CENTER,
293             GridBagConstraints.BOTH,
294             new Insets(5, 0, 5, 5),
295             0,
296             0));
297         // 'jPanelGeneralConstraint'
298         this.jPanelGeneralConstraint.add(
299             this.jLabelParent,
300             new GridBagConstraints(
301             0,
302             0,
303             1,
304             1,
305             0.0,
306             0.0,
307             GridBagConstraints.NORTH,
308             GridBagConstraints.NONE,
309             new Insets(5, 5, 5, 5),
310             0,
311             0));
312         this.jPanelGeneralConstraint.add(
313             this.jLabelChild,
314             new GridBagConstraints(
315             2,
316             0,
317             1,
318             1,
319             0.0,
320             0.0,
321             GridBagConstraints.NORTH,
322             GridBagConstraints.NONE,
323             new Insets(5, 5, 5, 5),
324             0,
325             0));
326         //FK
327         this.jPanelGeneralConstraint.add(
328             spLocal,
329             new GridBagConstraints(
330             0,
331             1,
332             1,
333             1,
334             1.0,
335             1.0,
336             GridBagConstraints.NORTH,
337             GridBagConstraints.BOTH,
338             new Insets(2, 2, 2, 2),
339             0,
340             0));
341         this.jPanelGeneralConstraint.add(
342             this.jLabelLink,
343             new GridBagConstraints(
344             1,
345             1,
346             1,
347             1,
348             0.0,
349             0.0,
350             GridBagConstraints.CENTER,
351             GridBagConstraints.HORIZONTAL,
352             new Insets(0, 0, 0, 0),
353             0,
354             0));
355         this.jPanelGeneralConstraint.add(
356             spReference,
357             new GridBagConstraints(
358             2,
359             1,
360             1,
361             1,
362             1.0,
363             1.0,
364             GridBagConstraints.NORTH,
365             GridBagConstraints.BOTH,
366             new Insets(2, 2, 2, 2),
367             0,
368             0));
369         this.jPanelGeneralConstraint.add(
370             jLabelOnUpdate,
371             new GridBagConstraints(
372             0,
373             2,
374             1,
375             1,
376             1.0,
377             1.0,
378             GridBagConstraints.NORTH,
379             GridBagConstraints.BOTH,
380             new Insets(2, 2, 2, 2),
381             0,
382             0));
383         this.jPanelGeneralConstraint.add(
384             jLabelOnDelete,
385             new GridBagConstraints(
386             2,
387             2,
388             1,
389             1,
390             1.0,
391             1.0,
392             GridBagConstraints.NORTH,
393             GridBagConstraints.BOTH,
394             new Insets(2, 2, 2, 2),
395             0,
396             0));
397         this.jPanelGeneralConstraint.add(
398             jComboUpdate,
399             new GridBagConstraints(
400             0,
401             3,
402             1,
403             1,
404             1.0,
405             1.0,
406             GridBagConstraints.NORTH,
407             GridBagConstraints.BOTH,
408             new Insets(2, 2, 2, 2),
409             0,
410             0));
411         this.jPanelGeneralConstraint.add(
412             jComboDelete,
413             new GridBagConstraints(
414             2,
415             3,
416             1,
417             1,
418             1.0,
419             1.0,
420             GridBagConstraints.NORTH,
421             GridBagConstraints.BOTH,
422             new Insets(2, 2, 2, 2),
423             0,
424             0));
425         // 'jPanelGeneral'
426         this.jPanelGeneral.add(
427             this.jPanelGeneralProperties,
428             new GridBagConstraints(
429             0,
430             0,
431             1,
432             1,
433             1.0,
434             1.0,
435             GridBagConstraints.CENTER,
436             GridBagConstraints.BOTH,
437             new Insets(5, 5, 0, 5),
438             0,
439             0));
440         this.jPanelGeneral.add(
441             this.jPanelGeneralConstraint,
442             new GridBagConstraints(
443             0,
444             1,
445             1,
446             1,
447             0.0,
448             0.0,
449             GridBagConstraints.CENTER,
450             GridBagConstraints.BOTH,
451             new Insets(5, 5, 5, 5),
452             0,
453             0));
454         // 'jPanelNotes'
455         this.jPanelNotes.add(
456             new JScrollPane(this.jTextAreaNotes),
457             new GridBagConstraints(
458             0,
459             0,
460             1,
461             1,
462             1.0,
463             1.0,
464             GridBagConstraints.CENTER,
465             GridBagConstraints.BOTH,
466             new Insets(5, 5, 5, 5),
467             0,
468             0));
469         // 'jTabbedPane'
470         this.jTabbedPane.add(this.jPanelGeneral, "General");
471         this.jTabbedPane.add(this.jPanelNotes, "Notes");
472         // Content Panel
473         this.getContentPane().add(
474             this.jTabbedPane,
475             new GridBagConstraints(
476             0,
477             0,
478             2,
479             1,
480             1.0,
481             1.0,
482             GridBagConstraints.NORTH,
483             GridBagConstraints.BOTH,
484             new Insets(5, 5, 0, 5),
485             0,
486             0));
487         this.getContentPane().add(
488             this.jButtonOK,
489             new GridBagConstraints(
490             0,
491             1,
492             1,
493             1,
494             1.0,
495             0.0,
496             GridBagConstraints.EAST,
497             GridBagConstraints.NONE,
498             new Insets(5, 5, 5, 5),
499             0,
500             0));
501         this.getContentPane().add(
502             this.jButtonCancel,
503             new GridBagConstraints(
504             1,
505             1,
506             1,
507             1,
508             0.0,
509             0.0,
510             GridBagConstraints.CENTER,
511             GridBagConstraints.NONE,
512             new Insets(5, 0, 5, 5),
513             0,
514             0));
515     }
516 
517 
518     /***
519      *  What to do before closing the window
520      *
521      * @param  isOK  save it
522      */
523     private void closingWindow(final boolean isOK)
524     {
525         // Save data if this method follows an action on 'jButtonOK'
526         if (isOK)
527         {
528             this.saveData();
529         }
530         // Dispose window (unallocate resources)
531         // show() must be call to set the
532         // window visible again
533         this.dispose();
534     }
535 
536 
537     /***
538      *  Enable or disable the 'OK' button depending on the length of
539      *  'jTextFieldName'
540      */
541     private void enablingOKButton()
542     {
543         if (this.jTextFieldName.getText().length() != 0)
544         {
545             // Both text fields length are different from zero,
546             // so enable 'jButtonOK'
547             this.jButtonOK.setEnabled(true);
548         }
549         // One or both text fields length are equal to zero,
550         // so diable 'jButtonOK'
551         else
552         {
553             this.jButtonOK.setEnabled(false);
554         }
555     }
556 
557 
558     /***
559      *  Get the informations from the selected constraint
560      *
561      * @param  pConstraint  the context constraint
562      */
563     public final void setData(final Constraint pConstraint)
564     {
565         // Define title of the window
566         this.setTitle(
567             new StringBuffer()
568             .append("Properties of '")
569             .append(pConstraint.getName())
570             .append("' - devaki-nextobjects")
571             .toString());
572         // Initialize the local 'Constraint' object
573         // with the 'Constraint' object to edit
574         this.myConstraint = pConstraint;
575         // Initialize components values
576         this.jTextFieldName.setText(this.myConstraint.getName());
577         this.jComboDelete.setSelectedItem(this.myConstraint.getOnDelete());
578         this.jComboUpdate.setSelectedItem(this.myConstraint.getOnUpdate());
579         // set the local key list
580         this.jListLocalKey.setListData(
581             createData(
582             myConstraint.getParentClass().getData(),
583             myConstraint.getLocalColumns()));
584         // set the foreign key list
585         //foreign keys are local to the table !!!
586         this.jListReference.setListData(
587             createData(
588             myConstraint.getChildClass().getData(),
589             myConstraint.getReferences()));
590         // Set 'jButtonOK' as the default button
591         this.getRootPane().setDefaultButton(this.jButtonOK);
592         // Make the window visible
593         this.show();
594     }
595 
596 
597     /***  Set the informations to the selected constraint */
598     private void saveData()
599     {
600         this.myConstraint.setName(this.jTextFieldName.getText());
601         this.myConstraint.setDescription(this.jTextAreaDescription.getText());
602         this.myConstraint.setNotes(this.jTextAreaNotes.getText());
603         if (this.jComboDelete.getSelectedItem() != null)
604         {
605             this.myConstraint.setOnDelete(this.jComboDelete.getSelectedItem().toString());
606         }
607         if (this.jComboUpdate.getSelectedItem() != null)
608         {
609             this.myConstraint.setOnUpdate(this.jComboUpdate.getSelectedItem().toString());
610         }
611 
612     Vector v0 = new Vector();
613     ListModel model = jListReference.getModel();
614     int n = model.getSize();
615 
616         for (int i = 0; i < n; i++)
617         {
618         CheckableItem item = (CheckableItem) model.getElementAt(i);
619 
620             if (item.isSelected())
621             {
622                 //foreign keys are in local table
623                 //mean foreign table host
624                 v0.addElement(
625                     ((Table) myConstraint.getChildClass()).getColumnForId(
626                     item.toString()));
627             }
628         }
629 
630     Vector v = new Vector();
631 
632         model = jListLocalKey.getModel();
633         n = model.getSize();
634         for (int i = 0; i < n; i++)
635         {
636         CheckableItem item = (CheckableItem) model.getElementAt(i);
637 
638             if (item.isSelected())
639             {
640                 v.addElement(
641                     ((Table) myConstraint.getParentClass()).getColumnForId(
642                     item.toString()));
643             }
644         }
645 
646     Iterator itV1 = v.iterator();
647     Iterator itV2 = v0.iterator();
648 
649         while (itV1.hasNext() || itV2.hasNext())
650         {
651             this.myConstraint.addReference(
652                 (Column) itV1.next(),
653                 (Column) itV2.next());
654         }
655         //repaint
656         this.myConstraint.getMyModel().getModelView().setFullRefresh(true);
657         this.myConstraint.getMyModel().getModelView().drawingArea.repaint();
658     }
659 
660 
661     /***
662      *  Help fill checkbox list
663      *
664      * @param  columns   columns
665      * @param  selected  selecteds
666      * @return           an array of checkable items
667      */
668     private final CheckableItem[] createData(
669         final Vector columns,
670         final List selected)
671     {
672     int n = columns.size();
673     CheckableItem[] items = new CheckableItem[n];
674 
675         for (int i = 0; i < n; i++)
676         {
677             items[i] =
678                 new CheckableItem(((Column) columns.elementAt(i)).getCode());
679             items[i].setSelected(selected.contains(columns.elementAt(i)));
680         }
681         return items;
682     }
683 
684 
685     /***
686      *  A checkable item
687      *
688      * @author    <a href="mailto:eflorent@devaki.org">Emmanuel Florent</a>
689      */
690     class CheckableItem
691     {
692         /***  Name */
693         private String str;
694         /***  Is selected */
695         private boolean isSelected;
696         /***  Optional icon */
697         private Icon icon;
698 
699 
700         /***
701          *  Constructor
702          *
703          * @param  pStr  the name of the item
704          */
705         public CheckableItem(final String pStr)
706         {
707             this.str = pStr;
708             isSelected = false;
709         }
710 
711 
712         /***
713          *  Set selected
714          *
715          * @param  b  selected
716          */
717         public final void setSelected(final boolean b)
718         {
719             isSelected = b;
720         }
721 
722 
723         /***
724          *  Is selected
725          *
726          * @return    selected
727          */
728         public final boolean isSelected()
729         {
730             return isSelected;
731         }
732 
733 
734         /***
735          *  Return the description
736          *
737          * @return    description
738          */
739         public final String toString()
740         {
741             return str;
742         }
743 
744 
745         /***
746          *  Set the icon
747          *
748          * @param  pIcon  an icon
749          */
750         public final void setIcon(final Icon pIcon)
751         {
752             this.icon = pIcon;
753         }
754 
755 
756         /***
757          *  Get the icon
758          *
759          * @return    the icon
760          */
761         public final Icon getIcon()
762         {
763             return icon;
764         }
765     }
766 
767 
768     /***
769      *  Render a checkable item
770      *
771      * @author    <a href="mailto:eflorent@devaki.org">Emmanuel Florent</a>
772      */
773     class CheckListRenderer extends JCheckBox implements ListCellRenderer
774     {
775         /***  Constructor */
776         public CheckListRenderer()
777         {
778             setBackground(UIManager.getColor("List.textBackground"));
779             setForeground(UIManager.getColor("List.textForeground"));
780         }
781 
782 
783         /***
784          *  get the renderer
785          *
786          * @param  list        the list
787          * @param  value       the value
788          * @param  index       index
789          * @param  isSelected  is selected
790          * @param  hasFocus    has focus
791          * @return             the list cell renderer componenent
792          */
793         public final Component getListCellRendererComponent(
794             final JList list,
795             final Object value,
796             final int index,
797             final boolean isSelected,
798             final boolean hasFocus)
799         {
800             setEnabled(list.isEnabled());
801             setSelected(((CheckableItem) value).isSelected());
802             setFont(list.getFont());
803             setText(value.toString());
804             return this;
805         }
806     }
807 }