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: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.modules.profiler.ui.panels;
042:
043: import org.netbeans.api.progress.ProgressHandle;
044: import org.netbeans.api.project.Project;
045: import org.netbeans.api.project.ui.OpenProjects;
046: import org.netbeans.lib.profiler.client.ClientUtils;
047: import org.netbeans.lib.profiler.ui.UIUtils;
048: import org.netbeans.lib.profiler.ui.components.HTMLTextArea;
049: import org.netbeans.modules.profiler.selector.ui.RootSelectorTree;
050: import org.netbeans.modules.profiler.selector.ui.SelectionTreeView;
051: import org.netbeans.modules.profiler.ui.ProfilerDialogs;
052: import org.netbeans.modules.profiler.utils.IDEUtils;
053: import org.openide.DialogDescriptor;
054: import org.openide.util.Lookup;
055: import org.openide.util.NbBundle;
056: import org.openide.util.RequestProcessor;
057: import java.awt.Color;
058: import java.awt.Container;
059: import java.awt.Dialog;
060: import java.awt.Dimension;
061: import java.awt.FlowLayout;
062: import java.awt.GridBagConstraints;
063: import java.awt.GridBagLayout;
064: import java.awt.Insets;
065: import java.awt.event.ActionEvent;
066: import java.awt.event.ActionListener;
067: import java.awt.event.ItemEvent;
068: import java.awt.event.ItemListener;
069: import java.beans.PropertyChangeEvent;
070: import java.beans.PropertyChangeListener;
071: import java.util.ArrayList;
072: import java.util.Collection;
073: import java.util.HashSet;
074: import java.util.List;
075: import java.util.Set;
076: import java.util.Vector;
077: import javax.swing.BorderFactory;
078: import javax.swing.DefaultComboBoxModel;
079: import javax.swing.JButton;
080: import javax.swing.JCheckBox;
081: import javax.swing.JComboBox;
082: import javax.swing.JLabel;
083: import javax.swing.JPanel;
084: import javax.swing.JScrollPane;
085: import javax.swing.UIManager;
086: import org.netbeans.modules.profiler.selector.ui.ProgressDisplayer;
087:
088: /**
089: *
090: * @author Jaroslav Bachorik
091: */
092: public class SelectRootMethodsPanel extends JPanel {
093: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
094:
095: // -----
096: // I18N String constants
097: private static final String OK_BUTTON_TEXT = NbBundle.getMessage(
098: SelectRootMethodsPanel.class,
099: "SelectRootMethodsPanel_OkButtonText"); // NOI18N
100: private static final String REMOVE_SELECTED_ITEM_TEXT = NbBundle
101: .getMessage(SelectRootMethodsPanel.class,
102: "SelectRootMethodsPanel_RemoveSelectedItemText"); // NOI18N
103: private static final String REMOVE_ALL_ITEM_TEXT = NbBundle
104: .getMessage(SelectRootMethodsPanel.class,
105: "SelectRootMethodsPanel_RemoveAllItemText"); // NOI18N
106: private static final String SELECT_ALL_ITEM_TEXT = NbBundle
107: .getMessage(SelectRootMethodsPanel.class,
108: "SelectRootMethodsPanel_SelectAllItemText"); // NOI18N
109: // -----
110: protected static final Dimension PREFERRED_TOPTREE_DIMENSION = new Dimension(
111: 500, 250);
112: private static SelectRootMethodsPanel instance;
113:
114: //~ Instance fields ----------------------------------------------------------------------------------------------------------
115:
116: private HTMLTextArea hintArea;
117: private JButton okButton;
118: private JCheckBox advancedShowAllProjectsCheckBox;
119: private JComboBox treeBuilderList;
120: private Project currentProject;
121: private RequestProcessor rp = new RequestProcessor(
122: "SRM-UI Processor", 1); // NOI18N
123: private RootSelectorTree advancedLogicalPackageTree;
124:
125: private volatile boolean changingBuilderList = false;
126: private boolean globalMode;
127:
128: //~ Constructors -------------------------------------------------------------------------------------------------------------
129:
130: /** Creates a new instance of SelectRootMethodsPanel */
131: public SelectRootMethodsPanel() {
132: initComponents(this );
133: }
134:
135: //~ Methods ------------------------------------------------------------------------------------------------------------------
136:
137: public static synchronized SelectRootMethodsPanel getDefault() {
138: if (instance == null) {
139: instance = new SelectRootMethodsPanel();
140: }
141:
142: return instance;
143: }
144:
145: public ClientUtils.SourceCodeSelection[] getRootMethods(
146: final Project project,
147: final ClientUtils.SourceCodeSelection[] currentSelection) {
148: this .currentProject = project;
149:
150: advancedLogicalPackageTree.reset();
151:
152: setGlobalMode(project == null);
153:
154: PropertyChangeListener pcl = new PropertyChangeListener() {
155: public void propertyChange(PropertyChangeEvent evt) {
156: refreshBuilderList();
157: }
158: };
159:
160: try {
161: advancedLogicalPackageTree.addPropertyChangeListener(
162: RootSelectorTree.SELECTION_TREE_VIEW_LIST_PROPERTY,
163: pcl);
164:
165: updateSelector(new Runnable() {
166: public void run() {
167: advancedLogicalPackageTree.setup(
168: relevantProjects(), currentSelection);
169: }
170: });
171:
172: final DialogDescriptor dd = new DialogDescriptor(
173: this ,
174: NbBundle.getMessage(this .getClass(),
175: "SelectRootMethodsPanel_Title"), // NOI18N
176: true, new Object[] { okButton,
177: DialogDescriptor.CANCEL_OPTION }, okButton,
178: DialogDescriptor.BOTTOM_ALIGN, null, null);
179:
180: Object[] additionalOptions = getAdditionalOptions();
181:
182: if ((additionalOptions != null)
183: && (additionalOptions.length > 0)) {
184: dd.setAdditionalOptions(additionalOptions);
185: }
186:
187: final Dialog d = ProfilerDialogs.createDialog(dd);
188: d.pack(); // To properly layout HTML hint area
189: d.setVisible(true);
190:
191: // ClientUtils.SourceCodeSelection[] rootMethods = this.currentSelectionSet.toArray(new ClientUtils.SourceCodeSelection[this.currentSelectionSet.size()]);
192: this .currentProject = null;
193:
194: return dd.getValue().equals(okButton) ? advancedLogicalPackageTree
195: .getSelection()
196: : null;
197: } finally {
198: advancedLogicalPackageTree.removePropertyChangeListener(
199: RootSelectorTree.SELECTION_TREE_VIEW_LIST_PROPERTY,
200: pcl);
201: }
202:
203: // this.currentSelectionSet.clear();
204: // return rootMethods;
205: }
206:
207: protected void initComponents(final Container container) {
208: GridBagConstraints gridBagConstraints;
209:
210: okButton = new JButton(OK_BUTTON_TEXT);
211:
212: // advancedLogicalPackageTree = new RootSelectorTree() {
213: // protected SelectionTreeBuilder getBuilder() {
214: // return (SelectionTreeBuilder) treeBuilderList.getSelectedItem();
215: // }
216: // };
217: // advancedLogicalPackageTree = new RootSelectorTree();
218:
219: advancedLogicalPackageTree = new RootSelectorTree(
220: new ProgressDisplayer() {
221: ProfilerProgressDisplayer pd = null;
222:
223: public synchronized void showProgress(String message) {
224: pd = ProfilerProgressDisplayer
225: .showProgress(message);
226: }
227:
228: public synchronized void showProgress(
229: String message,
230: ProgressController controller) {
231: pd = ProfilerProgressDisplayer.showProgress(
232: message, controller);
233: }
234:
235: public synchronized void showProgress(
236: String caption, String message,
237: ProgressController controller) {
238: pd = ProfilerProgressDisplayer.showProgress(
239: caption, message, controller);
240: }
241:
242: public synchronized boolean isOpened() {
243: return pd != null;
244: }
245:
246: public synchronized void close() {
247: if (pd != null) {
248: pd.close();
249: pd = null;
250: }
251: }
252: });
253:
254: advancedShowAllProjectsCheckBox = new JCheckBox();
255: treeBuilderList = new JComboBox();
256: treeBuilderList.addItemListener(new ItemListener() {
257: public void itemStateChanged(final ItemEvent e) {
258: if (changingBuilderList) {
259: return;
260: }
261:
262: if ((currentProject != null)
263: && (e.getStateChange() == ItemEvent.SELECTED)) {
264: rp.post(new Runnable() {
265: public void run() {
266: advancedLogicalPackageTree
267: .setSelectionTreeView((SelectionTreeView) e
268: .getItem());
269:
270: // updateSelectorProjects();
271: }
272: });
273: }
274: }
275: });
276:
277: container.setLayout(new GridBagLayout());
278:
279: hintArea = new HTMLTextArea() {
280: public Dimension getPreferredSize() { // Workaround to force the text area not to consume horizontal space to fit the contents to just one line
281:
282: return new Dimension(1, super .getPreferredSize().height);
283: }
284: };
285:
286: advancedLogicalPackageTree.setRowHeight(UIUtils
287: .getDefaultRowHeight() + 2);
288:
289: JScrollPane advancedLogicalPackageTreeScrollPane = new JScrollPane(
290: advancedLogicalPackageTree);
291: advancedLogicalPackageTreeScrollPane
292: .setPreferredSize(PREFERRED_TOPTREE_DIMENSION);
293:
294: gridBagConstraints = new GridBagConstraints();
295: gridBagConstraints.gridx = 0;
296: gridBagConstraints.gridy = 0;
297: gridBagConstraints.weightx = 1;
298: gridBagConstraints.weighty = 1;
299: gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER;
300: gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
301: gridBagConstraints.fill = GridBagConstraints.BOTH;
302: gridBagConstraints.insets = new Insets(10, 10, 0, 10);
303: container.add(advancedLogicalPackageTreeScrollPane,
304: gridBagConstraints);
305:
306: advancedShowAllProjectsCheckBox.setText(NbBundle.getMessage(
307: this .getClass(),
308: "SelectRootMethodsPanel_ShowAllProjectsLabel")); // NOI18N
309: advancedShowAllProjectsCheckBox
310: .addActionListener(new ActionListener() {
311: public void actionPerformed(ActionEvent e) {
312: rp.post(new Runnable() {
313: public void run() {
314: refreshBuilderList();
315: updateSelectorProjects();
316: }
317: });
318: }
319: });
320:
321: JPanel comboPanel = new JPanel(new FlowLayout());
322: comboPanel.add(new JLabel(NbBundle.getMessage(this .getClass(),
323: "SelectRootMethodsPanel_SelectViewLabel"))); // NOI18N
324: comboPanel.add(treeBuilderList);
325:
326: gridBagConstraints = new GridBagConstraints();
327: gridBagConstraints.gridx = 0;
328: gridBagConstraints.gridy = 1;
329: gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
330: gridBagConstraints.insets = new Insets(5, 10, 5, 10);
331: container.add(comboPanel, gridBagConstraints);
332:
333: gridBagConstraints = new GridBagConstraints();
334: gridBagConstraints.gridx = 1;
335: gridBagConstraints.gridy = 1;
336: gridBagConstraints.anchor = GridBagConstraints.NORTHEAST;
337: gridBagConstraints.insets = new Insets(10, 10, 5, 10);
338: container.add(advancedShowAllProjectsCheckBox,
339: gridBagConstraints);
340:
341: // hintArea
342: String hintString = getHintString();
343:
344: if ((hintString != null) && (hintString.length() > 0)) {
345: Color panelBackground = UIManager
346: .getColor("Panel.background"); //NOI18N
347: Color hintBackground = UIUtils.getSafeColor(panelBackground
348: .getRed() - 10, panelBackground.getGreen() - 10,
349: panelBackground.getBlue() - 10);
350: hintArea.setText(hintString);
351: hintArea.setEnabled(false);
352: hintArea.setDisabledTextColor(Color.darkGray);
353: hintArea.setBackground(hintBackground);
354: hintArea.setBorder(BorderFactory.createMatteBorder(10, 10,
355: 10, 10, hintBackground));
356: gridBagConstraints = new GridBagConstraints();
357: gridBagConstraints.gridx = 0;
358: gridBagConstraints.gridy = 3;
359: gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER;
360: gridBagConstraints.insets = new Insets(5, 10, 5, 10);
361: gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
362: gridBagConstraints.fill = GridBagConstraints.BOTH;
363: container.add(hintArea, gridBagConstraints);
364: }
365: }
366:
367: private Object[] getAdditionalOptions() {
368: return null;
369: }
370:
371: private void setGlobalMode(boolean value) {
372: advancedShowAllProjectsCheckBox.setSelected(value);
373: advancedShowAllProjectsCheckBox.setEnabled(!value);
374: globalMode = value;
375: }
376:
377: private String getHintString() {
378: return null;
379: }
380:
381: private void refreshBuilderList() {
382: List<SelectionTreeView> treeViews = advancedLogicalPackageTree
383: .getSelectionTreeViewList();
384: List<SelectionTreeView> usedTreeViews = new ArrayList<SelectionTreeView>();
385:
386: for (SelectionTreeView view : treeViews) {
387: if (view.isEnabled()) {
388: if (view.isPreferred()) {
389: usedTreeViews.add(0, view);
390: } else {
391: usedTreeViews.add(view);
392: }
393: }
394: }
395:
396: try {
397: changingBuilderList = true;
398:
399: treeBuilderList
400: .setModel(new DefaultComboBoxModel(
401: usedTreeViews
402: .toArray(new SelectionTreeView[usedTreeViews
403: .size()])));
404:
405: treeBuilderList.setSelectedIndex(0);
406: advancedLogicalPackageTree
407: .setSelectionTreeView((SelectionTreeView) treeBuilderList
408: .getItemAt(0));
409: } finally {
410: changingBuilderList = false;
411: }
412: }
413:
414: private Project[] relevantProjects() {
415: return advancedShowAllProjectsCheckBox.isSelected() ? OpenProjects
416: .getDefault().getOpenProjects()
417: : new Project[] { currentProject };
418: }
419:
420: private void updateSelector(Runnable updater) {
421: ProgressHandle ph = IDEUtils
422: .indeterminateProgress(
423: NbBundle
424: .getMessage(this .getClass(),
425: "SelectRootMethodsPanel_ParsingProjectStructureMessage"),
426: 500); // NOI18N
427:
428: try {
429: treeBuilderList.setEnabled(false);
430: advancedLogicalPackageTree.setEnabled(false);
431: advancedShowAllProjectsCheckBox.setEnabled(false);
432: okButton.setEnabled(false);
433: updater.run();
434: } finally {
435: ph.finish();
436: okButton.setEnabled(true);
437: advancedShowAllProjectsCheckBox.setEnabled(!globalMode);
438: advancedLogicalPackageTree.setEnabled(true);
439: treeBuilderList.setEnabled(true);
440: }
441: }
442:
443: private void updateSelectorProjects() {
444: updateSelector(new Runnable() {
445: public void run() {
446: advancedLogicalPackageTree
447: .setProjects(relevantProjects());
448: }
449: });
450: }
451: }
|