~ubuntu-branches/ubuntu/trusty/netbeans/trusty

« back to all changes in this revision

Viewing changes to openide/explorer/src/org/openide/explorer/propertysheet/IndexedEditorPanel.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
package org.openide.explorer.propertysheet;
 
42
 
 
43
import org.openide.awt.Mnemonics;
 
44
import org.openide.explorer.ExplorerManager;
 
45
import org.openide.explorer.view.TreeTableView;
 
46
import org.openide.nodes.Node;
 
47
import org.openide.util.Lookup;
 
48
import org.openide.util.NbBundle;
 
49
import org.openide.util.actions.NodeAction;
 
50
import org.openide.util.actions.SystemAction;
 
51
 
 
52
import java.awt.Component;
 
53
 
 
54
import java.beans.*;
 
55
 
 
56
import javax.swing.Action;
 
57
import javax.swing.JPanel;
 
58
import javax.swing.JScrollPane;
 
59
import javax.swing.Scrollable;
 
60
import javax.swing.UIManager;
 
61
import javax.swing.border.Border;
 
62
 
 
63
 
 
64
/**
 
65
 * Panel displaying indexed properties.
 
66
 * @author  dstrupl@netbeans.org
 
67
 */
 
68
class IndexedEditorPanel extends javax.swing.JPanel implements ExplorerManager.Provider, PropertyChangeListener,
 
69
    Lookup.Provider {
 
70
    private ExplorerManager em;
 
71
 
 
72
    /** lookup for move up and down actions */
 
73
    private Lookup selectedLookup;
 
74
    private Action moveUp;
 
75
    private Action moveDown;
 
76
    private Action newAction;
 
77
    private boolean showingDetails = false;
 
78
    private Node rootNode;
 
79
    private Node.Property prop;
 
80
    private JScrollPane jScrollPane1 = new JScrollPane();
 
81
    private JPanel detailsPanel = new JPanel();
 
82
 
 
83
    // Variables declaration - do not modify//GEN-BEGIN:variables
 
84
    private javax.swing.JButton deleteButton;
 
85
    private javax.swing.JButton detailsButton;
 
86
    private javax.swing.JButton downButton;
 
87
    private javax.swing.JPanel jPanel1;
 
88
    private javax.swing.JPanel jPanel2;
 
89
    private javax.swing.JButton newButton;
 
90
    private javax.swing.JLabel propertiesLabel;
 
91
    private javax.swing.JButton upButton;
 
92
    // End of variables declaration//GEN-END:variables
 
93
    // XXX look into constructor
 
94
    private TreeTableView treeTableView1;
 
95
 
 
96
    /** Creates new form IndexedEditorPanel */
 
97
    public IndexedEditorPanel(Node node, Node.Property[] props) {
 
98
        treeTableView1 = new TreeTableView();
 
99
 
 
100
        // install proper border
 
101
        setBorder((Border) UIManager.get("Nb.ScrollPane.border")); // NOI18N
 
102
        initComponents();
 
103
        propertiesLabel.setLabelFor(treeTableView1);
 
104
 
 
105
        jPanel2.setLayout(new java.awt.BorderLayout());
 
106
        jPanel2.add(treeTableView1);
 
107
 
 
108
        detailsPanel.setLayout(new java.awt.BorderLayout());
 
109
        getExplorerManager().setRootContext(node);
 
110
 
 
111
        rootNode = node;
 
112
        prop = props[0];
 
113
        getExplorerManager().addPropertyChangeListener(this);
 
114
        treeTableView1.setProperties(props);
 
115
        treeTableView1.setRootVisible(false);
 
116
        treeTableView1.setDefaultActionAllowed(false);
 
117
        treeTableView1.setTreePreferredWidth(200);
 
118
 
 
119
        node.addPropertyChangeListener(this);
 
120
 
 
121
        try {
 
122
            selectedLookup = org.openide.util.lookup.Lookups.proxy(this);
 
123
 
 
124
            NodeAction globalMoveUp = SystemAction.get(Class.forName("org.openide.actions.MoveUpAction").asSubclass(NodeAction.class)); // NOI18N
 
125
            NodeAction globalMoveDown = SystemAction.get(Class.forName("org.openide.actions.MoveDownAction").asSubclass(NodeAction.class)); // NOI18N
 
126
            NodeAction globalNewAction = SystemAction.get(Class.forName("org.openide.actions.NewAction").asSubclass(NodeAction.class)); // NOI18N
 
127
 
 
128
            // Get context aware instances.
 
129
            moveUp = globalMoveUp.createContextAwareInstance(selectedLookup);
 
130
            moveDown = globalMoveDown.createContextAwareInstance(selectedLookup);
 
131
            newAction = globalNewAction.createContextAwareInstance(selectedLookup);
 
132
        } catch (ClassNotFoundException cnfe) {
 
133
        }
 
134
 
 
135
        java.util.ResourceBundle bundle = NbBundle.getBundle(IndexedEditorPanel.class);
 
136
        treeTableView1.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_Properties"));
 
137
        newButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_New"));
 
138
        deleteButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_Delete"));
 
139
        upButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_MoveUp"));
 
140
        downButton.getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_MoveDown"));
 
141
        getAccessibleContext().setAccessibleDescription(bundle.getString("ACSD_IndexedEditorPanel"));
 
142
    }
 
143
 
 
144
    public void addNotify() {
 
145
        super.addNotify();
 
146
        updateButtonState();
 
147
    }
 
148
 
 
149
    /** Returns the lookup of currently selected node.
 
150
     */
 
151
    public Lookup getLookup() {
 
152
        Node[] arr = getExplorerManager().getSelectedNodes();
 
153
 
 
154
        return (arr.length == 1) ? arr[0].getLookup() : Lookup.EMPTY;
 
155
    }
 
156
 
 
157
    /** This method is called from within the constructor to
 
158
     * initialize the form.
 
159
     * WARNING: Do NOT modify this code. The content of this method is
 
160
     * always regenerated by the Form Editor.
 
161
     */
 
162
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
 
163
    private void initComponents() {
 
164
        java.awt.GridBagConstraints gridBagConstraints;
 
165
 
 
166
        jPanel1 = new javax.swing.JPanel();
 
167
        newButton = new javax.swing.JButton();
 
168
        deleteButton = new javax.swing.JButton();
 
169
        upButton = new javax.swing.JButton();
 
170
        downButton = new javax.swing.JButton();
 
171
        detailsButton = new javax.swing.JButton();
 
172
        propertiesLabel = new javax.swing.JLabel();
 
173
        jPanel2 = new javax.swing.JPanel();
 
174
 
 
175
        FormListener formListener = new FormListener();
 
176
 
 
177
        setLayout(new java.awt.GridBagLayout());
 
178
 
 
179
        setBorder(javax.swing.BorderFactory.createEmptyBorder(12, 12, 0, 12));
 
180
        jPanel1.setLayout(new java.awt.GridLayout(5, 1, 0, 5));
 
181
 
 
182
        org.openide.awt.Mnemonics.setLocalizedText(newButton, org.openide.util.NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_New"));
 
183
        newButton.addActionListener(formListener);
 
184
 
 
185
        jPanel1.add(newButton);
 
186
 
 
187
        org.openide.awt.Mnemonics.setLocalizedText(deleteButton, org.openide.util.NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_Delete"));
 
188
        deleteButton.addActionListener(formListener);
 
189
 
 
190
        jPanel1.add(deleteButton);
 
191
 
 
192
        org.openide.awt.Mnemonics.setLocalizedText(upButton, org.openide.util.NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_MoveUp"));
 
193
        upButton.addActionListener(formListener);
 
194
 
 
195
        jPanel1.add(upButton);
 
196
 
 
197
        org.openide.awt.Mnemonics.setLocalizedText(downButton, org.openide.util.NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_MoveDown"));
 
198
        downButton.addActionListener(formListener);
 
199
 
 
200
        jPanel1.add(downButton);
 
201
 
 
202
        org.openide.awt.Mnemonics.setLocalizedText(detailsButton, org.openide.util.NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_HideDetails"));
 
203
        detailsButton.addActionListener(formListener);
 
204
 
 
205
        jPanel1.add(detailsButton);
 
206
 
 
207
        gridBagConstraints = new java.awt.GridBagConstraints();
 
208
        gridBagConstraints.gridx = 1;
 
209
        gridBagConstraints.gridy = 1;
 
210
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
 
211
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.RELATIVE;
 
212
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
 
213
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 11, 0);
 
214
        add(jPanel1, gridBagConstraints);
 
215
 
 
216
        org.openide.awt.Mnemonics.setLocalizedText(propertiesLabel, org.openide.util.NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_Properties"));
 
217
        gridBagConstraints = new java.awt.GridBagConstraints();
 
218
        gridBagConstraints.gridx = 0;
 
219
        gridBagConstraints.gridy = 0;
 
220
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
 
221
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
 
222
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 11);
 
223
        add(propertiesLabel, gridBagConstraints);
 
224
 
 
225
        gridBagConstraints = new java.awt.GridBagConstraints();
 
226
        gridBagConstraints.gridx = 0;
 
227
        gridBagConstraints.gridy = 1;
 
228
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
 
229
        gridBagConstraints.weightx = 1.0;
 
230
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 11, 11);
 
231
        add(jPanel2, gridBagConstraints);
 
232
 
 
233
    }
 
234
 
 
235
    // Code for dispatching events from components to event handlers.
 
236
 
 
237
    private class FormListener implements java.awt.event.ActionListener {
 
238
        public void actionPerformed(java.awt.event.ActionEvent evt) {
 
239
            if (evt.getSource() == newButton) {
 
240
                IndexedEditorPanel.this.newButtonActionPerformed(evt);
 
241
            }
 
242
            else if (evt.getSource() == deleteButton) {
 
243
                IndexedEditorPanel.this.deleteButtonActionPerformed(evt);
 
244
            }
 
245
            else if (evt.getSource() == upButton) {
 
246
                IndexedEditorPanel.this.upButtonActionPerformed(evt);
 
247
            }
 
248
            else if (evt.getSource() == downButton) {
 
249
                IndexedEditorPanel.this.downButtonActionPerformed(evt);
 
250
            }
 
251
            else if (evt.getSource() == detailsButton) {
 
252
                IndexedEditorPanel.this.detailsButtonActionPerformed(evt);
 
253
            }
 
254
        }
 
255
    }// </editor-fold>//GEN-END:initComponents
 
256
 
 
257
    private void detailsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_detailsButtonActionPerformed
 
258
        showingDetails = !showingDetails;
 
259
 
 
260
        if (showingDetails && !this.equals(detailsPanel.getParent())) {
 
261
            initDetails();
 
262
        }
 
263
 
 
264
        updateButtonState();
 
265
        updateDetailsPanel();
 
266
    }
 
267
//GEN-LAST:event_detailsButtonActionPerformed
 
268
 
 
269
    private void newButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newButtonActionPerformed
 
270
 
 
271
        try {
 
272
            getExplorerManager().setSelectedNodes(new Node[] { rootNode });
 
273
        } catch (PropertyVetoException pve) {
 
274
            // this should be always possible --> if not, notify problem
 
275
            PropertyDialogManager.notify(pve);
 
276
        }
 
277
 
 
278
        if ((newAction != null) && (newAction.isEnabled())) {
 
279
            newAction.actionPerformed(evt);
 
280
        }
 
281
    }
 
282
//GEN-LAST:event_newButtonActionPerformed
 
283
 
 
284
    private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
 
285
 
 
286
        Node[] sn = getExplorerManager().getSelectedNodes();
 
287
 
 
288
        if ((sn == null) || (sn.length != 1) || (sn[0] == rootNode)) {
 
289
            return;
 
290
        }
 
291
 
 
292
        try {
 
293
            sn[0].destroy();
 
294
        } catch (java.io.IOException ioe) {
 
295
            PropertyDialogManager.notify(ioe);
 
296
        }
 
297
 
 
298
        rootNode = getExplorerManager().getRootContext();
 
299
    }
 
300
//GEN-LAST:event_deleteButtonActionPerformed
 
301
 
 
302
    private void downButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downButtonActionPerformed
 
303
 
 
304
        Node[] sn = getExplorerManager().getSelectedNodes();
 
305
 
 
306
        if ((moveDown != null) && (moveDown.isEnabled())) {
 
307
            moveDown.actionPerformed(evt);
 
308
        }
 
309
 
 
310
        if ((sn == null) || (sn.length != 1) || (sn[0] == rootNode)) {
 
311
            return;
 
312
        }
 
313
 
 
314
        try {
 
315
            getExplorerManager().setSelectedNodes(sn);
 
316
        } catch (PropertyVetoException pve) {
 
317
        }
 
318
    }
 
319
//GEN-LAST:event_downButtonActionPerformed
 
320
 
 
321
    private void upButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_upButtonActionPerformed
 
322
 
 
323
        Node[] sn = getExplorerManager().getSelectedNodes();
 
324
 
 
325
        if ((moveUp != null) && (moveUp.isEnabled())) {
 
326
            moveUp.actionPerformed(evt);
 
327
        }
 
328
 
 
329
        if ((sn == null) || (sn.length != 1) || (sn[0] == rootNode)) {
 
330
            return;
 
331
        }
 
332
 
 
333
        try {
 
334
            getExplorerManager().setSelectedNodes(sn);
 
335
        } catch (PropertyVetoException pve) {
 
336
        }
 
337
    }
 
338
//GEN-LAST:event_upButtonActionPerformed
 
339
 
 
340
    public synchronized ExplorerManager getExplorerManager() {
 
341
        if (em == null) {
 
342
            em = new ExplorerManager();
 
343
        }
 
344
 
 
345
        return em;
 
346
    }
 
347
 
 
348
    private void updateButtonState() {
 
349
        // refresh the lookup
 
350
        selectedLookup.lookup(Object.class);
 
351
 
 
352
        if (showingDetails) {
 
353
            detailsButton.setText(NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_HideDetails"));
 
354
        } else {
 
355
            detailsButton.setText(NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_ShowDetails"));
 
356
        }
 
357
 
 
358
        upButton.setEnabled((moveUp != null) && (moveUp.isEnabled()));
 
359
        downButton.setEnabled((moveDown != null) && (moveDown.isEnabled()));
 
360
 
 
361
        Node[] sn = getExplorerManager().getSelectedNodes();
 
362
        deleteButton.setEnabled((sn != null) && (sn.length == 1) && (sn[0] != rootNode));
 
363
        detailsButton.setVisible(
 
364
            (prop != null) && (prop.getPropertyEditor() != null) && (prop.getPropertyEditor().supportsCustomEditor())
 
365
        );
 
366
 
 
367
        if (detailsButton.isVisible()) {
 
368
            if (showingDetails) {
 
369
                Mnemonics.setLocalizedText(detailsButton, NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_HideDetails"));
 
370
                detailsButton.getAccessibleContext().setAccessibleDescription(
 
371
                    NbBundle.getBundle(IndexedEditorPanel.class).getString("ACSD_HideDetails")
 
372
                );
 
373
            } else {
 
374
                Mnemonics.setLocalizedText(detailsButton, NbBundle.getBundle(IndexedEditorPanel.class).getString("CTL_ShowDetails"));
 
375
                detailsButton.getAccessibleContext().setAccessibleDescription(
 
376
                    NbBundle.getBundle(IndexedEditorPanel.class).getString("ACSD_ShowDetails")
 
377
                );
 
378
            }
 
379
 
 
380
            detailsButton.setEnabled((sn != null) && (sn.length == 1) && (sn[0] != rootNode));
 
381
        }
 
382
    }
 
383
 
 
384
    private void updateDetailsPanel() {
 
385
        detailsPanel.removeAll();
 
386
 
 
387
        if (!showingDetails) {
 
388
            remove(detailsPanel);
 
389
            revalidateDetailsPanel();
 
390
 
 
391
            return;
 
392
        }
 
393
 
 
394
        Node[] selN = getExplorerManager().getSelectedNodes();
 
395
 
 
396
        if ((selN == null) || (selN.length == 0)) {
 
397
            revalidateDetailsPanel();
 
398
 
 
399
            return;
 
400
        }
 
401
 
 
402
        Node n = selN[0];
 
403
 
 
404
        if (n == rootNode) {
 
405
            revalidateDetailsPanel();
 
406
 
 
407
            return;
 
408
        }
 
409
 
 
410
        if (selN.length > 1) {
 
411
            n = new ProxyNode(selN);
 
412
        }
 
413
 
 
414
        // beware - this will function only if the DisplayIndexedNode has
 
415
        // one property on the first sheet and the property is of type
 
416
        // ValueProp
 
417
        Node.Property prop = n.getPropertySets()[0].getProperties()[0];
 
418
        PropertyPanel p = new PropertyPanel(prop);
 
419
        p.setPreferences(PropertyPanel.PREF_CUSTOM_EDITOR);
 
420
 
 
421
        if (isEditorScrollable(p)) {
 
422
            detailsPanel.add(p, java.awt.BorderLayout.CENTER);
 
423
        } else {
 
424
            jScrollPane1.setViewportView(p);
 
425
            detailsPanel.add(jScrollPane1, java.awt.BorderLayout.CENTER);
 
426
        }
 
427
 
 
428
        revalidateDetailsPanel();
 
429
    }
 
430
 
 
431
    private void revalidateDetailsPanel() {
 
432
        detailsPanel.invalidate();
 
433
        repaint();
 
434
 
 
435
        if (detailsPanel.getParent() != null) {
 
436
            detailsPanel.getParent().validate();
 
437
        } else {
 
438
            detailsPanel.validate();
 
439
        }
 
440
    }
 
441
 
 
442
    /**
 
443
     * This method gets called when a bound property is changed.
 
444
     * @param evt A PropertyChangeEvent object describing the event source
 
445
     *          and the property that has changed.
 
446
     */
 
447
    public void propertyChange(PropertyChangeEvent evt) {
 
448
        if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) {
 
449
            updateButtonState();
 
450
            updateDetailsPanel();
 
451
        }
 
452
    }
 
453
 
 
454
    private void initDetails() {
 
455
        java.awt.GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
 
456
        gridBagConstraints.gridx = 0;
 
457
        gridBagConstraints.gridy = 2;
 
458
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
 
459
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
 
460
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
 
461
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
 
462
        gridBagConstraints.weighty = 1.0;
 
463
        add(detailsPanel, gridBagConstraints);
 
464
    }
 
465
 
 
466
    private boolean isEditorScrollable(PropertyPanel p) {
 
467
        Component[] comps = p.getComponents();
 
468
 
 
469
        for (int i = 0; i < comps.length; i++) {
 
470
            if (comps[i] instanceof Scrollable || isInstanceOfTopComponent(comps[i])) {
 
471
                return true;
 
472
            }
 
473
        }
 
474
 
 
475
        return false;
 
476
    }
 
477
 
 
478
    /** Checks whether an object is instanceof TopComponent
 
479
     * @param obj the object
 
480
     * @return true or false
 
481
     */
 
482
    private static boolean isInstanceOfTopComponent(Object obj) {
 
483
        ClassLoader l = org.openide.util.Lookup.getDefault().lookup(ClassLoader.class);
 
484
 
 
485
        if (l == null) {
 
486
            l = IndexedEditorPanel.class.getClassLoader();
 
487
        }
 
488
 
 
489
        try {
 
490
            Class c = Class.forName("org.openide.windows.TopComponent", true, l); // NOI18N
 
491
 
 
492
            return c.isInstance(obj);
 
493
        } catch (Exception ex) {
 
494
            return false;
 
495
        }
 
496
    }
 
497
}