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