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.ruby.rubyproject.ui.customizer;
043:
044: import java.awt.event.MouseEvent;
045: import java.awt.event.MouseListener;
046: import java.util.Arrays;
047: import java.util.List;
048: import javax.swing.JPanel;
049: import javax.swing.ListSelectionModel;
050: import javax.swing.SwingUtilities;
051: import javax.swing.event.ChangeEvent;
052: import javax.swing.event.ChangeListener;
053: import javax.swing.event.ListSelectionEvent;
054: import javax.swing.event.ListSelectionListener;
055: import org.netbeans.modules.ruby.rubyproject.RubyProjectUtil; //import org.netbeans.modules.javacore.JMManager;
056: import org.openide.awt.Mnemonics;
057: import org.openide.awt.MouseUtils;
058: import org.openide.filesystems.FileObject;
059: import org.openide.util.NbBundle;
060: import org.openide.util.RequestProcessor;
061:
062: /** Browses and allows to choose a project's main class.
063: *
064: * @author Jiri Rechtacek
065: */
066: public class MainClassChooser extends JPanel {
067:
068: private ChangeListener changeListener;
069: private String dialogSubtitle = null;
070: private List/*<String>*/possibleMainClasses;
071:
072: /** Creates new form MainClassChooser */
073: public MainClassChooser(FileObject[] sourcesRoots) {
074: this (sourcesRoots, null);
075: }
076:
077: public MainClassChooser(FileObject[] sourcesRoots, String subtitle) {
078: dialogSubtitle = subtitle;
079: initComponents();
080: initClassesView(sourcesRoots);
081: }
082:
083: private void initClassesView(final FileObject[] sourcesRoots) {
084: possibleMainClasses = null;
085: jMainClassList
086: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
087: jMainClassList.setListData(getWarmupList());
088: jMainClassList
089: .addListSelectionListener(new ListSelectionListener() {
090: public void valueChanged(ListSelectionEvent evt) {
091: if (changeListener != null) {
092: changeListener
093: .stateChanged(new ChangeEvent(evt));
094: }
095: }
096: });
097: // support for double click to finish dialog with selected class
098: jMainClassList.addMouseListener(new MouseListener() {
099: public void mouseClicked(MouseEvent e) {
100: if (MouseUtils.isDoubleClick(e)) {
101: if (getSelectedMainClass() != null) {
102: if (changeListener != null) {
103: changeListener
104: .stateChanged(new ChangeEvent(e));
105: }
106: }
107: }
108: }
109:
110: public void mousePressed(MouseEvent e) {
111: }
112:
113: public void mouseReleased(MouseEvent e) {
114: }
115:
116: public void mouseEntered(MouseEvent e) {
117: }
118:
119: public void mouseExited(MouseEvent e) {
120: }
121: });
122:
123: RequestProcessor.getDefault().post(new Runnable() {
124: public void run() {
125: possibleMainClasses = RubyProjectUtil
126: .getMainClasses(sourcesRoots);
127: if (possibleMainClasses.isEmpty()) {
128: SwingUtilities.invokeLater(new Runnable() {
129: public void run() {
130: jMainClassList
131: .setListData(new String[] { NbBundle
132: .getMessage(
133: MainClassChooser.class,
134: "LBL_ChooseMainClass_NO_CLASSES_NODE") }); // NOI18N
135: }
136: });
137: } else {
138: final Object[] arr = possibleMainClasses.toArray();
139: // #46861, sort name of classes
140: Arrays.sort(arr);
141: SwingUtilities.invokeLater(new Runnable() {
142: public void run() {
143: jMainClassList.setListData(arr);
144: jMainClassList.setSelectedIndex(0);
145: }
146: });
147: }
148: }
149: });
150:
151: if (dialogSubtitle != null) {
152: Mnemonics.setLocalizedText(jLabel1, dialogSubtitle);
153: }
154: }
155:
156: private Object[] getWarmupList() {
157: // return JMManager.getManager().isScanInProgress() ?
158: // new Object[] {NbBundle.getMessage (MainClassChooser.class, "LBL_ChooseMainClass_SCANNING_MESSAGE")}:
159: // new Object[] {NbBundle.getMessage (MainClassChooser.class, "LBL_ChooseMainClass_WARMUP_MESSAGE")}; // NOI18N
160: return new Object[] { NbBundle.getMessage(
161: MainClassChooser.class,
162: "LBL_ChooseMainClass_WARMUP_MESSAGE") };
163: }
164:
165: private boolean isValidMainClassName(Object value) {
166: return (possibleMainClasses != null)
167: && (possibleMainClasses.contains(value));
168: }
169:
170: /** Returns the selected main class.
171: *
172: * @return name of class or null if no class with the main method is selected
173: */
174: public String getSelectedMainClass() {
175: if (isValidMainClassName(jMainClassList.getSelectedValue())) {
176: return (String) jMainClassList.getSelectedValue();
177: } else {
178: return null;
179: }
180: }
181:
182: public void addChangeListener(ChangeListener l) {
183: changeListener = l;
184: }
185:
186: public void removeChangeListener(ChangeListener l) {
187: changeListener = null;
188: }
189:
190: // Used only from unit tests to suppress check of main method. If value
191: // is different from null it will be returned instead.
192: public static Boolean unitTestingSupport_hasMainMethodResult = null;
193:
194: /** Checks if given file object contains the main method.
195: *
196: * @param classFO file object represents java
197: * @return false if parameter is null or doesn't contain SourceCookie
198: * or SourceCookie doesn't contain the main method
199: */
200: public static boolean hasMainMethod(FileObject classFO) {
201: return RubyProjectUtil.hasMainMethod(classFO);
202: }
203:
204: /** This method is called from within the constructor to
205: * initialize the form.
206: * WARNING: Do NOT modify this code. The content of this method is
207: * always regenerated by the Form Editor.
208: */
209: private void initComponents() {//GEN-BEGIN:initComponents
210: java.awt.GridBagConstraints gridBagConstraints;
211:
212: jLabel1 = new javax.swing.JLabel();
213: jScrollPane1 = new javax.swing.JScrollPane();
214: jMainClassList = new javax.swing.JList();
215:
216: setLayout(new java.awt.GridBagLayout());
217:
218: setPreferredSize(new java.awt.Dimension(380, 300));
219: getAccessibleContext().setAccessibleDescription(
220: org.openide.util.NbBundle.getBundle(
221: MainClassChooser.class).getString(
222: "AD_MainClassChooser"));
223: jLabel1.setLabelFor(jMainClassList);
224: org.openide.awt.Mnemonics.setLocalizedText(jLabel1,
225: org.openide.util.NbBundle.getBundle(
226: MainClassChooser.class).getString(
227: "CTL_AvaialableMainClasses"));
228: gridBagConstraints = new java.awt.GridBagConstraints();
229: gridBagConstraints.gridx = 0;
230: gridBagConstraints.gridy = 0;
231: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
232: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
233: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
234: gridBagConstraints.weightx = 1.0;
235: gridBagConstraints.insets = new java.awt.Insets(12, 12, 2, 12);
236: add(jLabel1, gridBagConstraints);
237:
238: jScrollPane1.setMinimumSize(new java.awt.Dimension(100, 200));
239: jScrollPane1.setViewportView(jMainClassList);
240: jMainClassList.getAccessibleContext().setAccessibleDescription(
241: org.openide.util.NbBundle.getBundle(
242: MainClassChooser.class).getString(
243: "AD_jMainClassList"));
244:
245: gridBagConstraints = new java.awt.GridBagConstraints();
246: gridBagConstraints.gridx = 0;
247: gridBagConstraints.gridy = 1;
248: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
249: gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
250: gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
251: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
252: gridBagConstraints.weightx = 1.0;
253: gridBagConstraints.weighty = 1.0;
254: gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 12);
255: add(jScrollPane1, gridBagConstraints);
256:
257: }//GEN-END:initComponents
258:
259: // Variables declaration - do not modify//GEN-BEGIN:variables
260: private javax.swing.JLabel jLabel1;
261: private javax.swing.JList jMainClassList;
262: private javax.swing.JScrollPane jScrollPane1;
263: // End of variables declaration//GEN-END:variables
264:
265: // Maybe useless renderer (fit if wanted to reneder Icons) // XXX
266: // private static final class MainClassRenderer extends DefaultListCellRenderer {
267: // public Component getListCellRendererComponent (JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
268: // String displayName;
269: // if (value instanceof String) {
270: // displayName = (String) value;
271: // } if (value instanceof FileObject) {
272: // displayName = ((FileObject)value).getName ();
273: // } else {
274: // displayName = value.toString ();
275: // }
276: // return super.getListCellRendererComponent (list, displayName, index, isSelected, cellHasFocus);
277: // }
278: // }
279: //
280: }
|