View Javadoc

1   package org.devaki.nextobjects.ui.workspace.models;
2   /*
3   
4   nextobjects Copyright (C) 2001-2005 Emmanuel Florent
5   
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by the
8   Free Software Foundation; either version 2 of the License, or (at your
9   option) any later version.
10  
11  This program is distributed in the hope that it will
12  be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13  of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the GNU General Public License for more details.
15  
16  You should have received a copy of the GNU General Public License along
17  with this program; if not, write to the Free Software Foundation, Inc., 59
18  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  
20  */
21  import java.util.Vector;
22  import java.util.Iterator;
23  import java.util.StringTokenizer;
24  import java.awt.GridBagConstraints;
25  import java.awt.GridBagLayout;
26  import java.awt.Insets;
27  import java.awt.event.ActionEvent;
28  import java.awt.event.ActionListener;
29  import java.awt.event.KeyAdapter;
30  import java.awt.event.KeyEvent;
31  import java.awt.event.MouseAdapter;
32  import java.awt.event.MouseEvent;
33  import javax.swing.BorderFactory;
34  import javax.swing.JPanel;
35  import javax.swing.JScrollPane;
36  import javax.swing.table.AbstractTableModel;
37  import javax.swing.DefaultListSelectionModel;
38  import javax.swing.table.JTableHeader;
39  import javax.swing.table.TableColumnModel;
40  import org.devaki.nextobjects.constants.CstImages;
41  import org.devaki.nextobjects.ui.components.CustomButton;
42  import org.devaki.nextobjects.ui.components.CustomTable;
43  import org.apache.maven.project.Developer;
44  /***
45   * This class provide a jtable representing columns and the ability to edit
46   * a set of column.  Here the columns are build upon the Maven Developer
47   * object. This class is used in the model edit window.
48   *
49   * @author <a href="mailto:eflorent@devaki.org">Emmanuel Florent</a>
50   */
51  public final class DeveloperEdit extends JPanel
52  {
53      /***
54       * Selected row in the jTable
55       */
56      private int selectedRow = -1;
57      /***
58       * The previous (UP) button
59       */
60      private final CustomButton jButtonPrevious =
61          new CustomButton(CstImages.ICN_UP, "Move the selected field up", true);
62      /***
63       * The next (DOWN) button
64       */
65      private final CustomButton jButtonNext =
66          new CustomButton(
67              CstImages.ICN_DOWN,
68              "Move the selected field down",
69              true);
70      /***
71       * The remove button
72       */
73      private final CustomButton jButtonRemove =
74          new CustomButton("Remove", "Remove the selected field", true, false);
75      /***
76       * The new button
77       */
78      private final CustomButton jButtonNew =
79          new CustomButton("New", "Create a new field", true, false);
80      /***
81       * The table for columns
82       */
83      private final CustomTable jTableDevelopers =
84          new CustomTable(
85              false,
86              DefaultListSelectionModel.SINGLE_SELECTION,
87              false,
88              false);
89      /***
90       * The table model
91       */
92      private ObjectDeveloperTableModel model = new ObjectDeveloperTableModel();
93      /***
94       * Constructor
95       *
96       */
97      public DeveloperEdit()
98      {
99          super(new GridBagLayout());
100         // Define table model
101         this.jTableDevelopers.setModel(this.model);
102         // Set tool tips for the table header
103         this.jTableDevelopers.setTableHeader(
104             new ToolTipHeader(this.jTableDevelopers.getColumnModel()));
105         // Fix columns width
106         this.setColumnsWidth();
107         // 'jPanelGeneralFields'
108         this.add(
109             new JScrollPane(this.jTableDevelopers),
110             new GridBagConstraints(
111                 0,
112                 0,
113                 5,
114                 1,
115                 1.0,
116                 1.0,
117                 GridBagConstraints.CENTER,
118                 GridBagConstraints.BOTH,
119                 new Insets(5, 5, 0, 5),
120                 0,
121                 0));
122         this.add(
123             this.jButtonNew,
124             new GridBagConstraints(
125                 0,
126                 1,
127                 1,
128                 1,
129                 0.0,
130                 0.0,
131                 GridBagConstraints.CENTER,
132                 GridBagConstraints.NONE,
133                 new Insets(5, 5, 5, 5),
134                 0,
135                 0));
136         this.add(
137             this.jButtonRemove,
138             new GridBagConstraints(
139                 1,
140                 1,
141                 1,
142                 1,
143                 0.0,
144                 0.0,
145                 GridBagConstraints.CENTER,
146                 GridBagConstraints.NONE,
147                 new Insets(5, 0, 5, 5),
148                 0,
149                 0));
150         this.add(
151             this.jButtonPrevious,
152             new GridBagConstraints(
153                 2,
154                 1,
155                 1,
156                 1,
157                 1.0,
158                 0.0,
159                 GridBagConstraints.EAST,
160                 GridBagConstraints.NONE,
161                 new Insets(5, 0, 5, 5),
162                 0,
163                 0));
164         this.add(
165             this.jButtonNext,
166             new GridBagConstraints(
167                 3,
168                 1,
169                 1,
170                 1,
171                 0.0,
172                 0.0,
173                 GridBagConstraints.CENTER,
174                 GridBagConstraints.NONE,
175                 new Insets(5, 0, 5, 5),
176                 0,
177                 0));
178         // Define table model
179         this.jTableDevelopers.setModel(this.model);
180         // Set tool tips for the table header
181         this.jTableDevelopers.setTableHeader(
182             new ToolTipHeader(this.jTableDevelopers.getColumnModel()));
183         // Fix columns width
184         //this.setColumnsWidth();
185         this.jButtonPrevious.addActionListener(new ActionListener()
186         {
187             // When calling 'jButtonPrevious', invert the current field with the
188             // previous field in 'jTableField'
189             public final void actionPerformed(final ActionEvent e)
190             {
191                 // It can be done, only if the current field is not the first in
192                 // 'jTableField'
193                 if (selectedRow > 0)
194                 {
195                     model.insertDeveloper(
196                         (Developer) model.getDevelopers().elementAt(
197                             selectedRow - 1),
198                         selectedRow + 1);
199                     model.removeField(selectedRow - 1);
200                     jTableDevelopers.setSelectedRow(--selectedRow);
201                 }
202             }
203         });
204         this.jButtonNext.addActionListener(new ActionListener()
205         {
206             // When calling 'jButtonNext', invert the current field
207             // with the next field in 'jTableField'
208             public final void actionPerformed(final ActionEvent e)
209             {
210                 // It can be done, only if the current field is not the last in
211                 // 'jTableField' and that it is different from -1
212                 if ((selectedRow > -1)
213                     && (selectedRow < (jTableDevelopers.getRowCount() - 1)))
214                 {
215                     model.insertDeveloper(
216                         (Developer) model.getDevelopers().elementAt(
217                             selectedRow),
218                         selectedRow + 2);
219                     model.removeField(selectedRow);
220                     jTableDevelopers.setSelectedRow(++selectedRow);
221                 }
222             }
223         });
224         this.jButtonRemove.addActionListener(new ActionListener()
225         {
226             // When calling 'jButtonRemove', remove the current field
227             public final void actionPerformed(final ActionEvent e)
228             {
229                 model.removeField(selectedRow);
230                 // If the removed field was in first position and that
231                 // there is always fields, set 'selectedRow' to zero
232                 if ((jTableDevelopers.getRowCount() > 0) && (selectedRow == 0))
233                 {
234                     selectedRow = -1;
235                     jTableDevelopers.setSelectedRow(selectedRow);
236                 }
237                 // Else decrement 'selectedRow' and apply it to 'jTableField'
238                 else
239                 {
240                     jTableDevelopers.setSelectedRow(--selectedRow);
241                 }
242                 // FIX : Reset the columns width due to an unknow resize call
243                 //setColumnsWidth();
244                 // Disable 'jButtonRemove' if there is no selected row
245                 if (selectedRow == -1)
246                 {
247                     jButtonRemove.setEnabled(false);
248                 }
249             }
250         });
251         this.jButtonNew.addActionListener(new ActionListener()
252         {
253             // When calling 'jButtonNew', add a field
254             public final void actionPerformed(final ActionEvent e)
255             {
256                 // Create a new 'Dependency' object
257                 Developer dep = new Developer();
258                 // Add it to 'jTableField'
259                 model.addDeveloper(dep);
260                 // Update 'selectedRow'
261                 selectedRow = jTableDevelopers.getRowCount() - 1;
262                 // Set the selected field in 'jTableField'
263                 jTableDevelopers.setSelectedRow(selectedRow);
264                 // Enable 'jButtonRemove'
265                 jButtonRemove.setEnabled(true);
266             }
267         });
268         // MOUSE
269         this.jTableDevelopers.addMouseListener(new MouseAdapter()
270         {
271             // When clicking on 'jTableField'...
272             public final void mouseClicked(final MouseEvent e)
273             {
274                 // Set 'selectedRow'
275                 selectedRow = jTableDevelopers.getSelectedRow();
276                 // Enable 'jButtonRemove'
277                 jButtonRemove.setEnabled(true);
278             }
279         });
280         // KEY
281         this.jTableDevelopers.addKeyListener(new KeyAdapter()
282         {
283             // When selecting a row of 'jTableField' using the keyboard...
284             public final void keyReleased(final KeyEvent e)
285             {
286                 // Set 'selectedRow'
287                 selectedRow = jTableDevelopers.getSelectedRow();
288                 // Enable 'jButtonRemove'
289                 jButtonRemove.setEnabled(true);
290             }
291         });
292         this.setBorder(BorderFactory.createTitledBorder("Developers"));
293         // Fix columns width
294         this.setColumnsWidth();
295     }
296     /***
297      * Unused: Cancel edition if 'DataDictionaryEdit' was
298      * edited in its previous call
299      */
300     public final void cancelCellEditing()
301     {
302         if (this.jTableDevelopers.isEditing())
303         {
304             int tmpInt1 = this.jTableDevelopers.getEditingRow();
305             int tmpInt2 = this.jTableDevelopers.getEditingColumn();
306             this
307                 .jTableDevelopers
308                 .getCellEditor(tmpInt1, tmpInt2)
309                 .cancelCellEditing();
310         }
311     }
312     /***
313      * Reset 'jTableField' columns width
314      */
315     private void setColumnsWidth()
316     {
317         for (int i = 0; i < this.model.getColumnCount(); i++)
318         {
319             this.jTableDevelopers.getColumnModel().getColumn(
320                 i).setPreferredWidth(
321                 this.model.getColumnSize(i));
322         }
323     }
324     /***
325      * set the Object Developer TableModel
326      * @param pModel Object Developer TableModel
327      */
328     protected void setModel(ObjectDeveloperTableModel pModel)
329     {
330         this.model = pModel;
331     }
332     /***
333      *  get the Object Developer TableModel
334      * @return Object Developer TableModel
335      */
336     protected ObjectDeveloperTableModel getModel()
337     {
338         return model;
339     }
340     /***
341      * This class define a model to edit the object columns
342      */
343     public final class ObjectDeveloperTableModel extends AbstractTableModel
344     {
345         /*** The data stored to be restored with cancel button */
346         private Vector oldData = new Vector();
347         /***
348          * The column name
349          */
350         private final String[] columnNames =
351             { "name", "id", "email", "organization", "url", "roles" };
352         /***
353          * The column class/types
354          */
355         private final Class[] columnClasses =
356             {
357                 String.class,
358                 String.class,
359                 String.class,
360                 String.class,
361                 String.class,
362                 String.class };
363         /***
364          * The column size
365          */
366         private final int[] columnSizes = { 100, 70, 80, 80, 80, 80 };
367         /***
368          * The columns
369          */
370         private Vector developers = new Vector(1);
371         /***
372          * Return the data contained in the JTable
373          * @return colums
374          */
375         public final Vector getDevelopers()
376         {
377             return developers;
378         }
379         /***
380          * Reset the TableModel to its old values
381          */
382         public final void resetDevelopers()
383         {
384             cancelCellEditing();
385             this.developers = new Vector(oldData);
386         }
387         /***
388          * Set data in the JTable
389          * @param pData the columns
390          */
391         public final void setDevelopers(final Vector pData)
392         {
393             // store the old data
394             oldData.removeAllElements();
395             for (int i = 0; i < pData.size(); i++)
396             {
397                 oldData.addElement(new Developer());
398             }
399             //fix the new data.
400             this.developers = new Vector(pData);
401         }
402         /***
403          * Add a dependency
404          * @param pDeveloper the dependency
405          */
406         public final void addDeveloper(final Developer pDeveloper)
407         {
408             this.developers.addElement(pDeveloper);
409             this.fireTableRowsInserted(
410                 this.developers.size() - 1,
411                 this.developers.size() - 1);
412         }
413         /***
414          * Add a field at a particular index
415          * @param pColumn the column
416          * @param i index
417          */
418         public final void insertDeveloper(final Developer pColumn, final int i)
419         {
420             this.developers.insertElementAt(pColumn, i);
421             this.fireTableRowsInserted(
422                 this.developers.size() - 1,
423                 this.developers.size() - 1);
424         }
425         /***
426          * Remove a field at a particular index
427          * @param i index
428          */
429         public final void removeField(final int i)
430         {
431             if (i >= 0 && i < developers.size())
432             {
433                 this.developers.removeElementAt(i);
434                 this.fireTableRowsDeleted(
435                     this.developers.size() - 1,
436                     this.developers.size() - 1);
437             }
438         }
439         /***
440          * Return the number of columns
441          * @return count
442          */
443         public final int getColumnCount()
444         {
445             return this.columnNames.length;
446         }
447         /***
448          * Return the number of lines
449          * @return the count of row, number of columns.
450          */
451         public final int getRowCount()
452         {
453             return this.developers.size();
454         }
455         /***
456          * Return the name of the column at the specified index
457          * @param i index
458          * @return column
459          */
460         public final String getColumnName(final int i)
461         {
462             return this.columnNames[i];
463         }
464         /***
465          * Return the class of the column at the specified index
466          * @param i index
467          * @return class
468          */
469         public final Class getColumnClass(final int i)
470         {
471             return this.columnClasses[i];
472         }
473         /***
474          * Return the size of the column at the specified index
475          * @param i index
476          * @return the size
477          */
478         public final int getColumnSize(final int i)
479         {
480             return this.columnSizes[i];
481         }
482         /***
483          * Return the value at the specified row and column
484          * @param row row index
485          * @param col column index
486          * @return the value
487          */
488         public final Object getValueAt(final int row, final int col)
489         {
490             Developer newDeveloper = (Developer) developers.elementAt(row);
491             switch (col)
492             {
493                 case 0 :
494                     return newDeveloper.getName();
495                 case 1 :
496                     return newDeveloper.getId();
497                 case 2 :
498                     return newDeveloper.getEmail();
499                 case 3 :
500                     return newDeveloper.getOrganization();
501                 case 4 :
502                     return newDeveloper.getUrl();
503                 case 5 :
504                     StringBuffer strRoles = new StringBuffer();
505                     Iterator itRoles = newDeveloper.getRoles().iterator();
506                     while (itRoles.hasNext())
507                     {
508                         strRoles.append(itRoles.next().toString());
509                         strRoles.append(";");
510                     }
511                     return strRoles;
512                 default :
513                     return null;
514             }
515         }
516         /***
517          * Set the specified value at the specified row and column
518          * @param value value
519          * @param row row index
520          * @param col column index
521          */
522         public final void setValueAt(
523             final Object value,
524             final int row,
525             final int col)
526         {
527             Developer newDeveloper = (Developer) developers.elementAt(row);
528             switch (col)
529             {
530                 case 0 :
531                     newDeveloper.setName(value.toString());
532                     break;
533                 case 1 :
534                     newDeveloper.setId(value.toString());
535                     break;
536                 case 2 :
537                     newDeveloper.setEmail(value.toString());
538                     break;
539                 case 3 :
540                     newDeveloper.setOrganization(value.toString());
541                     break;
542                 case 4 :
543                     newDeveloper.setUrl(value.toString());
544                     break;
545                 case 5 :
546                     StringTokenizer tknizer =
547                         new StringTokenizer(value.toString(), ";");
548                     while (tknizer.hasMoreTokens())
549                     {
550                         newDeveloper.addRole(tknizer.nextToken());
551                     }
552                     break;
553             }
554             // Replace the previous element
555             this.developers.setElementAt(newDeveloper, row);
556             this.fireTableDataChanged();
557             // Set the selected row for the jTableField
558             jTableDevelopers.setSelectedRow(row);
559         }
560         /***
561          * Return that every cell is editable
562          * @param row row index
563          * @param col column index
564          * @return is editable
565          */
566         public final boolean isCellEditable(final int row, final int col)
567         {
568             return true;
569         }
570     } // End of class 'EntityFieldTableModel'
571     /***
572      * Define the tooltips of the 'jTableField' header
573      */
574     private class ToolTipHeader extends JTableHeader
575     {
576         /***
577          * The tooltips
578          */
579         private String[] toolTips =
580             {
581                 " The full name of the developer.",
582                 " The username of the developer.",
583                 " The email address of the developer.",
584                 " The organization to which the developer belongs.",
585                 " The URL for the homepage of the developer",
586                 " The roles the developer plays in the project"
587                     + "\n ; separated list" };
588         /***
589         * Construct a new 'ToolTipHeader' object
590         * @param pModel the TableColumnModel
591         */
592         public ToolTipHeader(final TableColumnModel pModel)
593         {
594             super(pModel);
595         }
596         /***
597          * Return the tool tip depending on the mouse cursor position
598          * @param e the event
599          * @return the tooltip
600          */
601         public final String getToolTipText(final MouseEvent e)
602         {
603             int col = this.columnAtPoint(e.getPoint());
604             int modelCol = this.getTable().convertColumnIndexToModel(col);
605             return toolTips[modelCol];
606         }
607     }
608 }