1 19 20 package org.netbeans.modules.project.ui.actions; 21 22 import java.awt.BorderLayout ; 23 import java.awt.Color ; 24 import java.awt.Component ; 25 import java.awt.Dialog ; 26 import java.awt.Dimension ; 27 import java.awt.Graphics ; 28 import java.awt.Graphics2D ; 29 import java.awt.RenderingHints ; 30 import java.awt.Toolkit ; 31 import java.awt.event.ActionEvent ; 32 import java.awt.event.ActionListener ; 33 import java.awt.event.MouseEvent ; 34 import java.beans.PropertyChangeEvent ; 35 import java.beans.PropertyChangeListener ; 36 import java.util.Arrays ; 37 import javax.swing.Icon ; 38 import javax.swing.JButton ; 39 import javax.swing.JMenuItem ; 40 import javax.swing.JPanel ; 41 import javax.swing.JPopupMenu ; 42 import javax.swing.border.EmptyBorder ; 43 import javax.swing.event.ChangeEvent ; 44 import javax.swing.event.ChangeListener ; 45 import org.netbeans.api.project.Project; 46 import org.netbeans.modules.project.ui.NoMainProjectWarning; 47 import org.netbeans.modules.project.ui.OpenProjectList; 48 import org.netbeans.spi.project.ActionProvider; 49 import org.netbeans.spi.project.ProjectConfiguration; 50 import org.netbeans.spi.project.ProjectConfigurationProvider; 51 import org.netbeans.spi.project.ui.support.ProjectActionPerformer; 52 import org.openide.DialogDescriptor; 53 import org.openide.DialogDisplayer; 54 import org.openide.awt.Actions; 55 import org.openide.awt.MouseUtils; 56 import org.openide.awt.ToolbarPool; 57 import org.openide.util.Lookup; 58 import org.openide.util.Mutex; 59 import org.openide.util.NbBundle; 60 import org.openide.util.WeakListeners; 61 import org.openide.util.actions.Presenter; 62 import org.openide.util.lookup.Lookups; 63 64 68 public class MainProjectAction extends BasicAction implements Presenter.Toolbar, PropertyChangeListener { 69 70 private String command; 71 private ProjectActionPerformer performer; 72 private String name; 73 74 public MainProjectAction(ProjectActionPerformer performer, String name, Icon icon) { 75 this( null, performer, name, icon ); 76 } 77 78 public MainProjectAction(String command, String name, Icon icon) { 79 this( command, null, name, icon ); 80 } 81 82 public MainProjectAction(String command, ProjectActionPerformer performer, String name, Icon icon) { 83 84 this.command = command; 85 this.performer = performer; 86 this.name = name; 87 88 setDisplayName( name ); 89 if ( icon != null ) { 90 setSmallIcon( icon ); 91 } 92 93 refreshView(); 94 OpenProjectList.getDefault().addPropertyChangeListener( WeakListeners.propertyChange( this, OpenProjectList.getDefault() ) ); 96 } 98 99 public void actionPerformed( ActionEvent e ) { 100 101 Project p = OpenProjectList.getDefault().getMainProject(); 102 103 if (p == null) { 105 if (showNoMainProjectWarning (OpenProjectList.getDefault().getOpenProjects (), name)) { 107 return ; 108 } 109 p = OpenProjectList.getDefault().getMainProject(); 110 } 111 112 if ( command != null ) { 113 ActionProvider ap = (ActionProvider)p.getLookup().lookup( ActionProvider.class ); 114 if (Arrays.asList(ap.getSupportedActions()).contains(command)) { 115 ap.invokeAction(command, Lookup.EMPTY); 116 } else { 117 Toolkit.getDefaultToolkit().beep(); 119 refreshView(); 120 } 121 } 122 else { 123 performer.perform( p ); 124 } 125 } 126 127 128 130 132 public void propertyChange( PropertyChangeEvent evt ) { 133 if ( evt.getPropertyName() == OpenProjectList.PROPERTY_MAIN_PROJECT || 134 evt.getPropertyName() == OpenProjectList.PROPERTY_OPEN_PROJECTS ) { 135 Mutex.EVENT.readAccess(new Runnable () { 136 public void run() { 137 refreshView(); 138 } 139 }); 140 } 141 } 142 143 private void refreshView() { 144 145 Project p = OpenProjectList.getDefault().getMainProject(); 146 boolean noOpenProject = OpenProjectList.getDefault ().getOpenProjects ().length == 0; 147 148 if ( command == null ) { 149 setEnabled( performer.enable( p ) ); 150 } 151 else { 152 if ( p == null ) { 153 setEnabled( !noOpenProject ); 154 } 155 else if ( ActionsUtil.commandSupported ( p, command, Lookup.EMPTY ) ) { 156 setEnabled( !noOpenProject ); 157 } 158 else { 159 setEnabled( false ); 160 } 161 } 162 } 163 164 private boolean showNoMainProjectWarning(Project[] projects, String action) { 165 boolean canceled; 166 final JButton okButton = new JButton (NbBundle.getMessage (NoMainProjectWarning.class, "LBL_NoMainClassWarning_ChooseMainProject_OK")); okButton.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage (NoMainProjectWarning.class, "AD_NoMainClassWarning_ChooseMainProject_OK")); 168 169 final NoMainProjectWarning panel = new NoMainProjectWarning (projects); 171 172 Object [] options = new Object [] { 173 okButton, 174 DialogDescriptor.CANCEL_OPTION 175 }; 176 177 panel.addChangeListener (new ChangeListener () { 178 public void stateChanged (ChangeEvent e) { 179 if (e.getSource () instanceof MouseEvent && MouseUtils.isDoubleClick (((MouseEvent )e.getSource ()))) { 180 if (panel.getSelectedProject () != null) { 182 okButton.doClick (); 183 } 184 } else { 185 okButton.setEnabled (panel.getSelectedProject () != null); 186 } 187 } 188 }); 189 190 okButton.setEnabled (panel.getSelectedProject () != null); 191 192 DialogDescriptor desc = new DialogDescriptor (panel, 193 action == null ? 194 NbBundle.getMessage(NoMainProjectWarning.class, "CTL_NoMainProjectWarning_Title") : 195 Actions.cutAmpersand(action), 196 true, options, options[0], DialogDescriptor.DEFAULT_ALIGN, null, null); 197 desc.setMessageType (DialogDescriptor.INFORMATION_MESSAGE); 198 Dialog dlg = DialogDisplayer.getDefault ().createDialog (desc); 199 dlg.setVisible (true); 200 if (desc.getValue() != options[0]) { 201 canceled = true; 202 } else { 203 Project mainProject = panel.getSelectedProject (); 204 OpenProjectList.getDefault ().setMainProject (mainProject); 205 canceled = false; 206 } 207 dlg.dispose(); 208 209 return canceled; 210 } 211 212 private static final boolean SHOW_CONFIG_DROPDOWN = Boolean.getBoolean("org.netbeans.modules.project.ui.actions.MainProjectAction.SHOW_CONFIG_DROPDOWN"); 214 218 private static final String PREFERRED_ICON_SIZE = "PreferredIconSize"; public Component getToolbarPresenter() { 220 final JButton main = new JButton (); 221 Actions.connect(main, this); 222 if (!SHOW_CONFIG_DROPDOWN) { 223 return main; 224 } 225 final JPanel panel = new JPanel (new BorderLayout ()); 226 panel.addPropertyChangeListener(PREFERRED_ICON_SIZE, new PropertyChangeListener () { 227 public void propertyChange(PropertyChangeEvent evt) { 228 main.putClientProperty(PREFERRED_ICON_SIZE, panel.getClientProperty(PREFERRED_ICON_SIZE)); 229 } 230 }); 231 panel.setBorder(new EmptyBorder (0, 0, 0, 0)); 232 panel.add(main, BorderLayout.CENTER); 233 JButton configs = new ConfigButton(main.getPreferredSize().height); 234 panel.add(configs, BorderLayout.LINE_END); 235 return panel; 236 } 237 238 private static final class ArrowIcon implements Icon { 239 private static final int SIZE = 6; 240 private static final int HEIGHT = ToolbarPool.getDefault().getPreferredIconSize(); 241 private static final int PAD = 3; 242 public int getIconWidth() { 243 return SIZE * 2 - 1 + PAD * 2; 244 } 245 public int getIconHeight() { 246 return Math.max(SIZE + PAD * 2, HEIGHT); 247 } 248 public void paintIcon(Component c, Graphics g, int x, int y) { 249 g.setColor(Color.BLACK); 250 int offx = PAD; 251 int offy = (g.getClipBounds().height - SIZE) / 2; 252 ((Graphics2D ) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 253 g.fillPolygon(new int[] {offx, offx + SIZE * 2 - 2, offx + SIZE - 1}, new int[] {offy, offy, offy + SIZE - 1}, 3); 254 } 255 } 256 257 private final class ConfigButton extends JButton implements PropertyChangeListener , ActionListener { 258 259 private final PropertyChangeListener pcl = WeakListeners.propertyChange(this, null); 260 private JPopupMenu menu; 261 262 public ConfigButton(int height) { 263 super(new ArrowIcon()); 264 OpenProjectList.getDefault().addPropertyChangeListener(pcl); 265 propertyChange(null); 266 addActionListener(this); 267 setPreferredSize(new Dimension (getIcon().getIconWidth(), height)); 268 setFocusPainted(false); 269 } 270 271 public void propertyChange(PropertyChangeEvent evt) { 272 String prop = evt != null ? evt.getPropertyName() : null; 273 if (prop == null || prop.equals(OpenProjectList.PROPERTY_MAIN_PROJECT) || prop.equals(ProjectConfigurationProvider.PROP_CONFIGURATIONS)) { 274 Mutex.EVENT.readAccess(new Runnable () { 275 public void run() { 276 boolean v = false; 277 Project p = OpenProjectList.getDefault().getMainProject(); 278 if (p != null) { 279 ActionProvider ap = p.getLookup().lookup(ActionProvider.class); 280 if (ap != null) { 281 if (Arrays.asList(ap.getSupportedActions()).contains(command)) { 282 ProjectConfigurationProvider<?> pcp = p.getLookup().lookup(ProjectConfigurationProvider.class); 283 if (pcp != null) { 284 pcp.removePropertyChangeListener(pcl); 285 pcp.addPropertyChangeListener(pcl); 286 v = pcp.configurationsAffectAction(command) && 287 pcp.getConfigurations().size() > 1; 289 } 290 } 291 } 292 } 293 setVisible(v); 294 } 295 }); 296 } 297 } 298 299 public void actionPerformed(ActionEvent e) { 300 if (menu != null) { 301 menu.setVisible(false); 302 menu = null; 303 return; 304 } 305 final Project p = OpenProjectList.getDefault().getMainProject(); 306 ProjectConfigurationProvider<?> pcp = p.getLookup().lookup(ProjectConfigurationProvider.class); 307 menu = new JPopupMenu (); 308 for (final ProjectConfiguration config : pcp.getConfigurations()) { 309 JMenuItem item = new JMenuItem (config.getDisplayName()); 310 menu.add(item); 311 item.addActionListener(new ActionListener () { 312 public void actionPerformed(ActionEvent e) { 313 menu = null; 314 p.getLookup().lookup(ActionProvider.class).invokeAction(command, Lookups.singleton(config)); 315 } 316 }); 317 } 318 menu.show(this, 0, getSize().height); 319 } 320 321 } 322 323 } 324 | Popular Tags |