| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.maven.customizer; |
| |
| import java.awt.Component; |
| import java.awt.event.MouseEvent; |
| import java.awt.event.MouseListener; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Comparator; |
| import javax.lang.model.element.TypeElement; |
| import javax.swing.DefaultListCellRenderer; |
| import javax.swing.JList; |
| import javax.swing.JPanel; |
| import javax.swing.ListSelectionModel; |
| import javax.swing.SwingUtilities; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| import javax.swing.event.ListSelectionEvent; |
| import javax.swing.event.ListSelectionListener; |
| import org.netbeans.api.java.source.ElementHandle; |
| import org.netbeans.api.java.source.SourceUtils; |
| import org.openide.awt.Mnemonics; |
| import org.openide.awt.MouseUtils; |
| import org.openide.filesystems.FileObject; |
| import org.openide.util.RequestProcessor; |
| import static org.netbeans.modules.maven.customizer.Bundle.*; |
| import org.openide.util.NbBundle.Messages; |
| |
| /** Browses and allows to choose a project's main class. |
| * |
| * @author Jiri Rechtacek |
| */ |
| public class MainClassChooser extends JPanel { |
| |
| private ChangeListener changeListener; |
| private String dialogSubtitle = null; |
| private Collection<ElementHandle<TypeElement>> possibleMainClasses; |
| |
| /** Creates new form MainClassChooser */ |
| public MainClassChooser (FileObject[] sourcesRoots) { |
| this (sourcesRoots, null); |
| } |
| |
| public MainClassChooser (FileObject[] sourcesRoots, String subtitle) { |
| dialogSubtitle = subtitle; |
| initComponents(); |
| jMainClassList.setCellRenderer(new MainClassRenderer()); |
| initClassesView (sourcesRoots); |
| } |
| |
| @Messages("LBL_ChooseMainClass_NO_CLASSES_NODE=<No main classes found>") |
| private void initClassesView (final FileObject[] sourcesRoots) { |
| possibleMainClasses = null; |
| jMainClassList.setSelectionMode (ListSelectionModel.SINGLE_SELECTION); |
| jMainClassList.setListData (getWarmupList ()); |
| jMainClassList.addListSelectionListener (new ListSelectionListener () { |
| @Override |
| public void valueChanged (ListSelectionEvent evt) { |
| if (changeListener != null) { |
| changeListener.stateChanged (new ChangeEvent (evt)); |
| } |
| } |
| }); |
| // support for double click to finish dialog with selected class |
| jMainClassList.addMouseListener (new MouseListener () { |
| @Override |
| public void mouseClicked (MouseEvent e) { |
| if (MouseUtils.isDoubleClick (e)) { |
| if (getSelectedMainClass () != null) { |
| if (changeListener != null) { |
| changeListener.stateChanged (new ChangeEvent (e)); |
| } |
| } |
| } |
| } |
| @Override |
| public void mousePressed (MouseEvent e) {} |
| @Override |
| public void mouseReleased (MouseEvent e) {} |
| @Override |
| public void mouseEntered (MouseEvent e) {} |
| @Override |
| public void mouseExited (MouseEvent e) {} |
| }); |
| |
| RequestProcessor.getDefault ().post (new Runnable () { |
| @Override |
| public void run () { |
| |
| possibleMainClasses = SourceUtils.getMainClasses(sourcesRoots); |
| if (possibleMainClasses.isEmpty ()) { |
| SwingUtilities.invokeLater( new Runnable () { |
| @Override |
| public void run () { |
| jMainClassList.setListData (new String[] { LBL_ChooseMainClass_NO_CLASSES_NODE () } ); // NOI18N |
| } |
| }); |
| } else { |
| final ElementHandle<TypeElement>[] arr = possibleMainClasses.toArray(new ElementHandle[possibleMainClasses.size()]); |
| // #46861, sort name of classes |
| Arrays.sort (arr, new MainClassComparator()); |
| SwingUtilities.invokeLater(new Runnable () { |
| @Override |
| public void run () { |
| jMainClassList.setListData (arr); |
| jMainClassList.setSelectedIndex (0); |
| } |
| }); |
| } |
| } |
| }); |
| |
| if (dialogSubtitle != null) { |
| Mnemonics.setLocalizedText (jLabel1, dialogSubtitle); |
| } |
| } |
| |
| @Messages("LBL_ChooseMainClass_WARMUP_MESSAGE=Initializing view, please wait ...") |
| private Object[] getWarmupList () { |
| return new Object[] {LBL_ChooseMainClass_WARMUP_MESSAGE ()}; //NOI18N |
| } |
| |
| private boolean isValidMainClassName (Object value) { |
| return (possibleMainClasses != null) && (possibleMainClasses.contains (value)); |
| } |
| |
| |
| /** Returns the selected main class. |
| * |
| * @return name of class or null if no class with the main method is selected |
| */ |
| public String getSelectedMainClass () { |
| if (isValidMainClassName (jMainClassList.getSelectedValue ())) { |
| return ((ElementHandle)jMainClassList.getSelectedValue()).getQualifiedName(); |
| } else { |
| return null; |
| } |
| } |
| |
| public void addChangeListener (ChangeListener l) { |
| changeListener = l; |
| } |
| |
| public void removeChangeListener (ChangeListener l) { |
| changeListener = null; |
| } |
| |
| /** Checks if given file object contains the main method. |
| * |
| * @param classFO file object represents java |
| * @return false if parameter is null or doesn't contain SourceCookie |
| * or SourceCookie doesn't contain the main method |
| */ |
| public static boolean hasMainMethod (FileObject fo) { |
| if (fo == null) { |
| // ??? maybe better should be thrown IAE |
| return false; |
| } |
| return !SourceUtils.getMainClasses(fo).isEmpty(); |
| } |
| |
| /** This method is called from within the constructor to |
| * initialize the form. |
| * WARNING: Do NOT modify this code. The content of this method is |
| * always regenerated by the Form Editor. |
| */ |
| private void initComponents() {//GEN-BEGIN:initComponents |
| java.awt.GridBagConstraints gridBagConstraints; |
| |
| jLabel1 = new javax.swing.JLabel(); |
| jScrollPane1 = new javax.swing.JScrollPane(); |
| jMainClassList = new javax.swing.JList(); |
| |
| setLayout(new java.awt.GridBagLayout()); |
| |
| setPreferredSize(new java.awt.Dimension(380, 300)); |
| getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getBundle(MainClassChooser.class).getString("AD_MainClassChooser")); |
| jLabel1.setLabelFor(jMainClassList); |
| org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getBundle(MainClassChooser.class).getString("CTL_AvaialableMainClasses")); |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 0; |
| gridBagConstraints.gridy = 0; |
| gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; |
| gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; |
| gridBagConstraints.weightx = 1.0; |
| gridBagConstraints.insets = new java.awt.Insets(12, 12, 2, 12); |
| add(jLabel1, gridBagConstraints); |
| |
| jScrollPane1.setMinimumSize(new java.awt.Dimension(100, 200)); |
| jScrollPane1.setViewportView(jMainClassList); |
| jMainClassList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getBundle(MainClassChooser.class).getString("AD_jMainClassList")); |
| |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 0; |
| gridBagConstraints.gridy = 1; |
| gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; |
| gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; |
| gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; |
| gridBagConstraints.weightx = 1.0; |
| gridBagConstraints.weighty = 1.0; |
| gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 12); |
| add(jScrollPane1, gridBagConstraints); |
| |
| }//GEN-END:initComponents |
| |
| |
| // Variables declaration - do not modify//GEN-BEGIN:variables |
| private javax.swing.JLabel jLabel1; |
| private javax.swing.JList jMainClassList; |
| private javax.swing.JScrollPane jScrollPane1; |
| // End of variables declaration//GEN-END:variables |
| |
| |
| private static final class MainClassRenderer extends DefaultListCellRenderer { |
| @Override |
| public Component getListCellRendererComponent (JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
| String displayName; |
| if (value instanceof ElementHandle) { |
| displayName = ((ElementHandle)value).getQualifiedName(); |
| } else { |
| displayName = value.toString (); |
| } |
| return super.getListCellRendererComponent (list, displayName, index, isSelected, cellHasFocus); |
| } |
| } |
| |
| private static class MainClassComparator implements Comparator<ElementHandle> { |
| |
| @Override |
| public int compare(ElementHandle arg0, ElementHandle arg1) { |
| return arg0.getQualifiedName().compareTo(arg1.getQualifiedName()); |
| } |
| } |
| |
| } |