KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > properties > BundleEditPanel


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20
21 package org.netbeans.modules.properties;
22
23
24 import java.awt.*;
25 import java.awt.event.ActionEvent JavaDoc;
26 import java.awt.event.ActionListener JavaDoc;
27 import java.awt.event.MouseAdapter JavaDoc;
28 import java.awt.event.MouseEvent JavaDoc;
29 import java.beans.PropertyChangeEvent JavaDoc;
30 import java.beans.PropertyChangeListener JavaDoc;
31 import java.text.MessageFormat JavaDoc;
32 import javax.swing.*;
33 import javax.swing.border.LineBorder JavaDoc;
34 import javax.swing.event.*;
35 import javax.swing.plaf.BorderUIResource JavaDoc;
36 import javax.swing.plaf.BorderUIResource.BevelBorderUIResource;
37 import javax.swing.plaf.basic.BasicHTML JavaDoc;
38 import javax.swing.table.*;
39
40 import org.openide.DialogDescriptor;
41 import org.openide.NotifyDescriptor;
42 import org.openide.DialogDisplayer;
43 import org.openide.util.NbBundle;
44 import org.openide.util.WeakListeners;
45 import org.openide.windows.TopComponent;
46
47
48 /**
49  * Panel which shows bundle of .properties files encapsulated by <code>PropertiesDataObject</code> in one table view.
50  *
51  * @author Petr Jiricka
52  */

53 public class BundleEditPanel extends JPanel implements PropertyChangeListener JavaDoc {
54     
55     /** PropertiesDataObject this panel presents. */
56     private PropertiesDataObject obj;
57     
58     /** Document listener for value and comment textareas. */
59     private DocumentListener listener;
60     
61     /** Class representing settings used in table view. */
62     private static TableViewSettings settings;
63     
64     /** Generated serialized version UID. */
65     static final long serialVersionUID =-843810329041244483L;
66     
67     
68     /** Creates new form BundleEditPanel */
69     public BundleEditPanel(final PropertiesDataObject obj, PropertiesTableModel propTableModel) {
70         this.obj = obj;
71         
72         initComponents();
73         initAccessibility();
74         initSettings();
75         
76         // Sets table column model.
77
table.setColumnModel(new TableViewColumnModel());
78         
79         // Sets table model.
80
table.setModel(propTableModel);
81         
82         // Sets table cell editor.
83
JTextField textField = new JTextField();
84         // Force the document to accept newlines. The textField doesn't like
85
// it, but the same document is used by the <code>textValue</code> text
86
// area that must accept newlines.
87
textField.getDocument().putProperty("filterNewlines", Boolean.FALSE); // NOI18N
88
textField.setBorder(new LineBorder JavaDoc(Color.black));
89         textField.getAccessibleContext().setAccessibleName(NbBundle.getBundle(BundleEditPanel.class).getString("ACSN_CellEditor"));
90         textField.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACSD_CellEditor"));
91         listener = new ModifiedListener();
92         table.setDefaultEditor(PropertiesTableModel.StringPair.class,
93             new PropertiesTableCellEditor(textField, textComment, textValue, valueLabel, listener));
94         
95         // Sets renderer.
96
table.setDefaultRenderer(PropertiesTableModel.StringPair.class, new TableViewRenderer());
97         
98         updateAddButton();
99         
100         // property change listener - listens to editing state of the table
101
table.addPropertyChangeListener(new PropertyChangeListener JavaDoc() {
102             public void propertyChange(PropertyChangeEvent JavaDoc evt) {
103                 if (evt.getPropertyName().equals("tableCellEditor")) { // NOI18N
104
updateEnabled();
105                 } else if (evt.getPropertyName().equals("model")) { // NOI18N
106
updateAddButton();
107                 }
108             }
109         });
110         
111         // listens on clikcs on table header, detects column and sort accordingly to chosen one
112
table.getTableHeader().addMouseListener(new MouseAdapter JavaDoc() {
113             public void mouseClicked(MouseEvent JavaDoc e) {
114                 TableColumnModel colModel = table.getColumnModel();
115                 int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
116                 // No column was clicked.
117
if(columnModelIndex < 0)
118                     return;
119                 int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex();
120                 // not detected column
121
if (modelIndex < 0)
122                     return;
123                 obj.getBundleStructure().sort(modelIndex);
124             }
125         });
126         
127         
128         table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
129             public void valueChanged(ListSelectionEvent evt) {
130                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
131                     public void run() {
132                         updateSelection();
133                     }
134                 });
135             }
136         });
137         
138     } // End of constructor.
139

140     
141     /** Stops editing if editing is in run. */
142     protected void stopEditing() {
143         if (!table.isEditing()) return;
144         TableCellEditor cellEdit = table.getCellEditor();
145         if (cellEdit != null)
146             cellEdit.stopCellEditing();
147     }
148     
149     /** Updates the enabled status of the fields */
150     private void updateEnabled() {
151         // always edit value
152
textValue.setEditable(table.isEditing());
153         textValue.setEnabled(table.isEditing());
154         // sometimes edit the comment
155
if (table.isEditing()) {
156             PropertiesTableModel.StringPair sp = (PropertiesTableModel.StringPair)table.getCellEditor().getCellEditorValue();
157             textComment.setEditable(sp.isCommentEditable());
158             textComment.setEnabled(sp.isCommentEditable());
159         } else {
160             textComment.setEditable(false);
161             textComment.setEnabled(false);
162         }
163     }
164     
165     private void updateSelection() {
166         int row = table.getSelectedRow();
167         int column = table.getSelectedColumn();
168         BundleStructure structure = obj.getBundleStructure();
169         removeButton.setEnabled((row >= 0) && (!structure.isReadOnly()));
170         String JavaDoc value;
171         String JavaDoc comment;
172         if (column == -1) {
173             value = ""; // NOI18N
174
comment = ""; // NOI18N
175
} else if (column == 0) {
176             Element.ItemElem elem = structure.getItem(0, row);
177             value = structure.keyAt(row);
178             comment = (elem != null) ? elem.getComment() : ""; //NOI18N
179
} else {
180             Element.ItemElem elem = structure.getItem(column-1, row);
181             if (elem != null) {
182                 value = elem.getValue();
183                 comment = elem.getComment();
184             } else {
185                 value = ""; //NOI18N
186
comment = ""; //NOI18N
187
}
188         }
189         textValue.getDocument().removeDocumentListener(listener);
190         textComment.getDocument().removeDocumentListener(listener);
191         textValue.setText(value);
192         textComment.setText(comment);
193         textValue.getDocument().addDocumentListener(listener);
194         textComment.getDocument().addDocumentListener(listener);
195     }
196     
197     private void updateAddButton() {
198         addButton.setEnabled(!obj.getBundleStructure().isReadOnly());
199     }
200     
201     /** Returns the main table with all values */
202     public JTable getTable() {
203         return table;
204     }
205     
206     
207     /** Initializes <code>settings</code> variable. */
208     private void initSettings() {
209         settings = TableViewSettings.getDefault();
210                     
211         // Listen on changes of setting settings.
212
settings.addPropertyChangeListener(
213             WeakListeners.propertyChange(this, settings)
214         );
215     }
216
217     /**
218      * Handler of settings changes
219      */

220     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
221         // settings changed
222
BundleEditPanel.this.repaint();
223     }
224     
225     private void initAccessibility() {
226         this.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_BundleEditPanel"));
227         
228         table.getAccessibleContext().setAccessibleName(NbBundle.getBundle(BundleEditPanel.class).getString("ACSN_CTL_Table"));
229         table.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACSD_CTL_Table"));
230         textValue.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_CTL_TEXTVALUE"));
231         addButton.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_LBL_AddPropertyButton"));
232         textComment.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_CTL_TEXTCOMMENT"));
233         autoResizeCheck.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_CTL_AutoResize"));
234         removeButton.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(BundleEditPanel.class).getString("ACS_LBL_RemovePropertyButton"));
235     }
236     
237     public boolean requestFocusInWindow() {
238         return table.requestFocusInWindow();
239     }
240     
241     /** This method is called from within the constructor to
242      * initialize the form.
243      * WARNING: Do NOT modify this code. The content of this method is
244      * always regenerated by the FormEditor.
245      */

246     // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
247
private void initComponents() {
248         java.awt.GridBagConstraints JavaDoc gridBagConstraints;
249
250         tablePanel = new javax.swing.JPanel JavaDoc();
251         scrollPane = new javax.swing.JScrollPane JavaDoc();
252         table = new BundleTable();
253         valuePanel = new javax.swing.JPanel JavaDoc();
254         commentLabel = new javax.swing.JLabel JavaDoc();
255         jScrollPane2 = new javax.swing.JScrollPane JavaDoc();
256         textComment = new javax.swing.JTextArea JavaDoc();
257         valueLabel = new javax.swing.JLabel JavaDoc();
258         jScrollPane3 = new javax.swing.JScrollPane JavaDoc();
259         textValue = new javax.swing.JTextArea JavaDoc();
260         buttonPanel = new javax.swing.JPanel JavaDoc();
261         addButton = new javax.swing.JButton JavaDoc();
262         removeButton = new javax.swing.JButton JavaDoc();
263         autoResizeCheck = new javax.swing.JCheckBox JavaDoc();
264
265         setFocusCycleRoot(true);
266         setLayout(new java.awt.GridBagLayout JavaDoc());
267
268         tablePanel.setLayout(new java.awt.GridBagLayout JavaDoc());
269
270         table.setCellSelectionEnabled(true);
271         scrollPane.setViewportView(table);
272
273         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
274         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
275         gridBagConstraints.weightx = 1.0;
276         gridBagConstraints.weighty = 1.0;
277         gridBagConstraints.insets = new java.awt.Insets JavaDoc(12, 12, 0, 11);
278         tablePanel.add(scrollPane, gridBagConstraints);
279
280         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
281         gridBagConstraints.gridwidth = 2;
282         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
283         gridBagConstraints.weightx = 1.0;
284         gridBagConstraints.weighty = 1.0;
285         add(tablePanel, gridBagConstraints);
286
287         valuePanel.setLayout(new java.awt.GridBagLayout JavaDoc());
288
289         commentLabel.setLabelFor(textComment);
290         org.openide.awt.Mnemonics.setLocalizedText(commentLabel, NbBundle.getBundle(BundleEditPanel.class).getString("LBL_CommentLabel")); // NOI18N
291
gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
292         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
293         gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
294         gridBagConstraints.insets = new java.awt.Insets JavaDoc(11, 11, 0, 0);
295         valuePanel.add(commentLabel, gridBagConstraints);
296
297         textComment.setEditable(false);
298         textComment.setLineWrap(true);
299         textComment.setRows(3);
300         textComment.setEnabled(false);
301         jScrollPane2.setViewportView(textComment);
302
303         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
304         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
305         gridBagConstraints.weightx = 1.0;
306         gridBagConstraints.weighty = 1.0;
307         gridBagConstraints.insets = new java.awt.Insets JavaDoc(11, 11, 0, 0);
308         valuePanel.add(jScrollPane2, gridBagConstraints);
309
310         valueLabel.setLabelFor(textValue);
311         org.openide.awt.Mnemonics.setLocalizedText(valueLabel, NbBundle.getBundle(BundleEditPanel.class).getString("LBL_ValueLabel")); // NOI18N
312
gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
313         gridBagConstraints.gridx = 0;
314         gridBagConstraints.gridy = 1;
315         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
316         gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
317         gridBagConstraints.insets = new java.awt.Insets JavaDoc(11, 11, 11, 0);
318         valuePanel.add(valueLabel, gridBagConstraints);
319
320         textValue.setEditable(false);
321         textValue.setLineWrap(true);
322         textValue.setRows(3);
323         textValue.setEnabled(false);
324         jScrollPane3.setViewportView(textValue);
325
326         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
327         gridBagConstraints.gridx = 1;
328         gridBagConstraints.gridy = 1;
329         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
330         gridBagConstraints.weightx = 1.0;
331         gridBagConstraints.weighty = 1.0;
332         gridBagConstraints.insets = new java.awt.Insets JavaDoc(7, 11, 11, 0);
333         valuePanel.add(jScrollPane3, gridBagConstraints);
334
335         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
336         gridBagConstraints.gridx = 0;
337         gridBagConstraints.gridy = 1;
338         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
339         gridBagConstraints.weightx = 1.0;
340         add(valuePanel, gridBagConstraints);
341
342         buttonPanel.setLayout(new java.awt.GridBagLayout JavaDoc());
343
344         org.openide.awt.Mnemonics.setLocalizedText(addButton, NbBundle.getBundle(BundleEditPanel.class).getString("LBL_AddPropertyButton")); // NOI18N
345
addButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
346             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
347                 addButtonActionPerformed(evt);
348             }
349         });
350         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
351         gridBagConstraints.gridx = 0;
352         gridBagConstraints.gridy = 1;
353         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
354         gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
355         gridBagConstraints.weighty = 1.0;
356         gridBagConstraints.insets = new java.awt.Insets JavaDoc(11, 11, 0, 11);
357         buttonPanel.add(addButton, gridBagConstraints);
358
359         org.openide.awt.Mnemonics.setLocalizedText(removeButton, NbBundle.getBundle(BundleEditPanel.class).getString("LBL_RemovePropertyButton")); // NOI18N
360
removeButton.setEnabled(false);
361         removeButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
362             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
363                 removeButtonActionPerformed(evt);
364             }
365         });
366         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
367         gridBagConstraints.gridx = 0;
368         gridBagConstraints.gridy = 2;
369         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
370         gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
371         gridBagConstraints.insets = new java.awt.Insets JavaDoc(5, 11, 11, 11);
372         buttonPanel.add(removeButton, gridBagConstraints);
373
374         autoResizeCheck.setSelected(true);
375         org.openide.awt.Mnemonics.setLocalizedText(autoResizeCheck, NbBundle.getBundle(BundleEditPanel.class).getString("CTL_AutoResize")); // NOI18N
376
autoResizeCheck.addActionListener(new java.awt.event.ActionListener JavaDoc() {
377             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
378                 autoResizeCheckActionPerformed(evt);
379             }
380         });
381         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
382         gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
383         gridBagConstraints.insets = new java.awt.Insets JavaDoc(12, 12, 0, 11);
384         buttonPanel.add(autoResizeCheck, gridBagConstraints);
385
386         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
387         gridBagConstraints.gridx = 1;
388         gridBagConstraints.gridy = 1;
389         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
390         add(buttonPanel, gridBagConstraints);
391     }// </editor-fold>//GEN-END:initComponents
392

393     private void autoResizeCheckActionPerformed(java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_autoResizeCheckActionPerformed
394
if(autoResizeCheck.isSelected())
395             table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
396         else
397             table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
398     }//GEN-LAST:event_autoResizeCheckActionPerformed
399

400     private void removeButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_removeButtonActionPerformed
401
int selectedRow = table.getSelectedRow();
402         
403         if(selectedRow == -1)
404             return;
405         
406         stopEditing();
407         String JavaDoc key = ((PropertiesTableModel.StringPair)table.getModel().getValueAt(selectedRow, 0)).getValue();
408         
409         // Don't remove elemnt with key == null ( this is only case -> when there is an empty file with comment only)
410
if(key == null)
411             return;
412         
413         NotifyDescriptor.Confirmation msg = new NotifyDescriptor.Confirmation(
414         MessageFormat.format(
415         NbBundle.getBundle(BundleEditPanel.class).getString("MSG_DeleteKeyQuestion"),
416         new Object JavaDoc[] { key }
417         ),
418         NotifyDescriptor.OK_CANCEL_OPTION
419         );
420         
421         if (DialogDisplayer.getDefault().notify(msg).equals(NotifyDescriptor.OK_OPTION)) {
422             try {
423                 // Starts "atomic" acion for special undo redo manager of open support.
424
obj.getOpenSupport().atomicUndoRedoFlag = new Object JavaDoc();
425                 
426                 for (int i=0; i < obj.getBundleStructure().getEntryCount(); i++) {
427                     PropertiesFileEntry entry = obj.getBundleStructure().getNthEntry(i);
428                     if (entry != null) {
429                         PropertiesStructure ps = entry.getHandler().getStructure();
430                         if (ps != null) {
431                             ps.deleteItem(key);
432                         }
433                     }
434                 }
435             } finally {
436                 // finishes "atomic" undo redo action for special undo redo manager of open support
437
obj.getOpenSupport().atomicUndoRedoFlag = null;
438             }
439         }
440     }//GEN-LAST:event_removeButtonActionPerformed
441

442     private void addButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_addButtonActionPerformed
443
stopEditing();
444         
445         final Dialog[] dialog = new Dialog[1];
446         final Element.ItemElem item = new Element.ItemElem(
447         null,
448         new Element.KeyElem(null, ""), // NOI18N
449
new Element.ValueElem(null, ""), // NOI18N
450
new Element.CommentElem(null, "") // NOI18N
451
);
452         final JPanel panel = new PropertyPanel(item);
453         
454         DialogDescriptor dd = new DialogDescriptor(
455         panel,
456         NbBundle.getBundle(BundleEditPanel.class).getString("CTL_NewPropertyTitle"),
457         true,
458         DialogDescriptor.OK_CANCEL_OPTION,
459         DialogDescriptor.OK_OPTION,
460         new ActionListener JavaDoc() {
461             public void actionPerformed(ActionEvent JavaDoc evt2) {
462                 // OK pressed
463
if(evt2.getSource() == DialogDescriptor.OK_OPTION) {
464                     dialog[0].setVisible(false);
465                     dialog[0].dispose();
466                     
467                     final String JavaDoc key = item.getKey();
468                     String JavaDoc value = item.getValue();
469                     String JavaDoc comment = item.getComment();
470                     
471                     boolean keyAdded = false;
472                     
473                     try {
474                         // Starts "atomic" acion for special undo redo manager of open support.
475
obj.getOpenSupport().atomicUndoRedoFlag = new Object JavaDoc();
476                         
477                         // add key to all entries
478
for (int i=0; i < obj.getBundleStructure().getEntryCount(); i++) {
479                             PropertiesFileEntry entry = obj.getBundleStructure().getNthEntry(i);
480                             
481                             if (entry != null && !entry.getHandler().getStructure().addItem(key, value, comment)) {
482                                 NotifyDescriptor.Message msg = new NotifyDescriptor.Message(
483                                 MessageFormat.format(
484                                 NbBundle.getBundle(BundleEditPanel.class).getString("MSG_KeyExists"),
485                                 new Object JavaDoc[] {
486                                     item.getKey(),
487                                     Util.getLocaleLabel(entry)
488                                 }
489                                 ),
490                                 NotifyDescriptor.ERROR_MESSAGE);
491                                 DialogDisplayer.getDefault().notify(msg);
492                             } else {
493                                 keyAdded = true;
494                             }
495                         }
496                     } finally {
497                         // Finishes "atomic" undo redo action for special undo redo manager of open support.
498
obj.getOpenSupport().atomicUndoRedoFlag = null;
499                     }
500                     
501                     if(keyAdded) {
502                         // Item was added succesfully, go to edit it.
503
// PENDING: this is in request processor queue only
504
// due to reason that properties structure has just after
505
// adding new item inconsistence gap until it's reparsed anew.
506
// This should be removed when the parsing will be redsigned.
507
PropertiesRequestProcessor.getInstance().post(new Runnable JavaDoc() {
508                             public void run() {
509                                 // Find indexes.
510
int rowIndex = obj.getBundleStructure().getKeyIndexByName(key);
511                                 
512                                 if((rowIndex != -1)) {
513                                     final int row = rowIndex;
514                                     final int column = 1; // Default locale.
515

516                                     SwingUtilities.invokeLater(new Runnable JavaDoc() {
517                                         public void run() {
518                                             // Autoscroll to cell if possible and necessary.
519
if(table.getAutoscrolls()) {
520                                                 Rectangle cellRect = table.getCellRect(row, column, false);
521                                                 if (cellRect != null) {
522                                                     table.scrollRectToVisible(cellRect);
523                                                 }
524                                             }
525                                             
526                                             // Update selection & edit.
527
table.getColumnModel().getSelectionModel().setSelectionInterval(column, column);
528                                             table.getSelectionModel().setSelectionInterval(row, row);
529                                             
530                                             table.requestFocusInWindow();
531                                             table.editCellAt(row, column);
532                                         }
533                                     });
534                                 }
535                             }
536                         });
537                     }
538                     
539                     // Cancel pressed
540
} else if (evt2.getSource() == DialogDescriptor.CANCEL_OPTION) {
541                     dialog[0].setVisible(false);
542                     dialog[0].dispose();
543                 }
544             }
545         }
546         );
547         
548         dialog[0] = DialogDisplayer.getDefault().createDialog(dd);
549         dialog[0].setVisible(true);
550     }//GEN-LAST:event_addButtonActionPerformed
551

552     
553     // Variables declaration - do not modify//GEN-BEGIN:variables
554
private javax.swing.JButton JavaDoc addButton;
555     private javax.swing.JCheckBox JavaDoc autoResizeCheck;
556     private javax.swing.JPanel JavaDoc buttonPanel;
557     private javax.swing.JLabel JavaDoc commentLabel;
558     private javax.swing.JScrollPane JavaDoc jScrollPane2;
559     private javax.swing.JScrollPane JavaDoc jScrollPane3;
560     private javax.swing.JButton JavaDoc removeButton;
561     private javax.swing.JScrollPane JavaDoc scrollPane;
562     private javax.swing.JTable JavaDoc table;
563     private javax.swing.JPanel JavaDoc tablePanel;
564     private javax.swing.JTextArea JavaDoc textComment;
565     private javax.swing.JTextArea JavaDoc textValue;
566     private javax.swing.JLabel JavaDoc valueLabel;
567     private javax.swing.JPanel JavaDoc valuePanel;
568     // End of variables declaration//GEN-END:variables
569

570     
571     /** Header renderer used in table view. */
572     private class TableViewHeaderRenderer extends DefaultTableCellRenderer {
573         /** Sorted column. */
574         private int column;
575         
576         /** Overrides superclass method. */
577         public Component getTableCellRendererComponent(JTable table, Object JavaDoc value,
578         boolean isSelected, boolean hasFocus, int row, int column) {
579             
580             this.column = column;
581             
582             if (table != null) {
583                 JTableHeader header = table.getTableHeader();
584                 if (header != null) {
585                     this.setForeground(header.getForeground());
586                     this.setBackground(header.getBackground());
587                     this.setFont(header.getFont());
588                 }
589             }
590             
591             setText((value == null) ? "" : value.toString()); // NOI18N
592
this.setBorder(UIManager.getBorder("TableHeader.cellBorder")); // NOI18N
593
return this;
594         }
595         
596         /** Overrides superclass method. Adds painting ascending/descending marks for sorted column header. */
597         protected void paintComponent(Graphics g) {
598             super.paintComponent(g);
599             
600             int sortIndex = table.convertColumnIndexToView(obj.getBundleStructure().getSortIndex());
601             
602             // If the column is the sorted one draw mark on its header.
603
if(column == sortIndex ) {
604                 
605                 Color oldColor = g.getColor();
606                 
607                 FontMetrics fm = g.getFontMetrics();
608                 Rectangle space = fm.getStringBounds(" ", g).getBounds(); // NOI18N
609
Rectangle mark = fm.getStringBounds("\u25B2", g).getBounds(); // NOI18N
610
Rectangle bounds = this.getBounds();
611                 
612                 Insets insets = this.getInsets();
613                 
614                 BevelBorderUIResource bevelUI = (BevelBorderUIResource)BorderUIResource.getLoweredBevelBorderUIResource();
615                 
616                 boolean ascending = obj.getBundleStructure().getSortOrder();
617                 
618                 int x1, x2, x3, y1, y2, y3;
619                 
620                 if(ascending) {
621                     // Ascending order.
622
x1 = space.width + mark.width/2;
623                     x2 = space.width;
624                     x3 = space.width + mark.width;
625                     
626                     y1 = bounds.y + insets.top+2;
627                     y2 = bounds.y + bounds.height - insets.bottom-2;
628                     y3 = y2;
629                 } else {
630                     // Descending order.
631
x1 = space.width;
632                     x2 = space.width + mark.width;
633                     x3 = space.width + mark.width/2;
634                     
635                     y1 = bounds.y + insets.top + 2;
636                     y2 = y1;
637                     y3 = bounds.y + bounds.height - insets.bottom - 2;
638                 }
639                 
640                 // Draw bevel border.
641
// Draw shadow outer color.
642
g.setColor(bevelUI.getShadowOuterColor(this));
643                 if(ascending)
644                     g.drawLine(x1, y1, x2, y2);
645                 else
646                     g.drawPolyline(new int[] {x2, x1, x3}, new int[] {y2, y1, y3}, 3);
647                     
648                     // Draw shadow inner color.
649
g.setColor(bevelUI.getShadowInnerColor(this));
650                     if(ascending)
651                         g.drawLine(x1, y1+1, x2+1, y2-1);
652                     else
653                         g.drawPolyline(new int[] {x2-1, x1+1, x3}, new int[] {y2+1, y1+1, y3-1}, 3);
654                         
655                         // Draw highlihght outer color.
656
g.setColor(bevelUI.getHighlightOuterColor(this));
657                         if(ascending)
658                             g.drawPolyline(new int[] {x1, x3, x2}, new int[] {y1, y3, y2}, 3);
659                         else
660                             g.drawLine(x2, y2, x3, y3);
661                         
662                         // Draw highlight inner color.
663
g.setColor(bevelUI.getHighlightInnerColor(this));
664                         if(ascending)
665                             g.drawPolyline(new int[] {x1, x3-1, x2+1}, new int[] {y1+1, y3-1, y2-1}, 3);
666                         else
667                             g.drawLine(x2-1, y2+1, x3, y3-1);
668                         
669                         g.setColor(oldColor);
670             }
671         }
672     } // End of inner class TableViewHeaderRenderer.
673

674     
675     /**
676      * This subclass of Default column model is provided due correct set of column widths,
677      * see the JTable and horizontal scrolling problem in Java Discussion Forum.
678      */

679     private class TableViewColumnModel extends DefaultTableColumnModel {
680         /** Helper listener. */
681         private AncestorListener ancestorListener;
682         
683         /** Table header rendrer. */
684         private final TableCellRenderer headerRenderer = new TableViewHeaderRenderer();
685         
686         /** Overrides superclass method. */
687         public void addColumn(TableColumn aColumn) {
688             if (aColumn == null) {
689                 throw new IllegalArgumentException JavaDoc("Object is null"); // NOI18N
690
}
691             
692             tableColumns.addElement(aColumn);
693             aColumn.addPropertyChangeListener(this);
694             
695             // this method call is only difference with overriden superclass method
696
adjustColumnWidths();
697             
698             // set header renderer this 'ugly' way (for each column),
699
// in jdk1.2 is not possible to set default renderer
700
// for JTableHeader like in jdk1.3
701
aColumn.setHeaderRenderer(headerRenderer);
702             
703             // Post columnAdded event notification
704
fireColumnAdded(new TableColumnModelEvent(this, 0,
705             getColumnCount() - 1));
706         }
707         
708         /** Helper method adjusting the table according top component or mode which contains it, the
709          * minimal width of column is 1/10 of screen width. */

710         private void adjustColumnWidths() {
711             // The least initial width of column (1/10 of screen witdh).
712
Rectangle screenBounds = org.openide.util.Utilities.getUsableScreenBounds();
713             int columnWidth = screenBounds.width / 10;
714             
715             // Try to set widths according parent (viewport) width.
716
int totalWidth = 0;
717             TopComponent tc = (TopComponent)SwingUtilities.getAncestorOfClass(TopComponent.class, table);
718             if(tc != null) {
719                 totalWidth = tc.getBounds().width;
720             } else {
721                 if(ancestorListener == null) {
722                     table.addAncestorListener(ancestorListener = new AncestorListener() {
723                         /** If the ancestor is TopComponent adjustColumnWidths. */
724                         public void ancestorAdded(AncestorEvent evt) {
725                             if(evt.getAncestor() instanceof TopComponent) {
726                                 adjustColumnWidths();
727                                 table.removeAncestorListener(ancestorListener);
728                                 ancestorListener = null;
729                             }
730                         }
731                         
732                         /** Does nothing. */
733                         public void ancestorMoved(AncestorEvent evt) {
734                         }
735                         
736                         /** Does nothing. */
737                         public void ancestorRemoved(AncestorEvent evt) {
738                         }
739                     });
740                 }
741             }
742             
743             // Decrease of insets of scrollpane and insets set in layout manager.
744
// Note: Layout constraints hardcoded instead of getting via method call ->
745
// keep consistent with numbers in initComponents method.
746
totalWidth -= scrollPane.getInsets().left + scrollPane.getInsets().right + 12 + 11;
747             
748             // Helper variable for keeping additional pixels which remains after division.
749
int remainder = 0;
750             
751             // If calculations were succesful try to set the widths in case calculated width
752
// for one column is not less than 1/10 of screen width.
753
if(totalWidth > 0) {
754                 int computedColumnWidth = totalWidth / table.getColumnCount();
755                 if(computedColumnWidth > columnWidth) {
756                     columnWidth = computedColumnWidth - table.getColumnModel().getColumnMargin();
757                     remainder = totalWidth % table.getColumnCount();
758                 }
759             }
760             
761             // Set the column widths.
762
for (int i = 0; i < table.getColumnCount(); i++) {
763                 TableColumn column = table.getColumnModel().getColumn(i);
764                 
765                 // Add remainder to first column.
766
if(i==0) {
767                     // It is necessary to set both 'widths', see javax.swing.TableColumn.
768
column.setPreferredWidth(columnWidth + remainder);
769                     column.setWidth(columnWidth + remainder);
770                 } else {
771                     // It is necessary to set both 'widths', see javax.swing.TableColumn.
772
column.setPreferredWidth(columnWidth);
773                     column.setWidth(columnWidth);
774                 }
775             }
776             
777             // Recalculate total column width.
778
recalcWidthCache();
779             
780             // Revalidate table so the widths will fit properly.
781
table.revalidate();
782             
783             // Repaint header afterwards. Seems stupid but necessary.
784
table.getTableHeader().repaint();
785         }
786     } // End of inner class TableViewColumnModel.
787

788     
789     /** Renderer which renders cells in table view. */
790     private class TableViewRenderer extends DefaultTableCellRenderer {
791         /** Overrides superclass method. */
792         public Component getTableCellRendererComponent(JTable table,
793         Object JavaDoc value, boolean isSelected, boolean hasFocus, int row, int column) {
794             
795             if(value==null) return this;
796             
797             PropertiesTableModel.StringPair sp = (PropertiesTableModel.StringPair)value;
798             
799             setFont(settings.getFont());
800             
801             if(hasFocus) {
802                 setBorder(UIManager.getBorder("Table.focusCellHighlightBorder") ); // NOI18N
803
} else {
804                 setBorder(noFocusBorder);
805             }
806             
807             String JavaDoc text = null;
808             
809             if(sp.getValue() != null) {
810                 text = sp.getValue();
811             }
812             
813             // XXX Ugly hack to prevent problems showing 'html-ed' labels.
814
if(BasicHTML.isHTMLString(text)) { // NOI18N
815
text = " " + text; // NOI18N
816
}
817             
818             setValue(text == null ? "" : text); // NOI18N
819

820             // Set background color.
821
if(sp.isKeyType())
822                 setBackground(settings.getKeyBackground());
823             else {
824                 if( sp.getValue() != null)
825                     setBackground(settings.getValueBackground());
826                 else
827                     setBackground(settings.getShadowColor());
828             }
829             
830             // Set foregound color.
831
if(sp.isKeyType())
832                 setForeground(settings.getKeyColor());
833             else
834                 setForeground(settings.getValueColor());
835             
836             // Optimization to avoid painting background if is the same like table's.
837
Color back = getBackground();
838             boolean colorMatch = (back != null) && (back.equals(table.getBackground()) ) && table.isOpaque();
839             setOpaque(!colorMatch);
840             
841             return this;
842         }
843         
844         /** Overrides superclass method. It adds the highlighting of search occurences in it. */
845         protected void paintComponent(Graphics g) {
846             super.paintComponent(g);
847             
848             // If there is a highlihgt flag set do additional drawings.
849
if(FindPerformer.getFindPerformer(BundleEditPanel.this.table).isHighlightSearch()) {
850                 String JavaDoc text = getText();
851                 String JavaDoc findString = FindPerformer.getFindPerformer(BundleEditPanel.this.table).getFindString();
852                 
853                 // If there is a findString and the cell could contain it go ahead.
854
if(text != null && text.length()>0 && findString != null && findString.length()>0) {
855                     int index = 0;
856                     int width = (int)g.getFontMetrics().getStringBounds(findString, g).getWidth();
857                     
858                     Color oldColor = g.getColor();
859                     // In each iteration highlight one occurence of findString in this cell.
860
while((index = text.indexOf(findString, index)) >= 0) {
861                         
862                         int x = (int)g.getFontMetrics().getStringBounds(text.substring(0, index), g).getWidth()+this.getInsets().left;
863                         
864                         g.setColor(settings.getHighlightBackground());
865                         g.fillRect(x, 0, width, g.getClipBounds().height);
866                         
867                         g.setColor(settings.getHighlightColor());
868                         g.drawString(findString, x, -(int)g.getFontMetrics().getStringBounds(findString, g).getY());
869                         
870                         index += findString.length();
871                     }
872                     // Reset original color.
873
g.setColor(oldColor);
874                 }
875             }
876         }
877     } // End of inner class TableViewRenderer.
878

879     
880     
881     /** <code>JTable</code> with one bug fix.
882      * @see #removeEditorSilent */

883     static class BundleTable extends JTable {
884         
885         public BundleTable(){
886             super();
887             this.setRowHeight(getCellFontHeight() + 1);
888         }
889         
890         /**
891          * The same like superclass removeEditor except it doesn't request focus back to table.
892          * We need this kind of behaviour (see bug in IssueaZilla #9237). The table shoudl request focus
893          * after canceling editing when is showing only (submit bug to jdk ?).
894          * @see javax.swing.JTable#removeEditor */

895         public void removeEditorSilent() {
896             TableCellEditor editor = getCellEditor();
897             if(editor != null) {
898                 editor.removeCellEditorListener(this);
899                 
900                 // requestFocus();
901
if (editorComp != null) {
902                     remove(editorComp);
903                 }
904                 
905                 Rectangle cellRect = getCellRect(editingRow, editingColumn, false);
906                 
907                 setCellEditor(null);
908                 setEditingColumn(-1);
909                 setEditingRow(-1);
910                 editorComp = null;
911                 
912                 repaint(cellRect);
913             }
914         }
915         
916         private int getCellFontHeight() {
917             Font cellFont = UIManager.getFont("TextField.font");
918             if (cellFont != null) {
919                 FontMetrics fm = getFontMetrics(cellFont);
920                 if (fm != null) {
921                     return fm.getHeight();
922                 }
923             }
924             return 14;
925         }
926         
927     } // End of BundleTable class.
928

929     private class ModifiedListener implements DocumentListener {
930         
931         public void changedUpdate(DocumentEvent e) {
932             documentModified();
933         }
934         
935         public void insertUpdate(DocumentEvent e) {
936             documentModified();
937         }
938         
939         public void removeUpdate(DocumentEvent e) {
940             documentModified();
941         }
942         
943         private void documentModified() {
944             obj.setModified(true);
945         }
946         
947     }
948     
949 }
950
Popular Tags