Source Code Cross Referenced for TreeTableView.java in  » IDE-Netbeans » openide » org » openide » explorer » view » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » openide » org.openide.explorer.view 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:        package org.openide.explorer.view;
0042:
0043:        import java.util.logging.Logger;
0044:        import org.openide.awt.MouseUtils;
0045:        import org.openide.nodes.Node;
0046:        import org.openide.nodes.Node.Property;
0047:        import org.openide.util.NbBundle;
0048:        import org.openide.explorer.ExplorerManager;
0049:        import org.openide.explorer.ExplorerManager.Provider;
0050:        import org.openide.explorer.ExplorerUtils;
0051:
0052:        import java.awt.*;
0053:        import java.awt.event.*;
0054:
0055:        import java.beans.PropertyChangeEvent;
0056:        import java.beans.PropertyChangeListener;
0057:
0058:        import java.util.ArrayList;
0059:        import java.util.Comparator;
0060:        import java.util.Enumeration;
0061:        import java.util.HashSet;
0062:        import java.util.Iterator;
0063:        import java.util.logging.Level;
0064:
0065:        import javax.accessibility.AccessibleContext;
0066:
0067:        import javax.swing.*;
0068:        import javax.swing.border.Border;
0069:        import javax.swing.event.*;
0070:        import javax.swing.plaf.metal.MetalScrollBarUI;
0071:        import javax.swing.table.*;
0072:        import javax.swing.tree.*;
0073:        import org.openide.explorer.view.TreeView.PopupAdapter;
0074:        import org.openide.explorer.view.TreeView.PopupSupport;
0075:        import org.openide.explorer.view.TreeView.TreePropertyListener;
0076:
0077:        /** Explorer view. Allows to view tree of nodes on the left
0078:         * and its properties in table on the right.
0079:         * <p>
0080:         * The main mechanism for setting what properties are displayed is
0081:         * <a href="#setProperties"><code>setProperties (Node.Property[])</code></a>.
0082:         * Pass this method an
0083:         * array of properties.  These will act as a template, and properties of
0084:         * the displayed nodes which share the same <i>name</i> will be used in
0085:         * the columns of the table.
0086:         *
0087:         * You can customize behaviour
0088:         * of property columns using <code>Property.setValue (String parameter,
0089:         * Object value)</code>.  For example,
0090:         * assume you have following array of properties:
0091:         * <br><code>org.openide.nodes.Node.Property[] properties</code><br>
0092:         *
0093:         * if you need second column to be initially invisible in TreeTableView, you
0094:         * should set its custom parameter:
0095:         * <br><code>properties[1].setValue ("InvisibleInTreeTableView", Boolean.TRUE);</code>
0096:         *
0097:         * <TABLE border="1" summary="custom parameter list">
0098:         *     <TR>
0099:         *         <TH> Parameter name
0100:         *         </TH>
0101:         *         <TH> Parameter type
0102:         *         </TH>
0103:         *         <TH> Description
0104:         *         </TH>
0105:         *     </TR>
0106:         *     <TR>
0107:         *         <TD> InvisibleInTreeTableView</TD>
0108:         *         <TD> Boolean </TD>
0109:         *         <TD> This property column should be initially invisible (hidden).</TD>
0110:         *     </TR>
0111:         *     <TR>
0112:         *         <TD> ComparableColumnTTV</TD>
0113:         *         <TD> Boolean </TD>
0114:         *         <TD> This property column should be  used for sorting.</TD>
0115:         *     </TR>
0116:         *     <TR>
0117:         *         <TD> SortingColumnTTV</TD>
0118:         *         <TD> Boolean </TD>
0119:         *         <TD> TreeTableView should be initially sorted by this property column.</TD>
0120:         *     </TR>
0121:         *     <TR>
0122:         *         <TD> DescendingOrderTTV</TD>
0123:         *         <TD> Boolean </TD>
0124:         *         <TD> If this parameter and <code>SortingColumnTTV</code> is set, TreeTableView should
0125:         *              be initially sorted by this property columns in descending order.
0126:         *         </TD>
0127:         *     </TR>
0128:         *     <TR>
0129:         *         <TD> OrderNumberTTV</TD>
0130:         *         <TD> Integer </TD>
0131:         *         <TD> If this parameter is set to <code>N</code>, this property column will be
0132:         *             displayed as Nth column of table. If not set, column will be
0133:         *             displayed in natural order.
0134:         *         </TD>
0135:         *     </TR>
0136:         *     <TR>
0137:         *         <TD> TreeColumnTTV</TD>
0138:         *         <TD> Boolean </TD>
0139:         *         <TD> Identifies special property representing first (tree) column. To allow setting
0140:         *             of <code>SortingColumnTTV, DescendingOrderTTV, ComparableColumnTTV</code> parameters
0141:         *             also for first (tree) column, use this special parameter and add
0142:         *             this property to Node.Property[] array before calling
0143:         *             TreeTableView.setProperties (Node.Property[]).
0144:         *         </TD>
0145:         *     </TR>
0146:         *    <TR>
0147:         *        <TD> ColumnMnemonicCharTTV</TD>
0148:         *        <TD> String </TD>
0149:         *        <TD> When set, this parameter contains the mnemonic character for column's
0150:         *            display name (e.g. in <I>Change Visible Columns</I> dialog window).
0151:         *            If not set, no mnemonic will be displayed.
0152:         *        </TD>
0153:         *    </TR>
0154:         *    <TR>
0155:         *        <TD> ColumnDisplayNameWithMnemonicTTV</TD>
0156:         *        <TD> String </TD>
0157:         *        <TD> When set, this parameter contains column's display name with
0158:         *              '&amp;' as the mnemonic. This parameter should be preferred over
0159:         *              ColumnMnemonicCharTTV.
0160:         *        </TD>
0161:         *    </TR>
0162:         * </TABLE>
0163:         *
0164:         * <p>
0165:         * This class is a <q>view</q>
0166:         * to use it properly you need to add it into a component which implements
0167:         * {@link Provider}. Good examples of that can be found 
0168:         * in {@link ExplorerUtils}. Then just use 
0169:         * {@link Provider#getExplorerManager} call to get the {@link ExplorerManager}
0170:         * and control its state.
0171:         * </p>
0172:         * <p>
0173:         * There can be multiple <q>views</q> under one container implementing {@link Provider}. Select from
0174:         * range of predefined ones or write your own:
0175:         * </p>
0176:         * <ul>
0177:         *      <li>{@link org.openide.explorer.view.BeanTreeView} - shows a tree of nodes</li>
0178:         *      <li>{@link org.openide.explorer.view.ContextTreeView} - shows a tree of nodes without leaf nodes</li>
0179:         *      <li>{@link org.openide.explorer.view.ListView} - shows a list of nodes</li>
0180:         *      <li>{@link org.openide.explorer.view.IconView} - shows a rows of nodes with bigger icons</li>
0181:         *      <li>{@link org.openide.explorer.view.ChoiceView} - creates a combo box based on the explored nodes</li>
0182:         *      <li>{@link org.openide.explorer.view.TreeTableView} - shows tree of nodes together with a set of their {@link Property}</li>
0183:         *      <li>{@link org.openide.explorer.view.MenuView} - can create a {@link JMenu} structure based on structure of {@link Node}s</li>
0184:         * </ul>
0185:         * <p>
0186:         * All of these views use {@link ExplorerManager#find} to walk up the AWT hierarchy and locate the
0187:         * {@link ExplorerManager} to use as a controler. They attach as listeners to
0188:         * it and also call its setter methods to update the shared state based on the
0189:         * user action. Not all views make sence together, but for example
0190:         * {@link org.openide.explorer.view.ContextTreeView} and {@link org.openide.explorer.view.ListView} were designed to complement
0191:         * themselves and behaves like windows explorer. The {@link org.openide.explorer.propertysheet.PropertySheetView}
0192:         * for example should be able to work with any other view.
0193:         * </p>
0194:         *
0195:         * @author  jrojcek
0196:         * @since 1.7
0197:         */
0198:        public class TreeTableView extends BeanTreeView {
0199:            // icon of column button
0200:            private static final String COLUMNS_ICON = "/org/netbeans/modules/openide/explorer/columns.gif"; // NOI18N
0201:
0202:            // icons of ascending/descending order in column header
0203:            private static final String SORT_ASC_ICON = "org/netbeans/modules/openide/explorer/columnsSortedAsc.gif"; // NOI18N
0204:            private static final String SORT_DESC_ICON = "org/netbeans/modules/openide/explorer/columnsSortedDesc.gif"; // NOI18N
0205:
0206:            /** The table */
0207:            protected JTable treeTable;
0208:            private NodeTableModel tableModel;
0209:
0210:            // Tree scroll support
0211:            private JScrollBar hScrollBar;
0212:            private JScrollPane scrollPane;
0213:            private ScrollListener listener;
0214:
0215:            // hiding columns allowed
0216:            private boolean allowHideColumns = false;
0217:
0218:            // sorting by column allowed
0219:            private boolean allowSortingByColumn = false;
0220:
0221:            // hide horizontal scrollbar
0222:            private boolean hideHScrollBar = false;
0223:
0224:            // button in corner of scroll pane
0225:            private JButton colsButton = null;
0226:
0227:            // tree model with sorting support
0228:            private SortedNodeTreeModel sortedNodeTreeModel;
0229:
0230:            /** Listener on keystroke to invoke default action */
0231:            private ActionListener defaultTreeActionListener;
0232:
0233:            // default treetable header renderer
0234:            private TableCellRenderer defaultHeaderRenderer = null;
0235:            private MouseUtils.PopupMouseAdapter tableMouseListener;
0236:
0237:            /** Accessible context of this class (implemented by inner class AccessibleTreeTableView). */
0238:            private AccessibleContext accessContext;
0239:            private TreeColumnProperty treeColumnProperty = new TreeColumnProperty();
0240:            private int treeColumnWidth;
0241:            private Component treeTableParent = null;
0242:
0243:            /** Create TreeTableView with default NodeTableModel
0244:             */
0245:            public TreeTableView() {
0246:                this (new NodeTableModel());
0247:            }
0248:
0249:            /** Creates TreeTableView with provided NodeTableModel.
0250:             * @param ntm node table model
0251:             */
0252:            public TreeTableView(NodeTableModel ntm) {
0253:                tableModel = ntm;
0254:
0255:                initializeTreeTable();
0256:                setPopupAllowed(true);
0257:                setDefaultActionAllowed(true);
0258:
0259:                initializeTreeScrollSupport();
0260:
0261:                // add scrollbar and scrollpane into a panel
0262:                JPanel p = new CompoundScrollPane();
0263:                p.setLayout(new BorderLayout());
0264:                scrollPane.setViewportView(treeTable);
0265:                p.add(BorderLayout.CENTER, scrollPane);
0266:
0267:                ImageIcon ic = new ImageIcon(TreeTable.class
0268:                        .getResource(COLUMNS_ICON)); // NOI18N
0269:                colsButton = new javax.swing.JButton(ic);
0270:                colsButton.addActionListener(new ActionListener() {
0271:                    public void actionPerformed(ActionEvent evt) {
0272:                        selectVisibleColumns();
0273:                    }
0274:                });
0275:
0276:                JPanel sbp = new JPanel();
0277:                sbp.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
0278:                sbp.add(hScrollBar);
0279:                p.add(BorderLayout.SOUTH, sbp);
0280:
0281:                super 
0282:                        .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
0283:                super 
0284:                        .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
0285:                setViewportView(p);
0286:                setBorder(BorderFactory.createEmptyBorder()); //NOI18N
0287:                setViewportBorder(BorderFactory.createEmptyBorder()); //NOI18N
0288:            }
0289:
0290:            public void setRowHeader(JViewport rowHeader) {
0291:                rowHeader.setBorder(BorderFactory.createEmptyBorder());
0292:                super .setRowHeader(rowHeader);
0293:            }
0294:
0295:            /* Overriden to allow hide special horizontal scrollbar
0296:             */
0297:            public void setHorizontalScrollBarPolicy(int policy) {
0298:                hideHScrollBar = (policy == JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
0299:
0300:                if (hideHScrollBar) {
0301:                    hScrollBar.setVisible(false);
0302:                    ((TreeTable) treeTable).setTreeHScrollingEnabled(false);
0303:                }
0304:            }
0305:
0306:            /* Overriden to delegate policy of vertical scrollbar to inner scrollPane
0307:             */
0308:            public void setVerticalScrollBarPolicy(int policy) {
0309:                if (scrollPane == null) {
0310:                    return;
0311:                }
0312:
0313:                allowHideColumns = (policy == JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
0314:
0315:                if (allowHideColumns) {
0316:                    scrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER,
0317:                            colsButton);
0318:                }
0319:
0320:                treeTable.getTableHeader().setReorderingAllowed(
0321:                        allowHideColumns);
0322:
0323:                scrollPane.setVerticalScrollBarPolicy(policy);
0324:            }
0325:
0326:            protected NodeTreeModel createModel() {
0327:                return getSortedNodeTreeModel();
0328:            }
0329:
0330:            /** Requests focus for the tree component. Overrides superclass method. */
0331:            public void requestFocus() {
0332:                if (treeTable != null) {
0333:                    treeTable.requestFocus();
0334:                }
0335:            }
0336:
0337:            public boolean requestFocusInWindow() {
0338:                boolean res = super .requestFocusInWindow();
0339:
0340:                //#44856: pass the focus request to the treetable as well 
0341:                if (null != treeTable) {
0342:                    treeTable.requestFocus();
0343:                }
0344:
0345:                return res;
0346:            }
0347:
0348:            /* Sets sorting ability
0349:             */
0350:            private void setAllowSortingByColumn(boolean allow) {
0351:                if (allow && (allow != allowSortingByColumn)) {
0352:                    addMouseListener(new MouseAdapter() {
0353:                        public void mouseClicked(MouseEvent evt) {
0354:                            // Check whether it was really a click
0355:                            if (evt.getClickCount() == 0)
0356:                                return;
0357:                            Component c = evt.getComponent();
0358:
0359:                            if (c instanceof  JTableHeader) {
0360:                                JTableHeader h = (JTableHeader) c;
0361:                                int index = h.columnAtPoint(evt.getPoint());
0362:
0363:                                //issue 38442, column can be -1 if this is the
0364:                                //upper right corner - there's no column there,
0365:                                //so make sure it's an index >=0.
0366:                                if (index >= 0) {
0367:                                    clickOnColumnAction(index - 1);
0368:                                }
0369:                            }
0370:                        }
0371:                    });
0372:                }
0373:
0374:                allowSortingByColumn = allow;
0375:            }
0376:
0377:            /* Change sorting after clicking on comparable column header.
0378:             * Cycle through ascending -> descending -> no sort -> (start over)
0379:             */
0380:            private void clickOnColumnAction(int index) {
0381:                if (index == -1) {
0382:                    if (treeColumnProperty.isComparable()) {
0383:                        if (treeColumnProperty.isSortingColumn()) {
0384:                            if (!treeColumnProperty.isSortOrderDescending()) {
0385:                                setSortingOrder(false);
0386:                            } else {
0387:                                noSorting();
0388:                            }
0389:                        } else {
0390:                            int realIndex = tableModel
0391:                                    .translateVisibleColumnIndex(index);
0392:                            setSortingColumn(index);
0393:                            setSortingOrder(true);
0394:                        }
0395:                    }
0396:                } else if (tableModel.isComparableColumn(index)) {
0397:                    if (tableModel.isSortingColumnEx(tableModel
0398:                            .translateVisibleColumnIndex(index))) {
0399:                        if (!tableModel.isSortOrderDescending()) {
0400:                            setSortingOrder(false);
0401:                        } else {
0402:                            noSorting();
0403:                        }
0404:                    } else {
0405:                        int realIndex = tableModel
0406:                                .translateVisibleColumnIndex(index);
0407:                        setSortingColumn(realIndex);
0408:                        setSortingOrder(true);
0409:                    }
0410:                }
0411:            }
0412:
0413:            private void selectVisibleColumns() {
0414:                setCurrentWidths();
0415:
0416:                String viewName = null;
0417:
0418:                if (getParent() != null) {
0419:                    viewName = getParent().getName();
0420:                }
0421:
0422:                if (tableModel.selectVisibleColumns(viewName, treeTable
0423:                        .getColumnName(0), getSortedNodeTreeModel()
0424:                        .getRootDescription())) {
0425:                    if (tableModel.getSortingColumn() == -1) {
0426:                        getSortedNodeTreeModel().setSortedByProperty(null);
0427:                    }
0428:
0429:                    setTreePreferredWidth(treeColumnWidth);
0430:
0431:                    for (int i = 0; i < tableModel.getColumnCount(); i++) {
0432:                        setTableColumnPreferredWidth(tableModel
0433:                                .getArrayIndex(i), tableModel
0434:                                .getVisibleColumnWidth(i));
0435:                    }
0436:                }
0437:            }
0438:
0439:            private void setCurrentWidths() {
0440:                treeColumnWidth = treeTable.getColumnModel().getColumn(0)
0441:                        .getWidth();
0442:
0443:                for (int i = 0; i < tableModel.getColumnCount(); i++) {
0444:                    int w = treeTable.getColumnModel().getColumn(i + 1)
0445:                            .getWidth();
0446:                    tableModel.setVisibleColumnWidth(i, w);
0447:                }
0448:            }
0449:
0450:            /** Do not initialize tree now. We will do it from our constructor.
0451:             * [dafe] Used probably because this method is called *before* superclass
0452:             * is fully created (constructor finished) which is horrible but I don't
0453:             * have enough knowledge about this code to change it.
0454:             */
0455:            void initializeTree() {
0456:            }
0457:
0458:            /** Initialize tree and treeTable.
0459:             */
0460:            private void initializeTreeTable() {
0461:                treeModel = createModel();
0462:                treeTable = new TreeTable(treeModel, tableModel);
0463:                tree = ((TreeTable) treeTable).getTree();
0464:
0465:                defaultHeaderRenderer = treeTable.getTableHeader()
0466:                        .getDefaultRenderer();
0467:                treeTable.getTableHeader().setDefaultRenderer(
0468:                        new SortingHeaderRenderer());
0469:
0470:                // init listener & attach it to closing of
0471:                managerListener = new TreePropertyListener();
0472:                tree.addTreeExpansionListener(managerListener);
0473:
0474:                // add listener to sort a new expanded folders
0475:                tree.addTreeExpansionListener(new TreeExpansionListener() {
0476:                    public void treeExpanded(TreeExpansionEvent event) {
0477:                        TreePath path = event.getPath();
0478:
0479:                        if (path != null) {
0480:                            // bugfix $32480, store and recover currently expanded subnodes
0481:                            // store expanded paths
0482:                            Enumeration en = TreeTableView.this .tree
0483:                                    .getExpandedDescendants(path);
0484:
0485:                            // sort children
0486:                            getSortedNodeTreeModel().sortChildren(
0487:                                    (VisualizerNode) path
0488:                                            .getLastPathComponent(), true);
0489:
0490:                            // expand again folders
0491:                            while (en.hasMoreElements()) {
0492:                                TreeTableView.this .tree
0493:                                        .expandPath((TreePath) en.nextElement());
0494:                            }
0495:                        }
0496:                    }
0497:
0498:                    public void treeCollapsed(TreeExpansionEvent event) {
0499:                        // ignore it
0500:                    }
0501:                });
0502:
0503:                defaultActionListener = new PopupSupport();
0504:                Action popupWrapper = new AbstractAction() {
0505:                    public void actionPerformed(ActionEvent evt) {
0506:                        SwingUtilities.invokeLater(defaultActionListener);
0507:                    }
0508:
0509:                    public boolean isEnabled() {
0510:                        return treeTable.isFocusOwner() || tree.isFocusOwner();
0511:                    }
0512:                };
0513:
0514:                treeTable.getInputMap(JTree.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
0515:                        .put(
0516:                                KeyStroke.getKeyStroke(KeyEvent.VK_F10,
0517:                                        KeyEvent.SHIFT_DOWN_MASK),
0518:                                "org.openide.actions.PopupAction");
0519:                treeTable.getActionMap().put("org.openide.actions.PopupAction",
0520:                        popupWrapper);
0521:                tree.addMouseListener(defaultActionListener);
0522:
0523:                tableMouseListener = new MouseUtils.PopupMouseAdapter() {
0524:                    public void showPopup(MouseEvent mevt) {
0525:                        if (isPopupAllowed()) {
0526:                            if (mevt.getY() > treeTable.getHeight()) {
0527:                                // clear selection, if click under the table
0528:                                treeTable.clearSelection();
0529:                            } else {
0530:                                int selRow = treeTable.rowAtPoint(mevt
0531:                                        .getPoint());
0532:                                boolean isAlreadySelected = false;
0533:                                int[] currentSelection = tree
0534:                                        .getSelectionRows();
0535:                                for (int i = 0; null != currentSelection
0536:                                        && i < currentSelection.length; i++) {
0537:                                    if (selRow == currentSelection[i]) {
0538:                                        isAlreadySelected = true;
0539:                                        break;
0540:                                    }
0541:                                }
0542:                                if (!isAlreadySelected)
0543:                                    tree.setSelectionRow(selRow);
0544:                            }
0545:
0546:                            createPopup(mevt);
0547:                        }
0548:                    }
0549:                };
0550:                treeTable.addMouseListener(tableMouseListener);
0551:
0552:                if (UIManager.getColor("control") != null) { // NOI18N
0553:                    treeTable.setGridColor(UIManager.getColor("control")); // NOI18N
0554:                }
0555:            }
0556:
0557:            public void setSelectionMode(int mode) {
0558:                super .setSelectionMode(mode);
0559:
0560:                if (mode == TreeSelectionModel.SINGLE_TREE_SELECTION) {
0561:                    treeTable.getSelectionModel().setSelectionMode(
0562:                            ListSelectionModel.SINGLE_SELECTION);
0563:                } else if (mode == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION) {
0564:                    treeTable.getSelectionModel().setSelectionMode(
0565:                            ListSelectionModel.SINGLE_INTERVAL_SELECTION);
0566:                } else if (mode == TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION) {
0567:                    treeTable.getSelectionModel().setSelectionMode(
0568:                            ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
0569:                }
0570:            }
0571:
0572:            /** Overrides JScrollPane's getAccessibleContext() method to use internal accessible context.
0573:             */
0574:            public AccessibleContext getAccessibleContext() {
0575:                if (accessContext == null) {
0576:                    accessContext = new AccessibleTreeTableView();
0577:                }
0578:
0579:                return accessContext;
0580:            }
0581:
0582:            /** Initialize full support for horizontal scrolling.
0583:             */
0584:            private void initializeTreeScrollSupport() {
0585:                scrollPane = new JScrollPane();
0586:                scrollPane.setName("TreeTableView.scrollpane"); //NOI18N
0587:                scrollPane.setBorder(BorderFactory.createEmptyBorder());
0588:                scrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
0589:
0590:                if (UIManager.getColor("Table.background") != null) { // NOI18N
0591:                    scrollPane.getViewport().setBackground(
0592:                            UIManager.getColor("Table.background")); // NOI18N
0593:                }
0594:
0595:                hScrollBar = new JScrollBar(JScrollBar.HORIZONTAL);
0596:                hScrollBar.putClientProperty(
0597:                        MetalScrollBarUI.FREE_STANDING_PROP, Boolean.FALSE);
0598:                hScrollBar.setVisible(false);
0599:
0600:                listener = new ScrollListener();
0601:
0602:                treeTable.addPropertyChangeListener(listener);
0603:                scrollPane.getViewport().addComponentListener(listener);
0604:                tree.addPropertyChangeListener(listener);
0605:                hScrollBar.getModel().addChangeListener(listener);
0606:            }
0607:
0608:            /* Overriden to work well with treeTable.
0609:             */
0610:            public void setPopupAllowed(boolean value) {
0611:                if (tree == null) {
0612:                    return;
0613:                }
0614:
0615:                if ((popupListener == null) && value) {
0616:                    // on
0617:                    popupListener = new PopupAdapter() {
0618:                        protected void showPopup(MouseEvent e) {
0619:                            int selRow = tree.getClosestRowForLocation(
0620:                                    e.getX(), e.getY());
0621:
0622:                            if (!tree.isRowSelected(selRow)) {
0623:                                tree.setSelectionRow(selRow);
0624:                            }
0625:                        }
0626:                    };
0627:
0628:                    tree.addMouseListener(popupListener);
0629:
0630:                    return;
0631:                }
0632:
0633:                if ((popupListener != null) && !value) {
0634:                    // off
0635:                    tree.removeMouseListener(popupListener);
0636:                    popupListener = null;
0637:
0638:                    return;
0639:                }
0640:            }
0641:
0642:            /* Overriden to work well with treeTable.
0643:             */
0644:            public void setDefaultActionAllowed(boolean value) {
0645:                if (tree == null) {
0646:                    return;
0647:                }
0648:
0649:                defaultActionEnabled = value;
0650:
0651:                if (value) {
0652:                    defaultTreeActionListener = new DefaultTreeAction();
0653:                    treeTable
0654:                            .registerKeyboardAction(defaultTreeActionListener,
0655:                                    KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
0656:                                            0, false), JComponent.WHEN_FOCUSED);
0657:                } else {
0658:                    // Switch off.
0659:                    defaultTreeActionListener = null;
0660:                    treeTable.unregisterKeyboardAction(KeyStroke.getKeyStroke(
0661:                            KeyEvent.VK_ENTER, 0, false));
0662:                }
0663:            }
0664:
0665:            /** Set columns.
0666:             * @param props each column is constructed from Node.Property
0667:             */
0668:            public void setProperties(Property[] props) {
0669:                tableModel.setProperties(props);
0670:                treeColumnProperty
0671:                        .setProperty(tableModel.propertyForColumn(-1));
0672:
0673:                if (treeColumnProperty.isComparable()
0674:                        || tableModel.existsComparableColumn()) {
0675:                    setAllowSortingByColumn(true);
0676:
0677:                    if (treeColumnProperty.isSortingColumn()) {
0678:                        getSortedNodeTreeModel().setSortedByName(true,
0679:                                !treeColumnProperty.isSortOrderDescending());
0680:                    } else {
0681:                        int index = tableModel.getSortingColumn();
0682:
0683:                        if (index != -1) {
0684:                            getSortedNodeTreeModel().setSortedByProperty(
0685:                                    tableModel.propertyForColumnEx(index),
0686:                                    !tableModel.isSortOrderDescending());
0687:                        }
0688:                    }
0689:                }
0690:            }
0691:
0692:            /** Sets resize mode of table.
0693:             *
0694:             * @param mode - One of 5 legal values: <pre>JTable.AUTO_RESIZE_OFF,
0695:             *                                           JTable.AUTO_RESIZE_NEXT_COLUMN,
0696:             *                                           JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS,
0697:             *                                           JTable.AUTO_RESIZE_LAST_COLUMN,
0698:             *                                           JTable.AUTO_RESIZE_ALL_COLUMNS</pre>
0699:             */
0700:            public final void setTableAutoResizeMode(int mode) {
0701:                treeTable.setAutoResizeMode(mode);
0702:            }
0703:
0704:            /** Gets resize mode of table.
0705:             *
0706:             * @return mode - One of 5 legal values: <pre>JTable.AUTO_RESIZE_OFF,
0707:             *                                           JTable.AUTO_RESIZE_NEXT_COLUMN,
0708:             *                                           JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS,
0709:             *                                           JTable.AUTO_RESIZE_LAST_COLUMN,
0710:             *                                           JTable.AUTO_RESIZE_ALL_COLUMNS</pre>
0711:             */
0712:            public final int getTableAutoResizeMode() {
0713:                return treeTable.getAutoResizeMode();
0714:            }
0715:
0716:            /** Sets preferred width of table column
0717:             * @param index column index
0718:             * @param width preferred column width
0719:             */
0720:            public final void setTableColumnPreferredWidth(int index, int width) {
0721:                if (index == -1) {
0722:                    //Issue 47969 - sometimes this is called with a -1 arg
0723:                    return;
0724:                }
0725:
0726:                tableModel.setArrayColumnWidth(index, width);
0727:
0728:                int j = tableModel.getVisibleIndex(index);
0729:
0730:                if (j != -1) {
0731:                    treeTable.getColumnModel().getColumn(j + 1)
0732:                            .setPreferredWidth(width);
0733:                }
0734:            }
0735:
0736:            /** Gets preferred width of table column
0737:             * @param index column index
0738:             * @return preferred column width
0739:             */
0740:            public final int getTableColumnPreferredWidth(int index) {
0741:                int j = tableModel.getVisibleIndex(index);
0742:
0743:                if (j != -1) {
0744:                    return treeTable.getColumnModel().getColumn(j + 1)
0745:                            .getPreferredWidth();
0746:                } else {
0747:                    return tableModel.getArrayColumnWidth(index);
0748:                }
0749:            }
0750:
0751:            /** Set preferred size of tree view
0752:             * @param width preferred width of tree view
0753:             */
0754:            public final void setTreePreferredWidth(int width) {
0755:                treeTable.getColumnModel().getColumn(
0756:                        ((TreeTable) treeTable).getTreeColumnIndex())
0757:                        .setPreferredWidth(width);
0758:            }
0759:
0760:            /** Get preferred size of tree view
0761:             * @return preferred width of tree view
0762:             */
0763:            public final int getTreePreferredWidth() {
0764:                return treeTable.getColumnModel().getColumn(
0765:                        ((TreeTable) treeTable).getTreeColumnIndex())
0766:                        .getPreferredWidth();
0767:            }
0768:
0769:            public void addNotify() {
0770:                // to allow displaying popup also in blank area
0771:                if (treeTable.getParent() != null) {
0772:                    treeTableParent = treeTable.getParent();
0773:                    treeTableParent.addMouseListener(tableMouseListener);
0774:                }
0775:
0776:                super .addNotify();
0777:                if (tableModel.getRowCount() == 0) {
0778:                    //re-attach node listeners
0779:                    Node[] nodes = new Node[tree.getRowCount()];
0780:
0781:                    for (int i = 0; i < tree.getRowCount(); i++) {
0782:                        nodes[i] = Visualizer.findNode(tree.getPathForRow(i)
0783:                                .getLastPathComponent());
0784:                    }
0785:
0786:                    tableModel.setNodes(nodes);
0787:                }
0788:                listener.revalidateScrollBar();
0789:            }
0790:
0791:            public void removeNotify() {
0792:                super .removeNotify();
0793:
0794:                if (treeTableParent != null) { //IndexedEditorPanel
0795:                    treeTableParent.removeMouseListener(tableMouseListener);
0796:                }
0797:
0798:                treeTableParent = null;
0799:
0800:                // clear node listeners
0801:                tableModel.setNodes(new Node[] {});
0802:            }
0803:
0804:            public void addMouseListener(MouseListener l) {
0805:                super .addMouseListener(l);
0806:                treeTable.getTableHeader().addMouseListener(l);
0807:            }
0808:
0809:            public void removeMouseListener(MouseListener l) {
0810:                super .removeMouseListener(l);
0811:                treeTable.getTableHeader().removeMouseListener(l);
0812:            }
0813:
0814:            /**
0815:             * Drag and drop is not supported in TreeTableView.
0816:             */
0817:            public void setDragSource(boolean state) {
0818:            }
0819:
0820:            /**
0821:             * Drag and drop is not supported in TreeTableView.
0822:             */
0823:            public void setDropTarget(boolean state) {
0824:            }
0825:
0826:            /* Overriden to get position for popup invoked by keyboard
0827:             */
0828:            Point getPositionForPopup() {
0829:                int row = treeTable.getSelectedRow();
0830:
0831:                if (row < 0) {
0832:                    return null;
0833:                }
0834:
0835:                int col = treeTable.getSelectedColumn();
0836:
0837:                if (col < 0) {
0838:                    col = 0;
0839:                }
0840:
0841:                Rectangle r = null;
0842:
0843:                if (col == 0) {
0844:                    r = tree.getRowBounds(row);
0845:                } else {
0846:                    r = treeTable.getCellRect(row, col, true);
0847:                }
0848:
0849:                Point p = SwingUtilities
0850:                        .convertPoint(treeTable, r.x, r.y, this );
0851:
0852:                return p;
0853:            }
0854:
0855:            private void createPopup(MouseEvent e) {
0856:                Point p = SwingUtilities.convertPoint(e.getComponent(), e
0857:                        .getX(), e.getY(), TreeTableView.this );
0858:
0859:                createPopup(p.x, p.y);
0860:
0861:                e.consume();
0862:            }
0863:
0864:            void createPopup(int xpos, int ypos) {
0865:                int treeXpos = xpos - ((TreeTable) treeTable).getPositionX();
0866:
0867:                if (allowHideColumns || allowSortingByColumn) {
0868:                    int col = treeTable.getColumnModel().getColumnIndexAtX(
0869:                            treeXpos);
0870:                    super .createExtendedPopup(xpos, ypos, getListMenu(col));
0871:                } else {
0872:                    super .createPopup(xpos, ypos);
0873:                }
0874:            }
0875:
0876:            /* creates List Options menu
0877:             */
0878:            private JMenu getListMenu(final int col) {
0879:                JMenu listItem = new JMenu(NbBundle.getBundle(
0880:                        NodeTableModel.class).getString("LBL_ListOptions"));
0881:
0882:                if (allowHideColumns && (col > 0)) {
0883:                    JMenu colsItem = new JMenu(NbBundle.getBundle(
0884:                            NodeTableModel.class).getString("LBL_ColsMenu"));
0885:
0886:                    boolean addColsItem = false;
0887:
0888:                    if (col > 1) {
0889:                        JMenuItem moveLItem = new JMenuItem(NbBundle.getBundle(
0890:                                NodeTableModel.class).getString("LBL_MoveLeft"));
0891:                        moveLItem.addActionListener(new ActionListener() {
0892:                            public void actionPerformed(
0893:                                    java.awt.event.ActionEvent actionEvent) {
0894:                                treeTable.getColumnModel().moveColumn(col,
0895:                                        col - 1);
0896:                            }
0897:                        });
0898:                        colsItem.add(moveLItem);
0899:                        addColsItem = true;
0900:                    }
0901:
0902:                    if (col < tableModel.getColumnCount()) {
0903:                        JMenuItem moveRItem = new JMenuItem(NbBundle.getBundle(
0904:                                NodeTableModel.class)
0905:                                .getString("LBL_MoveRight"));
0906:                        moveRItem.addActionListener(new ActionListener() {
0907:                            public void actionPerformed(
0908:                                    java.awt.event.ActionEvent actionEvent) {
0909:                                treeTable.getColumnModel().moveColumn(col,
0910:                                        col + 1);
0911:                            }
0912:                        });
0913:                        colsItem.add(moveRItem);
0914:                        addColsItem = true;
0915:                    }
0916:
0917:                    if (addColsItem) {
0918:                        listItem.add(colsItem);
0919:                    }
0920:                }
0921:
0922:                if (allowSortingByColumn) {
0923:                    JMenu sortItem = new JMenu(NbBundle.getBundle(
0924:                            NodeTableModel.class).getString("LBL_SortMenu"));
0925:                    JRadioButtonMenuItem noSortItem = new JRadioButtonMenuItem(
0926:                            NbBundle.getBundle(NodeTableModel.class).getString(
0927:                                    "LBL_NoSort"), !getSortedNodeTreeModel()
0928:                                    .isSortingActive());
0929:                    noSortItem.addActionListener(new ActionListener() {
0930:                        public void actionPerformed(
0931:                                java.awt.event.ActionEvent actionEvent) {
0932:                            noSorting();
0933:                        }
0934:                    });
0935:                    sortItem.add(noSortItem);
0936:
0937:                    int visibleComparable = 0;
0938:                    JRadioButtonMenuItem colItem;
0939:
0940:                    if (treeColumnProperty.isComparable()) {
0941:                        visibleComparable++;
0942:                        colItem = new JRadioButtonMenuItem(treeTable
0943:                                .getColumnName(0), treeColumnProperty
0944:                                .isSortingColumn());
0945:                        colItem.setHorizontalTextPosition(SwingConstants.LEFT);
0946:                        colItem.addActionListener(new ActionListener() {
0947:                            public void actionPerformed(
0948:                                    java.awt.event.ActionEvent actionEvent) {
0949:                                setSortingColumn(-1);
0950:                            }
0951:                        });
0952:                        sortItem.add(colItem);
0953:                    }
0954:
0955:                    for (int i = 0; i < tableModel.getColumnCount(); i++) {
0956:                        if (tableModel.isComparableColumn(i)) {
0957:                            visibleComparable++;
0958:                            colItem = new JRadioButtonMenuItem(tableModel
0959:                                    .getColumnName(i), tableModel
0960:                                    .isSortingColumnEx(tableModel
0961:                                            .translateVisibleColumnIndex(i)));
0962:                            colItem
0963:                                    .setHorizontalTextPosition(SwingConstants.LEFT);
0964:
0965:                            final int index = tableModel
0966:                                    .translateVisibleColumnIndex(i);
0967:                            colItem.addActionListener(new ActionListener() {
0968:                                public void actionPerformed(
0969:                                        java.awt.event.ActionEvent actionEvent) {
0970:                                    setSortingColumn(index);
0971:                                }
0972:                            });
0973:                            sortItem.add(colItem);
0974:                        }
0975:                    }
0976:
0977:                    //add invisible columns
0978:                    for (int i = 0; i < tableModel.getColumnCountEx(); i++) {
0979:                        if (tableModel.isComparableColumnEx(i)
0980:                                && !tableModel.isVisibleColumnEx(i)) {
0981:                            visibleComparable++;
0982:                            colItem = new JRadioButtonMenuItem(tableModel
0983:                                    .getColumnNameEx(i), tableModel
0984:                                    .isSortingColumnEx(i));
0985:                            colItem
0986:                                    .setHorizontalTextPosition(SwingConstants.LEFT);
0987:
0988:                            final int index = i;
0989:                            colItem.addActionListener(new ActionListener() {
0990:                                public void actionPerformed(
0991:                                        java.awt.event.ActionEvent actionEvent) {
0992:                                    setSortingColumn(index);
0993:                                }
0994:                            });
0995:                            sortItem.add(colItem);
0996:                        }
0997:                    }
0998:
0999:                    if (visibleComparable > 0) {
1000:                        sortItem.addSeparator();
1001:
1002:                        boolean current_sort;
1003:
1004:                        if (treeColumnProperty.isSortingColumn()) {
1005:                            current_sort = treeColumnProperty
1006:                                    .isSortOrderDescending();
1007:                        } else {
1008:                            current_sort = tableModel.isSortOrderDescending();
1009:                        }
1010:
1011:                        JRadioButtonMenuItem ascItem = new JRadioButtonMenuItem(
1012:                                NbBundle.getBundle(NodeTableModel.class)
1013:                                        .getString("LBL_Ascending"),
1014:                                !current_sort);
1015:                        ascItem.setHorizontalTextPosition(SwingConstants.LEFT);
1016:                        ascItem.addActionListener(new ActionListener() {
1017:                            public void actionPerformed(
1018:                                    java.awt.event.ActionEvent actionEvent) {
1019:                                setSortingOrder(true);
1020:                            }
1021:                        });
1022:                        sortItem.add(ascItem);
1023:
1024:                        JRadioButtonMenuItem descItem = new JRadioButtonMenuItem(
1025:                                NbBundle.getBundle(NodeTableModel.class)
1026:                                        .getString("LBL_Descending"),
1027:                                current_sort);
1028:                        descItem.setHorizontalTextPosition(SwingConstants.LEFT);
1029:                        descItem.addActionListener(new ActionListener() {
1030:                            public void actionPerformed(
1031:                                    java.awt.event.ActionEvent actionEvent) {
1032:                                setSortingOrder(false);
1033:                            }
1034:                        });
1035:                        sortItem.add(descItem);
1036:
1037:                        if (!getSortedNodeTreeModel().isSortingActive()) {
1038:                            ascItem.setEnabled(false);
1039:                            descItem.setEnabled(false);
1040:                        }
1041:
1042:                        listItem.add(sortItem);
1043:                    }
1044:                }
1045:
1046:                if (allowHideColumns) {
1047:                    JMenuItem visItem = new JMenuItem(NbBundle.getBundle(
1048:                            NodeTableModel.class)
1049:                            .getString("LBL_ChangeColumns"));
1050:                    visItem.addActionListener(new ActionListener() {
1051:                        public void actionPerformed(
1052:                                java.awt.event.ActionEvent actionEvent) {
1053:                            selectVisibleColumns();
1054:                        }
1055:                    });
1056:
1057:                    listItem.add(visItem);
1058:                }
1059:
1060:                return listItem;
1061:            }
1062:
1063:            /* Sets column to be currently used for sorting
1064:             */
1065:            private void setSortingColumn(int index) {
1066:                tableModel.setSortingColumnEx(index);
1067:
1068:                if (index != -1) {
1069:                    getSortedNodeTreeModel().setSortedByProperty(
1070:                            tableModel.propertyForColumnEx(index),
1071:                            !tableModel.isSortOrderDescending());
1072:                    treeColumnProperty.setSortingColumn(false);
1073:                } else {
1074:                    getSortedNodeTreeModel().setSortedByName(true,
1075:                            !treeColumnProperty.isSortOrderDescending());
1076:                    treeColumnProperty.setSortingColumn(true);
1077:                }
1078:
1079:                // to change sort icon
1080:                treeTable.getTableHeader().repaint();
1081:            }
1082:
1083:            private void noSorting() {
1084:                tableModel.setSortingColumnEx(-1);
1085:                getSortedNodeTreeModel().setNoSorting();
1086:                treeColumnProperty.setSortingColumn(false);
1087:
1088:                // to change sort icon
1089:                treeTable.getTableHeader().repaint();
1090:            }
1091:
1092:            /* Sets sorting order for current sorting.
1093:             */
1094:            private void setSortingOrder(boolean ascending) {
1095:                if (treeColumnProperty.isSortingColumn()) {
1096:                    treeColumnProperty.setSortOrderDescending(!ascending);
1097:                } else {
1098:                    tableModel.setSortOrderDescending(!ascending);
1099:                }
1100:
1101:                getSortedNodeTreeModel().setSortOrder(ascending);
1102:
1103:                // to change sort icon
1104:                treeTable.getTableHeader().repaint();
1105:            }
1106:
1107:            private synchronized SortedNodeTreeModel getSortedNodeTreeModel() {
1108:                if (sortedNodeTreeModel == null) {
1109:                    sortedNodeTreeModel = new SortedNodeTreeModel();
1110:                }
1111:
1112:                return sortedNodeTreeModel;
1113:            }
1114:
1115:            /** This is internal accessible context for TreeTableView.
1116:             * It delegates setAccessibleName and setAccessibleDescription methods to set these properties
1117:             * in underlying TreeTable as well.
1118:             */
1119:            private class AccessibleTreeTableView extends AccessibleJScrollPane {
1120:                AccessibleTreeTableView() {
1121:                }
1122:
1123:                public void setAccessibleName(String accessibleName) {
1124:                    super .setAccessibleName(accessibleName);
1125:
1126:                    if (treeTable != null) {
1127:                        treeTable.getAccessibleContext().setAccessibleName(
1128:                                accessibleName);
1129:                    }
1130:                }
1131:
1132:                public void setAccessibleDescription(
1133:                        String accessibleDescription) {
1134:                    super .setAccessibleDescription(accessibleDescription);
1135:
1136:                    if (treeTable != null) {
1137:                        treeTable
1138:                                .getAccessibleContext()
1139:                                .setAccessibleDescription(accessibleDescription);
1140:                    }
1141:                }
1142:            }
1143:
1144:            /* Horizontal scrolling support.
1145:             */
1146:            private final class ScrollListener extends ComponentAdapter
1147:                    implements  PropertyChangeListener, ChangeListener {
1148:                boolean movecorrection = false;
1149:
1150:                ScrollListener() {
1151:                }
1152:
1153:                //Column width
1154:                public void propertyChange(PropertyChangeEvent evt) {
1155:                    if (((TreeTable) treeTable).getTreeColumnIndex() == -1) {
1156:                        return;
1157:                    }
1158:
1159:                    if ("width".equals(evt.getPropertyName())) { // NOI18N
1160:
1161:                        if (!treeTable.equals(evt.getSource())) {
1162:                            Dimension dim = hScrollBar.getPreferredSize();
1163:                            dim.width = treeTable.getColumnModel().getColumn(
1164:                                    ((TreeTable) treeTable)
1165:                                            .getTreeColumnIndex()).getWidth();
1166:                            hScrollBar.setPreferredSize(dim);
1167:                            hScrollBar.revalidate();
1168:                            hScrollBar.repaint();
1169:                        }
1170:
1171:                        revalidateScrollBar();
1172:                    } else if ("positionX".equals(evt.getPropertyName())) { // NOI18N
1173:                        revalidateScrollBar();
1174:                    } else if ("treeColumnIndex".equals(evt.getPropertyName())) { // NOI18N
1175:                        treeTable.getColumnModel().getColumn(
1176:                                ((TreeTable) treeTable).getTreeColumnIndex())
1177:                                .addPropertyChangeListener(listener);
1178:                    } else if ("column_moved".equals(evt.getPropertyName())) { // NOI18N
1179:
1180:                        int from = ((Integer) evt.getOldValue()).intValue();
1181:                        int to = ((Integer) evt.getNewValue()).intValue();
1182:
1183:                        if ((from == 0) || (to == 0)) {
1184:                            if (movecorrection) {
1185:                                movecorrection = false;
1186:                            } else {
1187:                                movecorrection = true;
1188:
1189:                                // not allowed to move first, tree column
1190:                                treeTable.getColumnModel().moveColumn(to, from);
1191:                            }
1192:
1193:                            return;
1194:                        }
1195:
1196:                        // module will be revalidated in NodeTableModel
1197:                        treeTable.getTableHeader().getColumnModel().getColumn(
1198:                                from).setModelIndex(from);
1199:                        treeTable.getTableHeader().getColumnModel().getColumn(
1200:                                to).setModelIndex(to);
1201:                        tableModel.moveColumn(from - 1, to - 1);
1202:                    }
1203:                }
1204:
1205:                //Viewport height
1206:                public void componentResized(ComponentEvent e) {
1207:                    revalidateScrollBar();
1208:                }
1209:
1210:                //ScrollBar change
1211:                public void stateChanged(ChangeEvent evt) {
1212:                    int value = hScrollBar.getModel().getValue();
1213:                    ((TreeTable) treeTable).setPositionX(value);
1214:                }
1215:
1216:                private void revalidateScrollBar() {
1217:                    if (!isDisplayable()) {
1218:                        return;
1219:                    }
1220:
1221:                    if ((treeTable.getColumnModel().getColumnCount() > 0)
1222:                            && (((TreeTable) treeTable).getTreeColumnIndex() >= 0)) {
1223:                        int extentWidth = treeTable.getColumnModel().getColumn(
1224:                                ((TreeTable) treeTable).getTreeColumnIndex())
1225:                                .getWidth();
1226:                        int maxWidth = tree.getPreferredSize().width;
1227:                        int extentHeight = scrollPane.getViewport().getSize().height;
1228:                        int maxHeight = tree.getPreferredSize().height;
1229:                        int positionX = ((TreeTable) treeTable).getPositionX();
1230:
1231:                        int value = Math.max(0, Math.min(positionX, maxWidth
1232:                                - extentWidth));
1233:
1234:                        boolean hsbvisible = hScrollBar.isVisible();
1235:                        boolean vsbvisible = scrollPane.getVerticalScrollBar()
1236:                                .isVisible();
1237:                        int hsbheight = hsbvisible ? hScrollBar.getHeight() : 0;
1238:                        int vsbwidth = scrollPane.getVerticalScrollBar()
1239:                                .getWidth();
1240:
1241:                        hScrollBar.setValues(value, extentWidth, 0, maxWidth);
1242:
1243:                        if (hideHScrollBar
1244:                                || (maxWidth <= extentWidth)
1245:                                || (vsbvisible && ((maxHeight <= (extentHeight + hsbheight)) && (maxWidth <= (extentWidth + vsbwidth))))) {
1246:                            hScrollBar.setVisible(false);
1247:                        } else {
1248:                            hScrollBar.setVisible(true);
1249:                        }
1250:                    }
1251:                }
1252:            }
1253:
1254:            /** Scrollable (better say not scrollable) pane. Used as container for
1255:             * left (controlling) and rigth (controlled) scroll panes.
1256:             */
1257:            private static final class CompoundScrollPane extends JPanel
1258:                    implements  Scrollable {
1259:                CompoundScrollPane() {
1260:                }
1261:
1262:                public void setBorder(Border b) {
1263:                    //do nothing
1264:                }
1265:
1266:                public boolean getScrollableTracksViewportWidth() {
1267:                    return true;
1268:                }
1269:
1270:                public int getScrollableBlockIncrement(Rectangle visibleRect,
1271:                        int orientation, int direction) {
1272:                    return 10;
1273:                }
1274:
1275:                public boolean getScrollableTracksViewportHeight() {
1276:                    return true;
1277:                }
1278:
1279:                public Dimension getPreferredScrollableViewportSize() {
1280:                    return this .getPreferredSize();
1281:                }
1282:
1283:                public int getScrollableUnitIncrement(Rectangle visibleRect,
1284:                        int orientation, int direction) {
1285:                    return 10;
1286:                }
1287:            }
1288:
1289:            /** Invokes default action.
1290:             */
1291:            private class DefaultTreeAction implements  ActionListener {
1292:                DefaultTreeAction() {
1293:                }
1294:
1295:                /**
1296:                 * Invoked when an action occurs.
1297:                 */
1298:                public void actionPerformed(ActionEvent e) {
1299:                    if (treeTable.getSelectedColumn() != ((TreeTable) treeTable)
1300:                            .getTreeColumnIndex()) {
1301:                        return;
1302:                    }
1303:
1304:                    Node[] nodes = manager.getSelectedNodes();
1305:
1306:                    if (nodes.length == 1) {
1307:                        Action a = nodes[0].getPreferredAction();
1308:
1309:                        if (a != null) {
1310:                            if (a.isEnabled()) {
1311:                                a.actionPerformed(new ActionEvent(nodes[0],
1312:                                        ActionEvent.ACTION_PERFORMED, "")); // NOI18N
1313:                            } else {
1314:                                Toolkit.getDefaultToolkit().beep();
1315:                            }
1316:                        }
1317:                    }
1318:                }
1319:            }
1320:
1321:            /* node tree model with added sorting support
1322:             */
1323:            private class SortedNodeTreeModel extends NodeTreeModel {
1324:                private Node.Property sortedByProperty;
1325:                private boolean sortAscending = true;
1326:                private Comparator<VisualizerNode> rowComparator;
1327:                private boolean sortedByName = false;
1328:                private SortingTask sortingTask = null;
1329:
1330:                SortedNodeTreeModel() {
1331:                }
1332:
1333:                void setNoSorting() {
1334:                    setSortedByProperty(null);
1335:                    setSortedByName(false);
1336:                    sortingChanged();
1337:                }
1338:
1339:                boolean isSortingActive() {
1340:                    return ((sortedByProperty != null) || sortedByName);
1341:                }
1342:
1343:                void setSortedByProperty(Node.Property prop) {
1344:                    if (sortedByProperty == prop) {
1345:                        return;
1346:                    }
1347:
1348:                    sortedByProperty = prop;
1349:
1350:                    if (prop == null) {
1351:                        rowComparator = null;
1352:                    } else {
1353:                        sortedByName = false;
1354:                    }
1355:
1356:                    sortingChanged();
1357:                }
1358:
1359:                void setSortedByProperty(Node.Property prop, boolean ascending) {
1360:                    if ((sortedByProperty == prop)
1361:                            && (ascending == sortAscending)) {
1362:                        return;
1363:                    }
1364:
1365:                    sortedByProperty = prop;
1366:                    sortAscending = ascending;
1367:
1368:                    if (prop == null) {
1369:                        rowComparator = null;
1370:                    } else {
1371:                        sortedByName = false;
1372:                    }
1373:
1374:                    sortingChanged();
1375:                }
1376:
1377:                void setSortedByName(boolean sorted, boolean ascending) {
1378:                    if ((sortedByName == sorted)
1379:                            && (ascending == sortAscending)) {
1380:                        return;
1381:                    }
1382:
1383:                    sortedByName = sorted;
1384:                    sortAscending = ascending;
1385:
1386:                    if (sortedByName) {
1387:                        sortedByProperty = null;
1388:                    }
1389:
1390:                    sortingChanged();
1391:                }
1392:
1393:                void setSortedByName(boolean sorted) {
1394:                    sortedByName = sorted;
1395:
1396:                    if (sortedByName) {
1397:                        sortedByProperty = null;
1398:                    }
1399:
1400:                    sortingChanged();
1401:                }
1402:
1403:                void setSortOrder(boolean ascending) {
1404:                    if (ascending == sortAscending) {
1405:                        return;
1406:                    }
1407:
1408:                    sortAscending = ascending;
1409:                    sortingChanged();
1410:                }
1411:
1412:                private Node.Property getNodeProperty(Node node,
1413:                        Node.Property prop) {
1414:                    Node.PropertySet[] propsets = node.getPropertySets();
1415:
1416:                    for (int i = 0, n = propsets.length; i < n; i++) {
1417:                        Node.Property[] props = propsets[i].getProperties();
1418:
1419:                        for (int j = 0, m = props.length; j < m; j++) {
1420:                            if (props[j].equals(prop)) {
1421:                                return props[j];
1422:                            }
1423:                        }
1424:                    }
1425:
1426:                    return null;
1427:                }
1428:
1429:                synchronized Comparator<VisualizerNode> getRowComparator() {
1430:                    if (rowComparator == null) {
1431:                        rowComparator = new Comparator<VisualizerNode>() {
1432:
1433:                            public int compare(VisualizerNode o1,
1434:                                    VisualizerNode o2) {
1435:                                if (o1 == o2) {
1436:                                    return 0;
1437:                                }
1438:                                Node n1 = o1.node;
1439:                                Node n2 = o2.node;
1440:
1441:                                if ((n1 == null) && (n2 == null)) {
1442:                                    return 0;
1443:                                }
1444:                                if (n1 == null) {
1445:                                    return 1;
1446:                                }
1447:                                if (n2 == null) {
1448:                                    return -1;
1449:                                }
1450:                                if ((n1.getParentNode() == null)
1451:                                        || (n2.getParentNode() == null)) {
1452:                                    // PENDING: throw Exception
1453:                                    Logger.getAnonymousLogger().warning(
1454:                                            "TTV.compare: Node " + n1 + " or "
1455:                                                    + n2 + " has no parent!");
1456:                                    return 0;
1457:                                }
1458:                                if (!(n1.getParentNode().equals(n2
1459:                                        .getParentNode()))) {
1460:                                    // PENDING: throw Exception
1461:                                    Logger.getAnonymousLogger().warning(
1462:                                            "TTV.compare: Nodes " + n1
1463:                                                    + " and " + n2
1464:                                                    + " has different parent!");
1465:                                    return 0;
1466:                                }
1467:                                int res = 0;
1468:
1469:                                if (sortedByName) {
1470:                                    res = n1.getDisplayName().compareTo(
1471:                                            n2.getDisplayName());
1472:                                    return sortAscending ? res : (-res);
1473:                                }
1474:                                Property p1 = getNodeProperty(n1,
1475:                                        sortedByProperty);
1476:                                Property p2 = getNodeProperty(n2,
1477:                                        sortedByProperty);
1478:
1479:                                if ((p1 == null) && (p2 == null)) {
1480:                                    return 0;
1481:                                }
1482:                                try {
1483:                                    if (p1 == null) {
1484:                                        res = -1;
1485:                                    } else if (p2 == null) {
1486:                                        res = 1;
1487:                                    } else {
1488:                                        Object v1 = p1.getValue();
1489:                                        Object v2 = p2.getValue();
1490:
1491:                                        if ((v1 == null) && (v2 == null)) {
1492:                                            return 0;
1493:                                        } else if (v1 == null) {
1494:                                            res = -1;
1495:                                        } else if (v2 == null) {
1496:                                            res = 1;
1497:                                        } else {
1498:                                            if ((v1.getClass() != v2.getClass())
1499:                                                    || !(v1 instanceof  Comparable)) {
1500:                                                v1 = v1.toString();
1501:                                                v2 = v2.toString();
1502:                                            }
1503:                                            res = ((Comparable) v1)
1504:                                                    .compareTo(v2);
1505:                                        }
1506:                                    }
1507:                                    return sortAscending ? res : (-res);
1508:                                } catch (Exception ex) {
1509:                                    Logger.getLogger(
1510:                                            TreeTableView.class.getName()).log(
1511:                                            Level.WARNING, null, ex);
1512:                                    return 0;
1513:                                }
1514:                            }
1515:                        };
1516:                    }
1517:
1518:                    return rowComparator;
1519:                }
1520:
1521:                void sortChildren(VisualizerNode parent, boolean synchronous) {
1522:                    //#37802 - resorts are processed too aggressively, causing 
1523:                    //NPEs.  Except for user-invoked actions (clicking the column
1524:                    //header, etc.), we will defer them to run later on the EQ, so
1525:                    //the change in the node has a chance to be fully processed
1526:                    if (synchronous) {
1527:                        synchronized (this ) {
1528:                            if (sortingTask != null) {
1529:                                sortingTask.remove(parent);
1530:
1531:                                if (sortingTask.isEmpty()) {
1532:                                    sortingTask = null;
1533:                                }
1534:                            }
1535:                        }
1536:
1537:                        doSortChildren(parent);
1538:                    } else {
1539:                        synchronized (this ) {
1540:                            if (sortingTask == null) {
1541:                                sortingTask = new SortingTask();
1542:                                SwingUtilities.invokeLater(sortingTask);
1543:                            }
1544:                        }
1545:
1546:                        sortingTask.add(parent);
1547:                    }
1548:                }
1549:
1550:                void doSortChildren(VisualizerNode parent) {
1551:                    if (isSortingActive()) {
1552:                        final Comparator<VisualizerNode> comparator = getRowComparator();
1553:
1554:                        if ((comparator != null) || (parent != null)) {
1555:                            parent.reorderChildren(comparator);
1556:                        }
1557:                    } else {
1558:                        parent.naturalOrder();
1559:                    }
1560:                }
1561:
1562:                void sortingChanged() {
1563:                    // PENDING: remember the last sorting to avoid multiple sorting
1564:                    // remenber expanded folders
1565:                    TreeNode tn = (TreeNode) (this .getRoot());
1566:                    java.util.List<TreePath> list = new ArrayList<TreePath>();
1567:                    Enumeration<TreePath> en = TreeTableView.this .tree
1568:                            .getExpandedDescendants(new TreePath(tn));
1569:
1570:                    while ((en != null) && en.hasMoreElements()) {
1571:                        TreePath path = en.nextElement();
1572:
1573:                        // bugfix #32328, don't sort whole subtree but only expanded folders
1574:                        sortChildren((VisualizerNode) path
1575:                                .getLastPathComponent(), true);
1576:                        list.add(path);
1577:                    }
1578:
1579:                    // expand again folders
1580:                    for (int i = 0; i < list.size(); i++) {
1581:                        TreeTableView.this .tree.expandPath(list.get(i));
1582:                    }
1583:                }
1584:
1585:                String getRootDescription() {
1586:                    if (getRoot() instanceof  VisualizerNode) {
1587:                        //#37802 commenting this out - unfathomable why you would need
1588:                        //to sort the root's children in order to get its short 
1589:                        //description - Tim
1590:                        //                sortChildren ((VisualizerNode)getRoot ());
1591:                        return ((VisualizerNode) getRoot())
1592:                                .getShortDescription();
1593:                    }
1594:
1595:                    return ""; // NOI18N
1596:                }
1597:
1598:                // overrided mothod from DefaultTreeModel
1599:                public void nodesWereInserted(TreeNode node, int[] childIndices) {
1600:                    super .nodesWereInserted(node, childIndices);
1601:
1602:                    if (node instanceof  VisualizerNode && isSortingActive()) {
1603:                        sortChildren((VisualizerNode) node, false);
1604:                    }
1605:                }
1606:
1607:                // overrided mothod from DefaultTreeModel
1608:                public void nodesChanged(TreeNode node, int[] childIndices) {
1609:                    super .nodesChanged(node, childIndices);
1610:
1611:                    if ((node != null) && (childIndices != null)
1612:                            && isSortingActive()) {
1613:                        sortChildren((VisualizerNode) node, false);
1614:                    }
1615:                }
1616:
1617:                // overrided mothod from DefaultTreeModel
1618:                public void setRoot(TreeNode root) {
1619:                    super .setRoot(root);
1620:
1621:                    if (root instanceof  VisualizerNode && isSortingActive()) {
1622:                        sortChildren((VisualizerNode) root, false);
1623:                    }
1624:                }
1625:
1626:                private class SortingTask implements  Runnable {
1627:                    private HashSet<VisualizerNode> toSort = new HashSet<VisualizerNode>();
1628:
1629:                    public synchronized void add(VisualizerNode parent) {
1630:                        toSort.add(parent);
1631:                    }
1632:
1633:                    public synchronized void remove(VisualizerNode parent) {
1634:                        toSort.remove(parent);
1635:                    }
1636:
1637:                    public synchronized boolean isEmpty() {
1638:                        return toSort.isEmpty();
1639:                    }
1640:
1641:                    public void run() {
1642:                        synchronized (SortedNodeTreeModel.this ) {
1643:                            SortedNodeTreeModel.this .sortingTask = null;
1644:                        }
1645:
1646:                        for (Iterator<VisualizerNode> i = toSort.iterator(); i
1647:                                .hasNext();) {
1648:                            VisualizerNode curr = i.next();
1649:                            SortedNodeTreeModel.this .doSortChildren(curr);
1650:                        }
1651:                    }
1652:                }
1653:            }
1654:
1655:            /* Cell renderer for sorting column header.
1656:             */
1657:            private class SortingHeaderRenderer extends
1658:                    DefaultTableCellRenderer {
1659:                SortingHeaderRenderer() {
1660:                }
1661:
1662:                /** Overrides superclass method. */
1663:                public Component getTableCellRendererComponent(JTable table,
1664:                        Object value, boolean isSelected, boolean hasFocus,
1665:                        int row, int column) {
1666:                    Component comp = defaultHeaderRenderer
1667:                            .getTableCellRendererComponent(table, value,
1668:                                    isSelected, hasFocus, row, column);
1669:
1670:                    if (comp instanceof  JLabel) {
1671:                        if ((column == 0)
1672:                                && treeColumnProperty.isSortingColumn()) {
1673:                            ((JLabel) comp)
1674:                                    .setIcon(getProperIcon(treeColumnProperty
1675:                                            .isSortOrderDescending()));
1676:                            ((JLabel) comp)
1677:                                    .setHorizontalTextPosition(SwingConstants.LEFT);
1678:
1679:                            // don't use deriveFont() - see #49973 for details
1680:                            comp.setFont(new Font(comp.getFont().getName(),
1681:                                    Font.BOLD, comp.getFont().getSize()));
1682:                        } else if ((column != 0)
1683:                                && ((tableModel.getVisibleSortingColumn() + 1) == column)) {
1684:                            ((JLabel) comp).setIcon(getProperIcon(tableModel
1685:                                    .isSortOrderDescending()));
1686:                            ((JLabel) comp)
1687:                                    .setHorizontalTextPosition(SwingConstants.LEFT);
1688:
1689:                            // don't use deriveFont() - see #49973 for details
1690:                            comp.setFont(new Font(comp.getFont().getName(),
1691:                                    Font.BOLD, comp.getFont().getSize()));
1692:                        } else {
1693:                            ((JLabel) comp).setIcon(null);
1694:                        }
1695:                    }
1696:
1697:                    return comp;
1698:                }
1699:
1700:                private ImageIcon getProperIcon(boolean descending) {
1701:                    if (descending) {
1702:                        return new ImageIcon(org.openide.util.Utilities
1703:                                .loadImage(SORT_DESC_ICON));
1704:                    } else {
1705:                        return new ImageIcon(org.openide.util.Utilities
1706:                                .loadImage(SORT_ASC_ICON));
1707:                    }
1708:                }
1709:            }
1710:
1711:            // End of inner class SortingHeaderRenderer.
1712:
1713:            private static class TreeColumnProperty {
1714:                private Property p = null;
1715:
1716:                TreeColumnProperty() {
1717:                }
1718:
1719:                void setProperty(Property p) {
1720:                    this .p = p;
1721:                }
1722:
1723:                boolean isComparable() {
1724:                    if (p == null) {
1725:                        return false;
1726:                    }
1727:
1728:                    Object o = p
1729:                            .getValue(NodeTableModel.ATTR_COMPARABLE_COLUMN);
1730:
1731:                    if ((o != null) && o instanceof  Boolean) {
1732:                        return ((Boolean) o).booleanValue();
1733:                    }
1734:
1735:                    return false;
1736:                }
1737:
1738:                boolean isSortingColumn() {
1739:                    if (p == null) {
1740:                        return false;
1741:                    }
1742:
1743:                    Object o = p.getValue(NodeTableModel.ATTR_SORTING_COLUMN);
1744:
1745:                    if ((o != null) && o instanceof  Boolean) {
1746:                        return ((Boolean) o).booleanValue();
1747:                    }
1748:
1749:                    return false;
1750:                }
1751:
1752:                void setSortingColumn(boolean sorting) {
1753:                    if (p == null) {
1754:                        return;
1755:                    }
1756:
1757:                    p.setValue(NodeTableModel.ATTR_SORTING_COLUMN,
1758:                            sorting ? Boolean.TRUE : Boolean.FALSE);
1759:                }
1760:
1761:                boolean isSortOrderDescending() {
1762:                    if (p == null) {
1763:                        return false;
1764:                    }
1765:
1766:                    Object o = p.getValue(NodeTableModel.ATTR_DESCENDING_ORDER);
1767:
1768:                    if ((o != null) && o instanceof  Boolean) {
1769:                        return ((Boolean) o).booleanValue();
1770:                    }
1771:
1772:                    return false;
1773:                }
1774:
1775:                void setSortOrderDescending(boolean descending) {
1776:                    if (p == null) {
1777:                        return;
1778:                    }
1779:
1780:                    p.setValue(NodeTableModel.ATTR_DESCENDING_ORDER,
1781:                            descending ? Boolean.TRUE : Boolean.FALSE);
1782:                }
1783:            }
1784:
1785:            /* For testing - use internal execution
1786:            public static void main(String[] args) {
1787:                SwingUtilities.invokeLater(new Runnable() {
1788:                    public void run() {
1789:                        Node n = //new org.netbeans.core.ModuleNode();
1790:                            RepositoryNodeFactory.getDefault().repository(DataFilter.ALL);
1791:
1792:                        org.openide.explorer.ExplorerManager em = new org.openide.explorer.ExplorerManager();
1793:                        em.setRootContext(n);
1794:
1795:                        org.openide.explorer.ExplorerPanel ep = new org.openide.explorer.ExplorerPanel(em);
1796:                        ep.setLayout (new BorderLayout ());
1797:                        ep.setBorder(new EmptyBorder(20, 20, 20, 20));
1798:
1799:                        TreeTableView ttv = new TreeTableView();
1800:                        ttv.setRootVisible(false);
1801:                        ttv.setPopupAllowed(true);
1802:                        ttv.setDefaultActionAllowed(true);
1803:                        ttv.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
1804:                        ttv.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
1805:
1806:                        org.openide.nodes.PropertySupport.ReadOnly prop2
1807:                            = new org.openide.nodes.PropertySupport.ReadOnly (
1808:                                    "name", // NOI18N
1809:                                    String.class,
1810:                                    "name",
1811:                                    "Name Tooltip"
1812:                                ) {
1813:                                    public Object getValue () {
1814:                                        return null;
1815:                                    }
1816:
1817:                                };
1818:                        //prop2.setValue( "InvisibleInTreeTableView", Boolean.TRUE );
1819:                        prop2.setValue( "SortingColumnTTV", Boolean.TRUE );
1820:                        prop2.setValue( "DescendingOrderTTV", Boolean.TRUE );
1821:                        prop2.setValue( "ComparableColumnTTV", Boolean.TRUE );
1822:
1823:                        ttv.setProperties(
1824:            //                    n.getChildren().getNodes()[0].getPropertySets()[0].getProperties());
1825:                            new Property[]{
1826:                                new org.openide.nodes.PropertySupport.ReadWrite (
1827:                                    "hidden", // NOI18N
1828:                                    Boolean.TYPE,
1829:                                    "hidden",
1830:                                    "Hidden tooltip"
1831:                                ) {
1832:                                    public Object getValue () {
1833:                                        return null;
1834:                                    }
1835:
1836:                                    public void setValue (Object o) {
1837:                                    }
1838:                                },
1839:                                prop2,
1840:                                new org.openide.nodes.PropertySupport.ReadOnly (
1841:                                    "template", // NOI18N
1842:                                    Boolean.TYPE,
1843:                                    "template",
1844:                                    "Template Tooltip"
1845:                                ) {
1846:                                    public Object getValue () {
1847:                                        return null;
1848:                                    }
1849:
1850:                                }
1851:
1852:                            }
1853:                        );
1854:                        ttv.setTreePreferredWidth(200);
1855:
1856:                        ttv.setTableColumnPreferredWidth(0, 60);
1857:                        ttv.setTableColumnPreferredWidth(1, 150);
1858:                        ttv.setTableColumnPreferredWidth(2, 100);
1859:
1860:
1861:                        ep.add("Center", ttv);
1862:                        ep.open();
1863:                    }
1864:                });
1865:            }
1866:             */
1867:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.