001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.tasklist.todo.settings;
043:
044: import java.awt.Component;
045: import java.util.ArrayList;
046: import java.util.Collection;
047: import javax.swing.JTable;
048: import javax.swing.ListSelectionModel;
049: import javax.swing.SwingUtilities;
050: import javax.swing.event.CellEditorListener;
051: import javax.swing.event.ChangeEvent;
052: import javax.swing.event.ListSelectionEvent;
053: import javax.swing.event.ListSelectionListener;
054: import javax.swing.table.DefaultTableModel;
055: import javax.swing.table.TableCellEditor;
056: import javax.swing.text.JTextComponent;
057: import org.netbeans.spi.options.OptionsPanelController;
058: import org.openide.util.NbBundle;
059:
060: /**
061: *
062: * @author S. Aubrecht
063: */
064: class ToDoCustomizer extends javax.swing.JPanel {
065:
066: private boolean changed = false;
067: private boolean isUpdating = false;
068:
069: /** Creates new form ToDoCustomizer */
070: public ToDoCustomizer() {
071: initComponents();
072: table.getSelectionModel().setSelectionMode(
073: ListSelectionModel.SINGLE_SELECTION);
074: table.getSelectionModel().addListSelectionListener(
075: new ListSelectionListener() {
076: public void valueChanged(ListSelectionEvent e) {
077: enableButtons();
078: }
079: });
080: jScrollPane1.getViewport().setOpaque(false);
081: enableButtons();
082: }
083:
084: private void enableButtons() {
085: int selIndex = table.getSelectedRow();
086: btnChange.setEnabled(selIndex >= 0);
087: btnRemove.setEnabled(selIndex >= 0);
088: }
089:
090: void update() {
091: isUpdating = true;
092: Collection<String> patterns = Settings.getDefault()
093: .getPatterns();
094: table.setModel(createModel(patterns));
095: table.setTableHeader(null);
096: checkScanCommentsOnly.setSelected(Settings.getDefault()
097: .isScanCommentsOnly());
098: changed = false;
099: isUpdating = false;
100: }
101:
102: void applyChanges() {
103: DefaultTableModel model = (DefaultTableModel) table.getModel();
104: ArrayList<String> patterns = new ArrayList<String>(model
105: .getRowCount());
106: for (int i = 0; i < model.getRowCount(); i++) {
107: patterns.add(model.getValueAt(i, 0).toString());
108: }
109: Settings.getDefault().setPatterns(patterns);
110: Settings.getDefault().setScanCommentsOnly(
111: checkScanCommentsOnly.isSelected());
112: }
113:
114: boolean isDataValid() {
115: return table.getRowCount() > 0;
116: }
117:
118: boolean isChanged() {
119: return changed;
120: }
121:
122: private DefaultTableModel createModel(Collection<String> patterns) {
123: DefaultTableModel model = new DefaultTableModel(
124: new Object[] { NbBundle.getMessage(
125: ToDoCustomizer.class,
126: "ToDoCustomizer.TableHeader") }, patterns
127: .size()); //NOI18N
128: int row = 0;
129: for (String p : patterns) {
130: model.setValueAt(p, row++, 0);
131: }
132: return model;
133: }
134:
135: /** This method is called from within the constructor to
136: * initialize the form.
137: * WARNING: Do NOT modify this code. The content of this method is
138: * always regenerated by the Form Editor.
139: */
140: // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
141: private void initComponents() {
142:
143: btnAdd = new javax.swing.JButton();
144: btnChange = new javax.swing.JButton();
145: jScrollPane1 = new javax.swing.JScrollPane();
146: table = new MyTable();
147: checkScanCommentsOnly = new javax.swing.JCheckBox();
148: jLabel1 = new javax.swing.JLabel();
149: btnRemove = new javax.swing.JButton();
150:
151: org.openide.awt.Mnemonics.setLocalizedText(btnAdd,
152: org.openide.util.NbBundle.getMessage(
153: ToDoCustomizer.class,
154: "ToDoCustomizer.btnAdd.text")); // NOI18N
155: btnAdd.addActionListener(new java.awt.event.ActionListener() {
156: public void actionPerformed(java.awt.event.ActionEvent evt) {
157: btnAddActionPerformed(evt);
158: }
159: });
160:
161: org.openide.awt.Mnemonics.setLocalizedText(btnChange,
162: org.openide.util.NbBundle.getMessage(
163: ToDoCustomizer.class,
164: "ToDoCustomizer.btnChange.text")); // NOI18N
165: btnChange
166: .addActionListener(new java.awt.event.ActionListener() {
167: public void actionPerformed(
168: java.awt.event.ActionEvent evt) {
169: btnChangeActionPerformed(evt);
170: }
171: });
172:
173: jScrollPane1.setOpaque(false);
174:
175: table.setModel(new javax.swing.table.DefaultTableModel(
176: new Object[][] { { null, null, null, null },
177: { null, null, null, null },
178: { null, null, null, null },
179: { null, null, null, null } }, new String[] {
180: "Title 1", "Title 2", "Title 3", "Title 4" }));
181: table.setOpaque(false);
182: table.setTableHeader(null);
183: jScrollPane1.setViewportView(table);
184:
185: org.openide.awt.Mnemonics.setLocalizedText(
186: checkScanCommentsOnly,
187: org.openide.util.NbBundle.getMessage(
188: ToDoCustomizer.class,
189: "ToDoCustomizer.checkScanCommentsOnly.text")); // NOI18N
190: checkScanCommentsOnly.setBorder(javax.swing.BorderFactory
191: .createEmptyBorder(0, 0, 0, 0));
192: checkScanCommentsOnly
193: .setMargin(new java.awt.Insets(0, 0, 0, 0));
194: checkScanCommentsOnly.setOpaque(false);
195: checkScanCommentsOnly
196: .addChangeListener(new javax.swing.event.ChangeListener() {
197: public void stateChanged(
198: javax.swing.event.ChangeEvent evt) {
199: checkScanCommentsOnlyStateChanged(evt);
200: }
201: });
202:
203: jLabel1.setLabelFor(table);
204: org.openide.awt.Mnemonics.setLocalizedText(jLabel1,
205: org.openide.util.NbBundle.getMessage(
206: ToDoCustomizer.class,
207: "ToDoCustomizer.TableHeader")); // NOI18N
208:
209: org.openide.awt.Mnemonics.setLocalizedText(btnRemove,
210: org.openide.util.NbBundle.getMessage(
211: ToDoCustomizer.class,
212: "ToDoCustomizer.btnRemove.text")); // NOI18N
213: btnRemove
214: .addActionListener(new java.awt.event.ActionListener() {
215: public void actionPerformed(
216: java.awt.event.ActionEvent evt) {
217: btnRemoveActionPerformed(evt);
218: }
219: });
220:
221: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
222: this );
223: this .setLayout(layout);
224: layout
225: .setHorizontalGroup(layout
226: .createParallelGroup(
227: org.jdesktop.layout.GroupLayout.LEADING)
228: .add(
229: layout
230: .createSequentialGroup()
231: .add(
232: jScrollPane1,
233: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
234: 257, Short.MAX_VALUE)
235: .addPreferredGap(
236: org.jdesktop.layout.LayoutStyle.RELATED)
237: .add(
238: layout
239: .createParallelGroup(
240: org.jdesktop.layout.GroupLayout.TRAILING,
241: false)
242: .add(
243: btnAdd,
244: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
245: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
246: Short.MAX_VALUE)
247: .add(
248: btnChange,
249: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
250: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
251: Short.MAX_VALUE)
252: .add(
253: btnRemove,
254: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
255: 81,
256: Short.MAX_VALUE)))
257: .add(jLabel1).add(checkScanCommentsOnly));
258: layout
259: .setVerticalGroup(layout
260: .createParallelGroup(
261: org.jdesktop.layout.GroupLayout.LEADING)
262: .add(
263: layout
264: .createSequentialGroup()
265: .add(jLabel1)
266: .addPreferredGap(
267: org.jdesktop.layout.LayoutStyle.RELATED)
268: .add(
269: layout
270: .createParallelGroup(
271: org.jdesktop.layout.GroupLayout.LEADING)
272: .add(
273: layout
274: .createSequentialGroup()
275: .add(
276: btnAdd)
277: .addPreferredGap(
278: org.jdesktop.layout.LayoutStyle.RELATED)
279: .add(
280: btnChange)
281: .addPreferredGap(
282: org.jdesktop.layout.LayoutStyle.RELATED)
283: .add(
284: btnRemove))
285: .add(
286: jScrollPane1,
287: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
288: 171,
289: Short.MAX_VALUE))
290: .addPreferredGap(
291: org.jdesktop.layout.LayoutStyle.RELATED)
292: .add(checkScanCommentsOnly)));
293: }// </editor-fold>//GEN-END:initComponents
294:
295: private void checkScanCommentsOnlyStateChanged(
296: javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_checkScanCommentsOnlyStateChanged
297: if (isUpdating)
298: return;
299: boolean wasChanged = changed;
300: changed = true;
301: firePropertyChange(OptionsPanelController.PROP_CHANGED,
302: new Boolean(wasChanged), Boolean.TRUE);
303:
304: }//GEN-LAST:event_checkScanCommentsOnlyStateChanged
305:
306: private void btnRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveActionPerformed
307: TableCellEditor editor = table.getCellEditor();
308: if (null != editor)
309: editor.cancelCellEditing();
310:
311: boolean wasValid = isDataValid();
312:
313: int selRow = table.getSelectedRow();
314: if (selRow < 0)
315: return;
316: DefaultTableModel model = (DefaultTableModel) table.getModel();
317: model.removeRow(selRow);
318: if (selRow > model.getRowCount() - 1)
319: selRow--;
320: if (selRow >= 0)
321: table.getSelectionModel().setSelectionInterval(selRow,
322: selRow);
323:
324: boolean wasChanged = changed;
325: changed = true;
326: firePropertyChange(OptionsPanelController.PROP_CHANGED,
327: new Boolean(wasChanged), Boolean.TRUE);
328:
329: firePropertyChange(OptionsPanelController.PROP_VALID,
330: new Boolean(wasValid), new Boolean(isDataValid()));
331: }//GEN-LAST:event_btnRemoveActionPerformed
332:
333: private void btnChangeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnChangeActionPerformed
334: int selRow = table.getSelectedRow();
335: if (selRow < 0)
336: return;
337: final boolean wasChanged = changed;
338: table.editCellAt(selRow, 0);
339: final TableCellEditor editor = table.getCellEditor();
340: editor.addCellEditorListener(new CellEditorListener() {
341: public void editingStopped(ChangeEvent e) {
342: editor.removeCellEditorListener(this );
343: changed = true;
344: firePropertyChange(OptionsPanelController.PROP_CHANGED,
345: new Boolean(wasChanged), Boolean.TRUE);
346: }
347:
348: public void editingCanceled(ChangeEvent e) {
349: editor.removeCellEditorListener(this );
350: }
351: });
352: }//GEN-LAST:event_btnChangeActionPerformed
353:
354: private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddActionPerformed
355: DefaultTableModel model = (DefaultTableModel) table.getModel();
356: model
357: .addRow(new Object[] { NbBundle.getMessage(
358: ToDoCustomizer.class,
359: "ToDoCustomizer.DefaultPattern") }); //NOI18N
360: table.getSelectionModel().setSelectionInterval(
361: model.getRowCount() - 1, model.getRowCount() - 1);
362: final boolean wasChanged = changed;
363: table.editCellAt(model.getRowCount() - 1, 0);
364: final TableCellEditor editor = table.getCellEditor();
365: editor.addCellEditorListener(new CellEditorListener() {
366: public void editingStopped(ChangeEvent e) {
367: editor.removeCellEditorListener(this );
368: changed = true;
369: firePropertyChange(OptionsPanelController.PROP_CHANGED,
370: new Boolean(wasChanged), Boolean.TRUE);
371: }
372:
373: public void editingCanceled(ChangeEvent e) {
374: editor.removeCellEditorListener(this );
375: }
376: });
377: }//GEN-LAST:event_btnAddActionPerformed
378:
379: // Variables declaration - do not modify//GEN-BEGIN:variables
380: private javax.swing.JButton btnAdd;
381: private javax.swing.JButton btnChange;
382: private javax.swing.JButton btnRemove;
383: private javax.swing.JCheckBox checkScanCommentsOnly;
384: private javax.swing.JLabel jLabel1;
385: private javax.swing.JScrollPane jScrollPane1;
386: private javax.swing.JTable table;
387:
388: // End of variables declaration//GEN-END:variables
389:
390: private static class MyTable extends JTable {
391:
392: @Override
393: public Component prepareEditor(TableCellEditor editor, int row,
394: int column) {
395: Component res = super .prepareEditor(editor, row, column);
396: if (res instanceof JTextComponent) {
397: final JTextComponent txt = (JTextComponent) res;
398: SwingUtilities.invokeLater(new Runnable() {
399: public void run() {
400: txt.selectAll();
401: txt.requestFocusInWindow();
402: }
403: });
404: }
405: return res;
406: }
407:
408: }
409: }
|