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-2007 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.cnd.makewizard;
043:
044: import java.awt.GridBagConstraints;
045: import java.awt.GridBagLayout;
046: import java.awt.Insets;
047: import java.awt.event.ActionEvent;
048: import java.awt.event.ActionListener;
049: import java.awt.event.FocusEvent;
050: import java.awt.event.FocusListener;
051: import java.io.File;
052: import javax.swing.JButton;
053: import javax.swing.JDialog;
054: import javax.swing.JFileChooser;
055: import javax.swing.JLabel;
056: import javax.swing.JTextField;
057: import javax.swing.KeyStroke;
058: import javax.swing.event.DocumentEvent;
059: import javax.swing.event.DocumentListener;
060: import javax.swing.text.DefaultEditorKit;
061: import javax.swing.text.JTextComponent;
062: import javax.swing.text.Keymap;
063: import org.netbeans.modules.cnd.api.utils.IpeFileSystemView;
064: import org.netbeans.modules.cnd.api.utils.IpeUtils;
065:
066: /**
067: * Superclass for a MakefileWizard panel consisting of a directory textfield
068: * and a name textfield. The directory textfield has a directory chooser. There
069: * may also be optional help text below the textfields.
070: */
071:
072: public class ItemChooser extends MakefileWizardPanel implements
073: FocusListener {
074:
075: /** Serial version number */
076: static final long serialVersionUID = 6653452210904639697L;
077:
078: // the fields in the first panel...
079: private JLabel dirLabel;
080: private JTextField dirText;
081: private JButton dirChooser;
082: private JLabel label;
083: private JTextField text;
084:
085: private JFileChooser fc;
086:
087: /** Is the directory a valid (ie, existing) directory? */
088: private boolean directoryValid;
089:
090: /** Is it OK for the directory to not exist? */
091: private boolean uncreatedDirOK;
092:
093: /** Is directory field read-only? */
094: private boolean dirReadOnly;
095:
096: /** Is the text field the name of a regular file? */
097: private boolean textNotFile;
098:
099: /**
100: * Constructor for the Makefile binary panel.
101: */
102: protected ItemChooser(MakefileWizard wd) {
103: this (wd, false, false);
104: }
105:
106: /**
107: * Constructor for the Makefile binary panel.
108: */
109: protected ItemChooser(MakefileWizard wd, boolean uncreatedDirOK) {
110: this (wd, uncreatedDirOK, false);
111: }
112:
113: /**
114: * Constructor for the Makefile binary panel.
115: */
116: protected ItemChooser(MakefileWizard wd, boolean uncreatedDirOK,
117: boolean dirReadOnly) {
118: super (wd);
119: this .uncreatedDirOK = uncreatedDirOK;
120: this .dirReadOnly = dirReadOnly;
121: }
122:
123: /**
124: * The default validation method. Most panels don't do validation so don't
125: * need to override this.
126: */
127: public boolean isPanelValid() {
128: return (uncreatedDirOK && textNotFile) || directoryValid;
129: }
130:
131: /** Override the defualt and do some validation */
132: protected final void onOk() {
133: checkit();
134: }
135:
136: /**
137: * Validate the base directory currently typed into the text field. This method should
138: * not be confused with validateData(), which is called during Makefile generation.
139: * This validation occurs while the panel is posted. The validateData() occurs much
140: * later.
141: */
142: private void validateDirectory() {
143: String dir = dirText.getText();
144:
145: if (dir.length() > 0) {
146: File file;
147:
148: if (dir.charAt(0) == File.separatorChar) {
149: file = new File(dir);
150: } else {
151: file = new File(".", dir); // NOI18N
152: }
153:
154: if (uncreatedDirOK) {
155: // for this case just check dir isn't a file
156: boolean tnf = !file.isFile();
157:
158: if (tnf != textNotFile) {
159: textNotFile = tnf;
160: MakefileWizard.getMakefileWizard().updateState();
161: }
162: } else {
163: // for this case it must be a valid directory
164: boolean isfile = file.isDirectory();
165: if (isfile != directoryValid) {
166: directoryValid = isfile;
167: MakefileWizard.getMakefileWizard().updateState();
168: }
169: }
170: }
171: }
172:
173: /** Check the directory and updateState if its changed */
174: private final void checkit() {
175: boolean oldVal = directoryValid;
176:
177: validateDirectory();
178: if (directoryValid != oldVal) {
179: MakefileWizard.getMakefileWizard().updateState();
180: }
181: }
182:
183: /** Defer widget creation until the panel needs to be displayed */
184: protected void create(String dlabel, char dmnem, String nlabel,
185: char nmnem) {
186: int gridy = 0;
187:
188: setLayout(new GridBagLayout());
189: GridBagConstraints grid = new GridBagConstraints();
190: Insets defaults = grid.insets;
191:
192: // Create the components for the directory area.
193: dirLabel = new JLabel(dlabel);
194: dirLabel.setDisplayedMnemonic(dmnem);
195: grid.anchor = GridBagConstraints.WEST;
196: grid.gridx = 0;
197: grid.gridy = gridy++;
198: grid.gridwidth = GridBagConstraints.REMAINDER;
199: add(dirLabel, grid);
200:
201: // The directory textfield
202: dirText = new JTextField(); // set value in addNotify()
203: dirText.addFocusListener(this );
204: dirLabel.setLabelFor(dirText);
205: grid.gridy = gridy++;
206: grid.gridwidth = GridBagConstraints.RELATIVE;
207: grid.weightx = 1.0;
208: grid.fill = GridBagConstraints.HORIZONTAL;
209: grid.anchor = GridBagConstraints.WEST;
210: grid.insets = defaults;
211: add(dirText, grid);
212: dirText.getDocument().addDocumentListener(
213: new DocumentListener() {
214:
215: public void changedUpdate(DocumentEvent ev) {
216: checkit();
217: }
218:
219: public void insertUpdate(DocumentEvent ev) {
220: checkit();
221: }
222:
223: public void removeUpdate(DocumentEvent ev) {
224: checkit();
225: }
226: });
227:
228: if (dirReadOnly) {
229: dirText.setEnabled(false);
230: } else {
231: // The directory chooser button
232: dirChooser = new JButton(getString("BTN_Chooser")); // NOI18N
233: dirChooser.setMnemonic(getString("MNEM_Chooser").charAt(0)); // NOI18N
234: grid.gridx = 2;
235: grid.gridwidth = GridBagConstraints.REMAINDER;
236: grid.fill = GridBagConstraints.NONE;
237: grid.anchor = GridBagConstraints.WEST;
238: grid.weightx = 0.0;
239: grid.insets = new Insets(0, 5, 0, 0);
240: add(dirChooser, grid);
241:
242: dirChooser.addActionListener(new ActionListener() {
243: public void actionPerformed(ActionEvent evt) {
244: String cwd = getMakefileData().getBaseDirectory(
245: MakefileData.EXPAND);
246:
247: fc = new JFileChooser();
248: fc.setApproveButtonText(getString("BTN_Approve")); // NOI18N
249: fc.setDialogTitle(getString("TITLE_DirChooser")); // NOI18N
250: fc.setCurrentDirectory(new File(cwd));
251: fc
252: .setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
253: fc.setFileSystemView(new IpeFileSystemView(fc
254: .getFileSystemView()));
255:
256: int returnVal = fc.showDialog(ItemChooser.this ,
257: null);
258: if (returnVal == JFileChooser.APPROVE_OPTION) {
259: String path = fc.getSelectedFile()
260: .getAbsolutePath();
261: dirText.setText(IpeUtils.getRelativePath(cwd,
262: path));
263: }
264: }
265: });
266: }
267:
268: // Now create and set the GridBagLayout constraints.
269: label = new JLabel(nlabel);
270: label.setDisplayedMnemonic(nmnem);
271: grid.anchor = GridBagConstraints.NORTHWEST;
272: grid.gridx = 0;
273: grid.gridy = gridy++;
274: grid.gridwidth = GridBagConstraints.REMAINDER;
275: grid.insets = new Insets(10, 0, 0, 0);
276: add(label, grid);
277:
278: text = new JTextField(); // set name in addNotify()
279: text.addFocusListener(this );
280: label.setLabelFor(text);
281: grid.gridy = gridy++;
282: grid.gridwidth = GridBagConstraints.RELATIVE;
283: grid.weightx = 1.0;
284: grid.insets = defaults;
285: grid.fill = GridBagConstraints.HORIZONTAL;
286: grid.anchor = GridBagConstraints.WEST;
287: add(text, grid);
288: Keymap km = text.addKeymap("ItemChooserKeymap", // NOI18N
289: text.getKeymap());
290: km.addActionForKeyStroke(KeyStroke.getKeyStroke('/'),
291: new DefaultEditorKit.BeepAction());
292: text.setKeymap(km);
293:
294: grid.gridx = 0;
295: grid.gridy = gridy++;
296: grid.gridwidth = GridBagConstraints.REMAINDER;
297: grid.gridheight = GridBagConstraints.REMAINDER;
298: grid.weightx = 1.0;
299: grid.weighty = 1.0;
300: add(new JLabel(""), grid); // NOI18N
301: }
302:
303: final void convertLabel(String nlabel, char nmnem) {
304: label.setText(nlabel);
305: label.setDisplayedMnemonic(nmnem);
306: }
307:
308: final JTextField getText() {
309: return text;
310: }
311:
312: final JTextField getDirText() {
313: return dirText;
314: }
315:
316: final JLabel getNameLabel() {
317: return label;
318: }
319:
320: public void focusGained(FocusEvent evt) {
321: }
322:
323: public void focusLost(FocusEvent evt) {
324: // help doesn't always get deselected so set total
325: // selection length to zero.
326: ((JTextComponent) evt.getComponent()).setSelectionEnd(0);
327: }
328:
329: public void addNotify() {
330: super .addNotify();
331: dirText.selectAll();
332: IpeUtils.requestFocus(dirText);
333: validateDirectory();
334: }
335:
336: public void removeNotify() {
337: super .removeNotify();
338:
339: if (fc != null && fc.isShowing()) {
340: Object o = fc.getTopLevelAncestor();
341: if (o != null && o instanceof JDialog) {
342: ((JDialog) o).dispose();
343: }
344: }
345: }
346: }
|