KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > options > MacrosEditorPanel


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-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.editor.options;
21
22 import java.awt.Dialog JavaDoc;
23 import java.awt.Font JavaDoc;
24 import java.awt.FontMetrics JavaDoc;
25 import java.awt.Graphics JavaDoc;
26 import java.awt.Window JavaDoc;
27 import java.awt.event.*;
28 import java.util.*;
29 import javax.swing.*;
30 import javax.swing.event.ListSelectionEvent JavaDoc;
31 import javax.swing.event.ListSelectionListener JavaDoc;
32 import javax.swing.table.*;
33
34 import org.openide.*;
35 import org.openide.util.NbBundle;
36 import org.openide.util.HelpCtx;
37
38
39 /**
40  * Component for visual editing of Map of macroiations. When you enter new
41  * macroiation with the already used macro, it will replace the existing one.
42  * macroiations with empty expanded form are perfectly valid, but macroiations
43  * with empty macro field are simply ignored.
44  *
45  * @author David Konecny
46  */

47
48 public class MacrosEditorPanel extends javax.swing.JPanel JavaDoc {
49
50     PairStringModel model;
51
52     // The master we talk to about changes in map
53
private MacrosEditor editor;
54     
55     private FontSizeTable macrosTable;
56
57     /** Creates new form MacrosEditorPanel */
58     public MacrosEditorPanel(MacrosEditor editor) {
59         this.editor = editor;
60         model = new PairStringModel();
61         initComponents ();
62
63         macrosTable = new FontSizeTable();
64         macrosTable.setBorder(new javax.swing.border.EmptyBorder JavaDoc(new java.awt.Insets JavaDoc(8, 8, 8, 8)));
65         macrosTable.setModel(model);
66         macrosTable.setShowVerticalLines(false);
67         macrosTable.setShowHorizontalLines(false);
68         macrosTable.setSelectionMode( DefaultListSelectionModel.SINGLE_SELECTION );
69         // Set the width of columns to 30% and 70%
70
TableColumnModel col = macrosTable.getColumnModel();
71         col.getColumn( 0 ).setMaxWidth( 3000 );
72         col.getColumn( 0 ).setPreferredWidth( 30 );
73         col.getColumn( 1 ).setMaxWidth( 7000 );
74         col.getColumn( 1 ).setPreferredWidth( 70 );
75         macrosPane.setViewportView(macrosTable);
76         
77         getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_MEP")); // NOI18N
78
macrosTable.getAccessibleContext().setAccessibleName(getBundleString("ACSN_MEP_Table")); // NOI18N
79
macrosTable.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_MEP_Table")); // NOI18N
80
addButton.setMnemonic(getBundleString("MEP_Add_Mnemonic").charAt(0)); // NOI18N
81
editButton.setMnemonic(getBundleString("MEP_Edit_Mnemonic").charAt(0)); // NOI18N
82
removeButton.setMnemonic(getBundleString("MEP_Remove_Mnemonic").charAt(0)); // NOI18N
83
addButton.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_MEP_Add")); // NOI18N
84
editButton.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_MEP_Edit")); // NOI18N
85
removeButton.getAccessibleContext().setAccessibleDescription(getBundleString("ACSD_MEP_Remove")); // NOI18N
86
enableButtons(false);
87
88         macrosTable.registerKeyboardAction(new ActionListener() {
89             public void actionPerformed(ActionEvent evt) {
90                 SwingUtilities.getAncestorOfClass(Window JavaDoc.class, MacrosEditorPanel.this).setVisible(false);
91             }},
92             KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
93             JComponent.WHEN_FOCUSED
94         );
95             
96         macrosTable.getSelectionModel().addListSelectionListener(new ListSelectionListener JavaDoc() {
97             public void valueChanged(ListSelectionEvent JavaDoc e) {
98                 if (e.getValueIsAdjusting()) return;
99                 
100                 // XXX - hack because of bugparade's 4801274
101
if (macrosTable.getRowCount() == 0){
102                     enableButtons(false);
103                     return;
104                 }
105                 
106                 // valid fix of #35096
107
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
108                 enableButtons(!lsm.isSelectionEmpty());
109             }
110         });
111             
112     }
113
114     private void enableButtons(boolean enable){
115         editButton.setEnabled(enable);
116         removeButton.setEnabled(enable);
117     }
118     
119     private String JavaDoc getBundleString(String JavaDoc s) {
120         return NbBundle.getMessage(MacrosEditorPanel.class, s);
121     }
122     
123     /**
124      * Fill in editor with initial values
125      */

126     public void setValue( Map m ) {
127         HashMap hm;
128         if (m != null)
129             hm = new HashMap(m);
130         else
131             hm = new HashMap();
132         if (hm.containsKey(null)) {
133             hm.remove(null);
134         }
135         // Our model is the one and only holding data
136
model.setData( new TreeMap( hm ) );
137         // select first item, just to have something selected
138
if( model.getRowCount() > 0 ) macrosTable.setRowSelectionInterval( 0, 0 );
139     }
140
141     /**
142      * Take the result of users modifications
143      */

144     public Map getValue() {
145         return model.getData();
146     }
147
148     /**
149      * Tell the editor (and in round the system), that user've changed
150      * macros mapping.
151      */

152     private void notifyEditor() {
153         if( editor != null ) editor.customEditorChange();
154     }
155
156
157     private void initComponents() {//GEN-BEGIN:initComponents
158
java.awt.GridBagConstraints JavaDoc gridBagConstraints;
159
160         macrosPane = new javax.swing.JScrollPane JavaDoc();
161         addButton = new javax.swing.JButton JavaDoc();
162         editButton = new javax.swing.JButton JavaDoc();
163         removeButton = new javax.swing.JButton JavaDoc();
164
165         setLayout(new java.awt.GridBagLayout JavaDoc());
166
167         setBorder(new javax.swing.border.EmptyBorder JavaDoc(new java.awt.Insets JavaDoc(12, 12, 11, 11)));
168         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
169         gridBagConstraints.gridheight = 4;
170         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
171         gridBagConstraints.weightx = 1.0;
172         gridBagConstraints.weighty = 1.0;
173         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 0, 12);
174         add(macrosPane, gridBagConstraints);
175
176         addButton.setText(getBundleString( "MEP_Add" ));
177         addButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
178             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
179                 addButtonActionPerformed(evt);
180             }
181         });
182
183         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
184         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
185         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 5, 0);
186         add(addButton, gridBagConstraints);
187
188         editButton.setText(getBundleString( "MEP_Edit" ));
189         editButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
190             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
191                 editButtonActionPerformed(evt);
192             }
193         });
194
195         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
196         gridBagConstraints.gridx = 1;
197         gridBagConstraints.gridy = 1;
198         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
199         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 5, 0);
200         add(editButton, gridBagConstraints);
201
202         removeButton.setText(getBundleString( "MEP_Remove" ));
203         removeButton.addActionListener(new java.awt.event.ActionListener JavaDoc() {
204             public void actionPerformed(java.awt.event.ActionEvent JavaDoc evt) {
205                 removeButtonActionPerformed(evt);
206             }
207         });
208
209         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
210         gridBagConstraints.gridx = 1;
211         gridBagConstraints.gridy = 2;
212         gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
213         add(removeButton, gridBagConstraints);
214
215     }//GEN-END:initComponents
216

217     private void addButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_addButtonActionPerformed
218
String JavaDoc[] macro = getMacro( null );
219         // If user canceled entering, do noting
220
if( macro == null ) return;
221         int index = model.putPair( macro ); // can silently replace existing mapping
222
macrosTable.setRowSelectionInterval( index, index );
223         notifyEditor();
224     }//GEN-LAST:event_addButtonActionPerformed
225

226     private void editButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_editButtonActionPerformed
227
int index = macrosTable.getSelectedRow();
228         if( index != -1 ) { // is something selected?
229
String JavaDoc[] pair = model.getPair( index );
230             pair = getMacro( pair );
231             if( pair != null ) {
232                 model.removePair( index );
233                 index = model.putPair( pair );
234                 macrosTable.setRowSelectionInterval( index, index );
235                 notifyEditor();
236             }
237         }
238     }//GEN-LAST:event_editButtonActionPerformed
239

240     private void removeButtonActionPerformed (java.awt.event.ActionEvent JavaDoc evt) {//GEN-FIRST:event_removeButtonActionPerformed
241
int index = macrosTable.getSelectedRow();
242         if( index != -1 ) { // is something selected?
243
model.removePair( index );
244             if( index >= model.getRowCount() ) index--;
245             if( index >= 0 ) macrosTable.setRowSelectionInterval( index, index );
246             notifyEditor();
247         }
248     }//GEN-LAST:event_removeButtonActionPerformed
249

250     /**
251      * Creates a dialog asking user for pair of Strings.
252      * @param macro value to be preset in dialog, or <CODE>null</CODE>
253      * @return String[2] filled with {macro, expand}
254      * or <CODE>null</CODE> if canceled.
255      */

256     private String JavaDoc[] getMacro( String JavaDoc[] macro ) {
257         MacroInputPanel input = new MacroInputPanel();
258         // set HELP_ID of parent
259
HelpCtx.setHelpIDString( input, (HelpCtx.findHelp(this) != null ? HelpCtx.findHelp(this).getHelpID() : null) );
260         if( macro != null ) input.setMacro( macro ); // preset value
261

262         DialogDescriptor dd = new DialogDescriptor ( input, getBundleString( "MEP_EnterMacro" ) ); // NOI18N
263
Dialog JavaDoc dial = org.openide.DialogDisplayer.getDefault().createDialog(dd);
264         input.requestFocus(); // Place caret in it, hopefully
265
dial.setVisible(true); // let the user tell us their wish
266

267         if( dd.getValue() == DialogDescriptor.OK_OPTION ) {
268             String JavaDoc[] retVal = input.getMacro();
269             if( ! "".equals( retVal[0] ) ) {// NOI18N don't allow empty macro
270
int existingKeyPosition = model.containsKey(retVal[0]);
271                 
272                 if (existingKeyPosition >= 0){
273                     // ignore if user edits value and doesn't change the key
274
if ( macro!=null && macro[0].equals(retVal[0]) ) return retVal;
275                     
276                     String JavaDoc[] existingPair = model.getPair(existingKeyPosition);
277                     NotifyDescriptor NDConfirm = new NotifyDescriptor.Confirmation(
278                     NbBundle.getMessage(MacrosEditorPanel.class, "MEP_Overwrite", retVal[0] ),
279                     NotifyDescriptor.YES_NO_OPTION,
280                     NotifyDescriptor.WARNING_MESSAGE
281                     );
282                     
283                     org.openide.DialogDisplayer.getDefault().notify(NDConfirm);
284                     if (NDConfirm.getValue()!=NDConfirm.YES_OPTION){
285                         return null;
286                     }
287                 }
288                 return retVal;
289             }
290         }
291         return null; // cancel or empty
292
}
293
294
295     // Variables declaration - do not modify//GEN-BEGIN:variables
296
private javax.swing.JButton JavaDoc addButton;
297     private javax.swing.JButton JavaDoc editButton;
298     private javax.swing.JScrollPane JavaDoc macrosPane;
299     private javax.swing.JButton JavaDoc removeButton;
300     // End of variables declaration//GEN-END:variables
301

302
303     /**
304      * TableModel of sorted map of string pairs, provides additional functions
305      * for setting, getting and modifying it's content.
306      */

307     private class PairStringModel extends javax.swing.table.AbstractTableModel JavaDoc {
308
309         String JavaDoc[] columns = { getBundleString( "MEP_MacroTitle" ), // NOI18N
310
getBundleString( "MEP_ExpandTitle" ) }; // NOI18N
311

312         TreeMap data;
313         String JavaDoc[] keys;
314
315         public PairStringModel() {
316             data = new TreeMap();
317             keys = new String JavaDoc[0];
318         }
319
320         public void setData( TreeMap data ) {
321             this.data = data;
322             updateKeys();
323         }
324
325         private void updateKeys() {
326             keys = (String JavaDoc[])data.keySet().toArray( new String JavaDoc[0] );
327             fireTableDataChanged(); // we make general changes to table, invalidate whole
328
}
329
330         public TreeMap getData() {
331             return data;
332         }
333
334         public int getRowCount() {
335             return keys.length;
336         }
337
338         public int getColumnCount() {
339             return 2;
340         }
341
342         public String JavaDoc getColumnName(int column) {
343             return columns[column];
344         }
345
346         public Object JavaDoc getValueAt(int row, int column) {
347             if( column == 0 ) return keys[row];
348             else return data.get( keys[row] );
349         }
350
351         public int putPair( String JavaDoc[] pair ) {
352             data.put( pair[0], pair[1] );
353             updateKeys();
354             return Arrays.binarySearch( keys, pair[0] ); // it should always find
355
}
356
357         public void removePair( int row ) {
358             data.remove( getValueAt( row, 0 ) );
359             updateKeys();
360         }
361
362         public String JavaDoc[] getPair( int row ) {
363             String JavaDoc key = (String JavaDoc)getValueAt( row, 0 );
364             String JavaDoc[] retVal = { key, (String JavaDoc)data.get( key ) };
365             return retVal;
366         }
367         
368         public int containsKey( String JavaDoc key ){
369             return Arrays.binarySearch( keys, key );
370         }
371         
372     }
373
374      private final class FontSizeTable extends JTable{
375  
376          private boolean needCalcRowHeight = true;
377          
378          public void updateUI() {
379              super.updateUI();
380              needCalcRowHeight = true;
381          }
382          
383          public void paint(Graphics JavaDoc g) {
384              if (needCalcRowHeight) {
385                  calcRowHeight(g);
386              }
387              super.paint(g);
388          }
389          
390          /** Calculate the height of rows based on the current font. This is
391           * done when the first paint occurs, to ensure that a valid Graphics
392           * object is available.
393           */

394          private void calcRowHeight(Graphics JavaDoc g) {
395              Font JavaDoc f = getFont();
396              FontMetrics JavaDoc fm = g.getFontMetrics(f);
397              int rowHeight = fm.getHeight();
398              needCalcRowHeight = false;
399              setRowHeight(rowHeight);
400          }
401          
402      }
403     
404 }
405
Popular Tags