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.options.indentation;
043:
044: import java.awt.Component;
045: import java.awt.event.ActionEvent;
046: import java.awt.event.ActionListener;
047: import java.io.BufferedReader;
048: import java.io.IOException;
049: import java.io.InputStream;
050: import java.io.InputStreamReader;
051: import javax.swing.AbstractButton;
052: import javax.swing.JLabel;
053: import javax.swing.JPanel;
054: import javax.swing.SpinnerNumberModel;
055: import javax.swing.SwingUtilities;
056: import javax.swing.border.EtchedBorder;
057: import javax.swing.event.ChangeEvent;
058: import javax.swing.event.ChangeListener;
059: import javax.swing.text.BadLocationException;
060: import javax.swing.text.Document;
061: import org.netbeans.editor.BaseDocument;
062: import org.netbeans.editor.Formatter;
063: import org.netbeans.spi.options.OptionsPanelController;
064: import org.openide.awt.Mnemonics;
065: import org.openide.util.NbBundle;
066:
067: /**
068: * Implementation of one panel in Options Dialog.
069: *
070: * @author Jan Jancura
071: */
072: public class IndentationPanel extends JPanel implements ChangeListener,
073: ActionListener {
074:
075: private IndentationModel model;
076: private String originalText;
077: private boolean listen = false;
078: private boolean changed = false;
079:
080: /**
081: * Creates new form IndentationPanel.
082: */
083: public IndentationPanel() {
084: initComponents();
085:
086: // localization
087: setName(loc("Indentation_Tab")); //NOI18N
088: loc(lNumberOfSpacesPerIndent, "Indent"); //NOI18N
089: loc(lTabSize, "TabSize"); //NOI18N
090: loc(lPreview, "Preview"); //NOI18N
091: loc(lExpandTabsToSpaces, "Expand_Tabs"); //NOI18N
092: loc(lRightMargin, "Right_Margin"); //NOI18N
093: cbExpandTabsToSpaces.getAccessibleContext().setAccessibleName(
094: loc("AN_Expand_Tabs")); //NOI18N
095: cbExpandTabsToSpaces.getAccessibleContext()
096: .setAccessibleDescription(loc("AD_Expand_Tabs")); //NOI18N
097: epPreview.getAccessibleContext().setAccessibleName(
098: loc("AN_Preview")); //NOI18N
099: epPreview.getAccessibleContext().setAccessibleDescription(
100: loc("AD_Preview")); //NOI18N
101:
102: //listeners
103: epPreview.setBorder(new EtchedBorder());
104: cbExpandTabsToSpaces.addActionListener(this );
105: sNumberOfSpacesPerIndent.setModel(new SpinnerNumberModel(4, 1,
106: 50, 1));
107: sNumberOfSpacesPerIndent.addChangeListener(this );
108: sTabSize.setModel(new SpinnerNumberModel(4, 1, 50, 1));
109: sTabSize.addChangeListener(this );
110: sRightMargin.setModel(new SpinnerNumberModel(120, 1, 200, 10));
111: sRightMargin.addChangeListener(this );
112: epPreview.setEnabled(false);
113: }
114:
115: /** This method is called from within the constructor to
116: * initialize the form.
117: * WARNING: Do NOT modify this code. The content of this method is
118: * always regenerated by the Form Editor.
119: */
120: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
121: private void initComponents() {
122:
123: lNumberOfSpacesPerIndent = new javax.swing.JLabel();
124: sNumberOfSpacesPerIndent = new javax.swing.JSpinner();
125: cbExpandTabsToSpaces = new javax.swing.JCheckBox();
126: lPreview = new javax.swing.JLabel();
127: jScrollPane1 = new javax.swing.JScrollPane();
128: epPreview = new javax.swing.JEditorPane();
129: lTabSize = new javax.swing.JLabel();
130: sTabSize = new javax.swing.JSpinner();
131: lExpandTabsToSpaces = new javax.swing.JLabel();
132: lRightMargin = new javax.swing.JLabel();
133: sRightMargin = new javax.swing.JSpinner();
134:
135: lNumberOfSpacesPerIndent.setLabelFor(sNumberOfSpacesPerIndent);
136: lNumberOfSpacesPerIndent
137: .setText("Number of Spaces per Indent:");
138:
139: cbExpandTabsToSpaces.setBorder(javax.swing.BorderFactory
140: .createEmptyBorder(0, 0, 0, 0));
141: cbExpandTabsToSpaces.setMargin(new java.awt.Insets(0, 0, 0, 0));
142:
143: lPreview.setText("Preview:");
144:
145: jScrollPane1.setViewportView(epPreview);
146:
147: lTabSize.setLabelFor(sTabSize);
148: lTabSize.setText("Tab Size:");
149:
150: lExpandTabsToSpaces.setLabelFor(cbExpandTabsToSpaces);
151: lExpandTabsToSpaces.setText("Expand Tabs To Spaces:");
152:
153: lRightMargin.setLabelFor(sRightMargin);
154: lRightMargin.setText("Right Margin:");
155:
156: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
157: this );
158: this .setLayout(layout);
159: layout
160: .setHorizontalGroup(layout
161: .createParallelGroup(
162: org.jdesktop.layout.GroupLayout.LEADING)
163: .add(
164: jScrollPane1,
165: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
166: 763, Short.MAX_VALUE)
167: .add(
168: layout.createSequentialGroup().add(
169: lPreview).addContainerGap())
170: .add(
171: org.jdesktop.layout.GroupLayout.TRAILING,
172: layout
173: .createSequentialGroup()
174: .add(
175: layout
176: .createParallelGroup(
177: org.jdesktop.layout.GroupLayout.LEADING)
178: .add(
179: layout
180: .createSequentialGroup()
181: .add(
182: layout
183: .createParallelGroup(
184: org.jdesktop.layout.GroupLayout.LEADING)
185: .add(
186: layout
187: .createSequentialGroup()
188: .add(
189: layout
190: .createParallelGroup(
191: org.jdesktop.layout.GroupLayout.LEADING)
192: .add(
193: lNumberOfSpacesPerIndent,
194: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
195: 211,
196: Short.MAX_VALUE)
197: .add(
198: lTabSize,
199: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
200: 211,
201: Short.MAX_VALUE))
202: .addPreferredGap(
203: org.jdesktop.layout.LayoutStyle.RELATED))
204: .add(
205: layout
206: .createSequentialGroup()
207: .add(
208: lRightMargin)
209: .add(
210: 140,
211: 140,
212: 140)))
213: .add(
214: layout
215: .createParallelGroup(
216: org.jdesktop.layout.GroupLayout.LEADING,
217: false)
218: .add(
219: sRightMargin)
220: .add(
221: sTabSize)
222: .add(
223: sNumberOfSpacesPerIndent,
224: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
225: 42,
226: Short.MAX_VALUE))
227: .add(
228: 204,
229: 204,
230: 204))
231: .add(
232: layout
233: .createSequentialGroup()
234: .add(
235: cbExpandTabsToSpaces)
236: .addPreferredGap(
237: org.jdesktop.layout.LayoutStyle.RELATED)
238: .add(
239: lExpandTabsToSpaces)))
240: .add(294, 294, 294)));
241: layout
242: .setVerticalGroup(layout
243: .createParallelGroup(
244: org.jdesktop.layout.GroupLayout.LEADING)
245: .add(
246: layout
247: .createSequentialGroup()
248: .add(14, 14, 14)
249: .add(
250: layout
251: .createParallelGroup(
252: org.jdesktop.layout.GroupLayout.BASELINE)
253: .add(
254: cbExpandTabsToSpaces)
255: .add(
256: lExpandTabsToSpaces))
257: .addPreferredGap(
258: org.jdesktop.layout.LayoutStyle.RELATED)
259: .add(
260: layout
261: .createParallelGroup(
262: org.jdesktop.layout.GroupLayout.BASELINE)
263: .add(
264: lNumberOfSpacesPerIndent)
265: .add(
266: sNumberOfSpacesPerIndent,
267: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
268: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
269: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
270: .addPreferredGap(
271: org.jdesktop.layout.LayoutStyle.RELATED)
272: .add(
273: layout
274: .createParallelGroup(
275: org.jdesktop.layout.GroupLayout.BASELINE)
276: .add(lTabSize)
277: .add(
278: sTabSize,
279: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
280: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
281: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
282: .add(6, 6, 6)
283: .add(
284: layout
285: .createParallelGroup(
286: org.jdesktop.layout.GroupLayout.BASELINE)
287: .add(
288: lRightMargin)
289: .add(
290: sRightMargin,
291: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
292: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
293: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
294: .addPreferredGap(
295: org.jdesktop.layout.LayoutStyle.UNRELATED)
296: .add(lPreview)
297: .addPreferredGap(
298: org.jdesktop.layout.LayoutStyle.RELATED)
299: .add(
300: jScrollPane1,
301: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
302: 165, Short.MAX_VALUE)));
303: }// </editor-fold>//GEN-END:initComponents
304:
305: // Variables declaration - do not modify//GEN-BEGIN:variables
306: private javax.swing.JCheckBox cbExpandTabsToSpaces;
307: private javax.swing.JEditorPane epPreview;
308: private javax.swing.JScrollPane jScrollPane1;
309: private javax.swing.JLabel lExpandTabsToSpaces;
310: private javax.swing.JLabel lNumberOfSpacesPerIndent;
311: private javax.swing.JLabel lPreview;
312: private javax.swing.JLabel lRightMargin;
313: private javax.swing.JLabel lTabSize;
314: private javax.swing.JSpinner sNumberOfSpacesPerIndent;
315: private javax.swing.JSpinner sRightMargin;
316: private javax.swing.JSpinner sTabSize;
317:
318: // End of variables declaration//GEN-END:variables
319:
320: private static String loc(String key) {
321: return NbBundle.getMessage(IndentationPanel.class, key);
322: }
323:
324: private static void loc(Component c, String key) {
325: if (!(c instanceof JLabel)) {
326: c.getAccessibleContext()
327: .setAccessibleName(loc("AN_" + key)); //NOI18N
328: c.getAccessibleContext().setAccessibleDescription(
329: loc("AD_" + key)); //NOI18N
330: }
331: if (c instanceof AbstractButton) {
332: Mnemonics.setLocalizedText((AbstractButton) c, loc("CTL_"
333: + key)); //NOI18N
334: } else {
335: Mnemonics.setLocalizedText((JLabel) c, loc("CTL_" + key)); //NOI18N
336: }
337: }
338:
339: private void updatePreview() {
340: model.setExpandTabs(cbExpandTabsToSpaces.isSelected());
341: model.setSpacesPerTab((Integer) sNumberOfSpacesPerIndent
342: .getValue());
343: model.setTabSize((Integer) sTabSize.getValue());
344: model.setRightMargin((Integer) sRightMargin.getValue());
345:
346: // start formatter
347: SwingUtilities.invokeLater(new Runnable() {
348: public void run() {
349: epPreview.setText(originalText);
350: Document doc = epPreview.getDocument();
351: if (doc instanceof BaseDocument) {
352: BaseDocument bdoc = (BaseDocument) doc;
353: Formatter formatter = bdoc.getFormatter();
354: formatter.reformatLock();
355: bdoc.atomicLock();
356: try {
357: formatter.reformat(bdoc, 0, bdoc.getLength());
358: } catch (BadLocationException ex) {
359: ex.printStackTrace();
360: } finally {
361: bdoc.atomicUnlock();
362: formatter.reformatUnlock();
363: }
364: }
365: }
366: });
367: }
368:
369: // ActionListener ..........................................................
370:
371: public void stateChanged(ChangeEvent e) {
372: if (!listen)
373: return;
374: updatePreview();
375: if (changed != model.isChanged()) {
376: firePropertyChange(OptionsPanelController.PROP_CHANGED,
377: Boolean.valueOf(changed), Boolean.valueOf(model
378: .isChanged()));
379: }
380: changed = model.isChanged();
381: }
382:
383: public void actionPerformed(ActionEvent e) {
384: if (!listen)
385: return;
386: updatePreview();
387: if (changed != model.isChanged()) {
388: firePropertyChange(OptionsPanelController.PROP_CHANGED,
389: Boolean.valueOf(changed), Boolean.valueOf(model
390: .isChanged()));
391: }
392: changed = model.isChanged();
393: }
394:
395: public void update() {
396: model = new IndentationModel();
397:
398: if (originalText == null) {
399: // add text to preview
400: try {
401: InputStream is = getClass()
402: .getResourceAsStream(
403: "/org/netbeans/modules/options/indentation/indentationExample"); //NOI18N
404: BufferedReader r = new BufferedReader(
405: new InputStreamReader(is));
406: try {
407: StringBuffer sb = new StringBuffer();
408: String line = r.readLine();
409: while (line != null) {
410: sb.append(line).append('\n'); //NOI18N
411: line = r.readLine();
412: }
413: originalText = new String(sb);
414: } finally {
415: r.close();
416: }
417: } catch (IOException ex) {
418: ex.printStackTrace();
419: }
420: }
421:
422: // init components
423: listen = false;
424: SwingUtilities.invokeLater(new Runnable() {
425: public void run() {
426: epPreview.setContentType("text/xml");
427: cbExpandTabsToSpaces.setSelected(model.isExpandTabs());
428: sNumberOfSpacesPerIndent.setValue(model
429: .getSpacesPerTab());
430: sTabSize.setValue(model.getTabSize());
431: sRightMargin.setValue(model.getRightMargin());
432: listen = true;
433:
434: // update preview
435: updatePreview();
436: }
437: });
438: }
439:
440: public void applyChanges() {
441: if (model != null) {
442: model.applyChanges();
443: }
444: }
445:
446: public void cancel() {
447: if (model != null) {
448: model.revertChanges();
449: }
450: }
451:
452: public boolean dataValid() {
453: return true;
454: }
455:
456: public boolean isChanged() {
457: if (model == null) {
458: return false;
459: } else {
460: return model.isChanged();
461: }
462: }
463: }
|