KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > project > ui > actions > ActiveConfigAction


1 /*
2  * Sun Public License Notice
3  *
4  * The contents of this file are subject to the Sun Public License
5  * Version 1.0 (the "License"). You may not use this file except in
6  * compliance with the License. A copy of the License is available at
7  * http://www.sun.com/
8  *
9  * The Original Code is NetBeans. The Initial Developer of the Original
10  * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
11  * Microsystems, Inc. All Rights Reserved.
12  */

13
14 package org.netbeans.modules.project.ui.actions;
15
16 import java.awt.Component JavaDoc;
17 import java.awt.Container JavaDoc;
18 import java.awt.Dimension JavaDoc;
19 import java.awt.GridBagConstraints JavaDoc;
20 import java.awt.GridBagLayout JavaDoc;
21 import java.awt.Insets JavaDoc;
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.awt.event.ActionListener JavaDoc;
24 import java.beans.PropertyChangeEvent JavaDoc;
25 import java.beans.PropertyChangeListener JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.logging.Level JavaDoc;
29 import java.util.logging.Logger JavaDoc;
30 import javax.swing.AbstractAction JavaDoc;
31 import javax.swing.Action JavaDoc;
32 import javax.swing.BorderFactory JavaDoc;
33 import javax.swing.ComboBoxModel JavaDoc;
34 import javax.swing.DefaultComboBoxModel JavaDoc;
35 import javax.swing.JComboBox JavaDoc;
36 import javax.swing.JComponent JavaDoc;
37 import javax.swing.JLabel JavaDoc;
38 import javax.swing.JList JavaDoc;
39 import javax.swing.JMenu JavaDoc;
40 import javax.swing.JMenuItem JavaDoc;
41 import javax.swing.JPanel JavaDoc;
42 import javax.swing.JRadioButtonMenuItem JavaDoc;
43 import javax.swing.ListCellRenderer JavaDoc;
44 import javax.swing.UIManager JavaDoc;
45 import javax.swing.border.Border JavaDoc;
46 import javax.swing.plaf.UIResource JavaDoc;
47 import org.netbeans.api.project.Project;
48 import org.netbeans.api.project.ProjectManager;
49 import org.netbeans.modules.project.ui.OpenProjectList;
50 import org.netbeans.spi.project.ProjectConfiguration;
51 import org.netbeans.spi.project.ProjectConfigurationProvider;
52 import org.openide.awt.DynamicMenuContent;
53 import org.openide.awt.Mnemonics;
54 import org.openide.util.ContextAwareAction;
55 import org.openide.util.HelpCtx;
56 import org.openide.util.Lookup;
57 import org.openide.util.Mutex;
58 import org.openide.util.MutexException;
59 import org.openide.util.NbBundle;
60 import org.openide.util.actions.CallableSystemAction;
61 import org.openide.util.actions.Presenter;
62
63 /**
64  * Action permitting selection of a configuration for the main project.
65  * @author Greg Crawley, Adam Sotona, Jesse Glick
66  */

67 public class ActiveConfigAction extends CallableSystemAction implements ContextAwareAction {
68
69     private static final Logger JavaDoc LOGGER = Logger.getLogger(ActiveConfigAction.class.getName());
70
71     private static final DefaultComboBoxModel JavaDoc EMPTY_MODEL = new DefaultComboBoxModel JavaDoc();
72     private static final Object JavaDoc CUSTOMIZE_ENTRY = new Object JavaDoc();
73
74     private final PropertyChangeListener JavaDoc lst;
75     private final JComboBox JavaDoc configListCombo;
76     private boolean listeningToCombo = true;
77
78     private Project currentProject;
79     private ProjectConfigurationProvider pcp;
80
81     public ActiveConfigAction() {
82         super();
83         putValue("noIconInMenu", Boolean.TRUE); // NOI18N
84
configListCombo = new JComboBox JavaDoc();
85         configListCombo.setRenderer(new ConfigCellRenderer());
86         configListCombo.setToolTipText(org.openide.awt.Actions.cutAmpersand(getName()));
87         configurationsListChanged(null);
88         configListCombo.addActionListener(new ActionListener JavaDoc() {
89             public void actionPerformed(ActionEvent JavaDoc e) {
90                 if (!listeningToCombo) {
91                     return;
92                 }
93                 Object JavaDoc o = configListCombo.getSelectedItem();
94                 if (o == CUSTOMIZE_ENTRY) {
95                     activeConfigurationChanged(pcp != null ? getActiveConfiguration(pcp) : null);
96                     pcp.customize();
97                 } else if (o != null) {
98                     activeConfigurationSelected((ProjectConfiguration) o);
99                 }
100             }
101         });
102         lst = new PropertyChangeListener JavaDoc() {
103             public void propertyChange(PropertyChangeEvent JavaDoc evt) {
104                 if (ProjectConfigurationProvider.PROP_CONFIGURATIONS.equals(evt.getPropertyName())) {
105                     configurationsListChanged(getConfigurations(pcp));
106                 } else if (ProjectConfigurationProvider.PROP_CONFIGURATION_ACTIVE.equals(evt.getPropertyName())) {
107                     activeConfigurationChanged(getActiveConfiguration(pcp));
108                 }
109             }
110         };
111         activeProjectChanged(OpenProjectList.getDefault().getMainProject());
112         OpenProjectList.getDefault().addPropertyChangeListener(new PropertyChangeListener JavaDoc() {
113             public void propertyChange(PropertyChangeEvent JavaDoc evt) {
114                 if (OpenProjectList.PROPERTY_MAIN_PROJECT.equals(evt.getPropertyName())) {
115                     activeProjectChanged(OpenProjectList.getDefault().getMainProject());
116                 }
117             }
118         });
119     }
120
121
122     private synchronized void configurationsListChanged(Collection JavaDoc<? extends ProjectConfiguration> configs) {
123         LOGGER.log(Level.FINER, "configurationsListChanged: {0}", configs);
124         if (configs == null) {
125             configListCombo.setModel(EMPTY_MODEL);
126             configListCombo.setEnabled(false);
127             /*if( null != toolbarPanel )
128                 toolbarPanel.setVisible( false );*/

129         } else {
130             DefaultComboBoxModel JavaDoc model = new DefaultComboBoxModel JavaDoc(configs.toArray());
131             if (pcp.hasCustomizer()) {
132                 model.addElement(CUSTOMIZE_ENTRY);
133             }
134             configListCombo.setModel(model);
135             configListCombo.setEnabled(true);
136             if( null != toolbarPanel )
137                 toolbarPanel.setVisible( true );
138         }
139         if( null != toolbarPanel && null != toolbarPanel.getParent() ) {
140             Container JavaDoc parentComp = toolbarPanel.getParent();
141             parentComp.invalidate();
142             parentComp.repaint();
143         }
144         if (pcp != null) {
145             activeConfigurationChanged(getActiveConfiguration(pcp));
146         }
147     }
148
149     private synchronized void activeConfigurationChanged(ProjectConfiguration config) {
150         LOGGER.log(Level.FINER, "activeConfigurationChanged: {0}", config);
151         listeningToCombo = false;
152         try {
153             configListCombo.setSelectedIndex(-1);
154             if (config != null) {
155                 ComboBoxModel JavaDoc m = configListCombo.getModel();
156                 for (int i = 0; i < m.getSize(); i++) {
157                     if (config.equals(m.getElementAt(i))) {
158                         configListCombo.setSelectedIndex(i);
159                         break;
160                     }
161                 }
162             }
163         } finally {
164             listeningToCombo = true;
165         }
166     }
167
168     private synchronized void activeConfigurationSelected(ProjectConfiguration cfg) {
169         LOGGER.log(Level.FINER, "activeConfigurationSelected: {0}", cfg);
170         if (pcp != null && cfg != null && !cfg.equals(getActiveConfiguration(pcp))) {
171             try {
172                 setActiveConfiguration(pcp, cfg);
173             } catch (IOException JavaDoc x) {
174                 LOGGER.log(Level.WARNING, null, x);
175             }
176         }
177     }
178
179     public HelpCtx getHelpCtx() {
180         return new HelpCtx(ActiveConfigAction.class);
181     }
182
183     public String JavaDoc getName() {
184         return NbBundle.getMessage(ActiveConfigAction.class, "ActiveConfigAction.label");
185     }
186
187     public void performAction() {
188         assert false;
189     }
190
191     private JPanel JavaDoc toolbarPanel;
192     public Component JavaDoc getToolbarPresenter() {
193         // Do not return combo box directly; looks bad.
194
toolbarPanel = new JPanel JavaDoc(new GridBagLayout JavaDoc());
195         toolbarPanel.setOpaque(false); // don't interrupt JToolBar background
196
toolbarPanel.setMaximumSize(new Dimension JavaDoc(150, 80));
197         toolbarPanel.setMinimumSize(new Dimension JavaDoc(150, 0));
198         toolbarPanel.setPreferredSize(new Dimension JavaDoc(150, 23));
199         // XXX top inset of 2 looks better w/ small toolbar, but 1 seems to look better for large toolbar (the default):
200
toolbarPanel.add(configListCombo, new GridBagConstraints JavaDoc(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets JavaDoc(1, 6, 1, 5), 0, 0));
201         //toolbarPanel.setVisible( configListCombo.getItemCount() > 0 );
202
toolbarPanel.setEnabled( configListCombo.getItemCount() > 0 );
203         return toolbarPanel;
204     }
205
206     class ConfigMenu extends JMenu JavaDoc implements DynamicMenuContent {
207
208         private final Lookup context;
209
210         public ConfigMenu(Lookup context) {
211             this.context = context;
212             if (context != null) {
213                 Mnemonics.setLocalizedText(this, NbBundle.getMessage(ActiveConfigAction.class, "ActiveConfigAction.context.label"));
214             } else {
215                 Mnemonics.setLocalizedText(this, ActiveConfigAction.this.getName());
216             }
217         }
218
219         public JComponent JavaDoc[] getMenuPresenters() {
220             removeAll();
221             final ProjectConfigurationProvider<?> pcp;
222             if (context != null) {
223                 Collection JavaDoc<? extends Project> projects = context.lookupAll(Project.class);
224                 if (projects.size() == 1) {
225                     pcp = projects.iterator().next().getLookup().lookup(ProjectConfigurationProvider.class);
226                 } else {
227                     // No selection, or multiselection.
228
pcp = null;
229                 }
230             } else {
231                 pcp = ActiveConfigAction.this.pcp; // global menu item; take from main project
232
}
233             if (pcp != null) {
234                 boolean something = false;
235                 ProjectConfiguration activeConfig = getActiveConfiguration(pcp);
236                 for (final ProjectConfiguration config : getConfigurations(pcp)) {
237                     JRadioButtonMenuItem JavaDoc jmi = new JRadioButtonMenuItem JavaDoc(config.getDisplayName(), config.equals(activeConfig));
238                     jmi.addActionListener(new ActionListener JavaDoc() {
239                         public void actionPerformed(ActionEvent JavaDoc e) {
240                             activeConfigurationSelected(config);
241                         }
242                     });
243                     add(jmi);
244                     something = true;
245                 }
246                 if (pcp.hasCustomizer()) {
247                     if (something) {
248                         addSeparator();
249                     }
250                     something = true;
251                     JMenuItem JavaDoc customize = new JMenuItem JavaDoc();
252                     Mnemonics.setLocalizedText(customize, NbBundle.getMessage(ActiveConfigAction.class, "ActiveConfigAction.customize"));
253                     customize.addActionListener(new ActionListener JavaDoc() {
254                         public void actionPerformed(ActionEvent JavaDoc e) {
255                             pcp.customize();
256                         }
257                     });
258                     add(customize);
259                 }
260                 setEnabled(something);
261             } else {
262                 // No configurations supported for this project.
263
setEnabled(false);
264                 // to hide entirely just use: return new JComponent[0];
265
}
266             return new JComponent JavaDoc[] {this};
267         }
268
269         public JComponent JavaDoc[] synchMenuPresenters(JComponent JavaDoc[] items) {
270             // Always rebuild submenu.
271
// For performance, could try to reuse it if context == null and nothing has changed.
272
return getMenuPresenters();
273         }
274
275     }
276
277     public JMenuItem JavaDoc getMenuPresenter() {
278         return new ConfigMenu(null);
279     }
280
281     private static class ConfigCellRenderer extends JLabel JavaDoc implements ListCellRenderer JavaDoc, UIResource JavaDoc {
282         
283         private Border JavaDoc defaultBorder = getBorder();
284         
285         public ConfigCellRenderer () {
286             setOpaque(true);
287         }
288
289         public Component JavaDoc getListCellRendererComponent(JList JavaDoc list, Object JavaDoc value, int index, boolean isSelected, boolean cellHasFocus) {
290             // #89393: GTK needs name to render cell renderer "natively"
291
setName("ComboBox.listRenderer"); // NOI18N
292

293             String JavaDoc label = null;
294             if (value instanceof ProjectConfiguration) {
295                 label = ((ProjectConfiguration) value).getDisplayName();
296                 setBorder (defaultBorder);
297             } else if (value == CUSTOMIZE_ENTRY) {
298                 label = org.openide.awt.Actions.cutAmpersand(
299                         NbBundle.getMessage(ActiveConfigAction.class, "ActiveConfigAction.customize"));
300                 setBorder(BorderFactory.createCompoundBorder(
301                         BorderFactory.createMatteBorder(1, 0, 0, 0,
302                         UIManager.getColor("controlDkShadow")), defaultBorder));
303             } else {
304                 assert value == null;
305                 label = null;
306                 setBorder (defaultBorder);
307             }
308             
309             setText(label);
310             setIcon(null);
311             
312             if ( isSelected ) {
313                 setBackground(list.getSelectionBackground());
314                 setForeground(list.getSelectionForeground());
315             }
316             else {
317                 setBackground(list.getBackground());
318                 setForeground(list.getForeground());
319             }
320             
321             return this;
322         }
323         
324         // #89393: GTK needs name to render cell renderer "natively"
325
public String JavaDoc getName() {
326             String JavaDoc name = super.getName();
327             return name == null ? "ComboBox.renderer" : name; // NOI18N
328
}
329         
330     }
331
332     private synchronized void activeProjectChanged(Project p) {
333         LOGGER.log(Level.FINER, "activeProjectChanged: {0} -> {1}", new Object JavaDoc[] {currentProject, p});
334         if (currentProject != p) {
335             if (pcp != null) {
336                 pcp.removePropertyChangeListener(lst);
337             }
338             currentProject = p;
339             if (currentProject != null) {
340                 pcp = currentProject.getLookup().lookup(ProjectConfigurationProvider.class);
341                 if (pcp != null) {
342                     pcp.addPropertyChangeListener(lst);
343                 }
344             } else {
345                 pcp = null;
346             }
347             configurationsListChanged(pcp == null ? null : getConfigurations(pcp));
348
349         }
350     }
351
352     public Action JavaDoc createContextAwareInstance(final Lookup actionContext) {
353         class A extends AbstractAction JavaDoc implements Presenter.Popup {
354             public void actionPerformed(ActionEvent JavaDoc e) {
355                 assert false;
356             }
357             public JMenuItem JavaDoc getPopupPresenter() {
358                 return new ConfigMenu(actionContext);
359             }
360         }
361         return new A();
362     }
363
364     private static Collection JavaDoc<? extends ProjectConfiguration> getConfigurations(final ProjectConfigurationProvider<?> pcp) {
365         return ProjectManager.mutex().readAccess(new Mutex.Action<Collection JavaDoc<? extends ProjectConfiguration>>() {
366             public Collection JavaDoc<? extends ProjectConfiguration> run() {
367                 return pcp.getConfigurations();
368             }
369         });
370     }
371
372     private static ProjectConfiguration getActiveConfiguration(final ProjectConfigurationProvider<?> pcp) {
373         return ProjectManager.mutex().readAccess(new Mutex.Action<ProjectConfiguration>() {
374             public ProjectConfiguration run() {
375                 return pcp.getActiveConfiguration();
376             }
377         });
378     }
379
380     @SuppressWarnings JavaDoc("unchecked")
381     private static void setActiveConfiguration(ProjectConfigurationProvider<?> pcp, final ProjectConfiguration pc) throws IOException JavaDoc {
382         final ProjectConfigurationProvider _pcp = pcp;
383         try {
384             ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void JavaDoc>() {
385                 public Void JavaDoc run() throws IOException JavaDoc {
386                     _pcp.setActiveConfiguration(pc);
387                     return null;
388                 }
389             });
390         } catch (MutexException e) {
391             throw (IOException JavaDoc) e.getException();
392         }
393     }
394
395 }
396
Popular Tags