Source Code Cross Referenced for Outline.java in  » IDE-Netbeans » web.core » org » netbeans » swing » outline » 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 » web.core » org.netbeans.swing.outline 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        /*
043:         * Outline.java
044:         *
045:         * Created on January 27, 2004, 6:59 PM
046:         */
047:
048:        package org.netbeans.swing.outline;
049:
050:        import java.awt.Font;
051:        import java.awt.FontMetrics;
052:        import java.awt.Graphics;
053:        import java.awt.Insets;
054:        import java.awt.Rectangle;
055:        import java.awt.event.ActionEvent;
056:        import java.awt.event.ActionListener;
057:        import java.awt.event.ComponentAdapter;
058:        import java.awt.event.ComponentEvent;
059:        import java.awt.event.ComponentListener;
060:        import java.awt.event.MouseEvent;
061:        import java.util.ArrayList;
062:        import java.util.EventObject;
063:        import java.util.List;
064:        import javax.swing.JScrollBar;
065:        import javax.swing.JScrollPane;
066:        import javax.swing.JTable;
067:        import javax.swing.JTree;
068:        import javax.swing.JViewport;
069:        import javax.swing.ListSelectionModel;
070:        import javax.swing.Timer;
071:        import javax.swing.UIManager;
072:        import javax.swing.event.TableModelEvent;
073:        import javax.swing.event.TreeModelEvent;
074:        import javax.swing.table.TableCellRenderer;
075:        import javax.swing.table.TableModel;
076:        import javax.swing.tree.AbstractLayoutCache;
077:        import javax.swing.tree.TreePath;
078:
079:        /** An Outline, or tree-table component.  Takes an instance of OutlineModel,
080:         * an interface which merges TreeModel and TableModel.
081:         * <p>
082:         * Simplest usage:  
083:         * <ol>
084:         * <li>Create a standard tree model for the tree node portion of the outline.</li>
085:         * <li>Implement RowModel.  RowModel is a subset of TableModel - it is passed
086:         * the value in column 0 of the Outline and a column index, and returns the 
087:         * value in the column in question.</li>
088:         * <li>Pass the TreeModel and the RowModel to <code>DefaultOutlineModel.createModel()</code>
089:         * </ol>
090:         * This will generate an instance of DefaultOutlineModel which will use the
091:         * TreeModel for the rows/tree column content, and use the RowModel to provide
092:         * the additional table columns.
093:         * <p>
094:         * It is also useful to provide an implementation of <code>RenderDataProvider</code>
095:         * to supply icons and affect text display of cells - this covers most of the 
096:         * needs for which it is necessary to write a custom cell renderer in JTable/JTree.
097:         * <p>
098:         * <b>Example usage:</b><br>
099:         * Assume FileTreeModel is a model which, given a root directory, will 
100:         * expose the files and folders underneath it.  We will implement a 
101:         * RowModel to expose the file size and date, and a RenderDataProvider which
102:         * will use a gray color for uneditable files and expose the full file path as
103:         * a tooltip.  Assume the class this is implemented in is a 
104:         * JPanel subclass or other Swing container.
105:         * <br>
106:         * XXX todo: clean up formatting & edit for style
107:         * <pre>
108:         * public void initComponents() {
109:         *   setLayout (new BorderLayout());
110:         *   TreeModel treeMdl = new FileTreeModel (someDirectory);
111:         *
112:         *   OutlineModel mdl = DefaultOutlineModel.createOutlineModel(treeMdl, 
113:         *       new FileRowModel(), true);
114:         *   outline = new Outline();
115:         *   outline.setRenderDataProvider(new FileDataProvider()); 
116:         *   outline.setRootVisible (true);
117:         *   outline.setModel (mdl);
118:         *   add (outline, BorderLayout.CENTER);
119:         * }
120:         *  private class FileRowModel implements RowModel {
121:         *     public Class getColumnClass(int column) {
122:         *          switch (column) {
123:         *              case 0 : return Date.class;
124:         *              case 1 : return Long.class;
125:         *              default : assert false;
126:         *          }
127:         *          return null;
128:         *      }
129:         *      
130:         *      public int getColumnCount() {
131:         *          return 2;
132:         *      }
133:         *      
134:         *      public String getColumnName(int column) {
135:         *          return column == 0 ? "Date" : "Size";
136:         *      }
137:         *      
138:         *      public Object getValueFor(Object node, int column) {
139:         *          File f = (File) node;
140:         *          switch (column) {
141:         *              case 0 : return new Date (f.lastModified());
142:         *              case 1 : return new Long (f.length());
143:         *              default : assert false;
144:         *          }
145:         *          return null;
146:         *      }
147:         *      
148:         *      public boolean isCellEditable(Object node, int column) {
149:         *          return false;
150:         *      }
151:         *      
152:         *      public void setValueFor(Object node, int column, Object value) {
153:         *          //do nothing, nothing is editable
154:         *      }
155:         *  }
156:         *  
157:         *  private class FileDataProvider implements RenderDataProvider {
158:         *      public java.awt.Color getBackground(Object o) {
159:         *          return null;
160:         *      }
161:         *      
162:         *      public String getDisplayName(Object o) {
163:         *          return ((File) o).getName();
164:         *      }
165:         *      
166:         *      public java.awt.Color getForeground(Object o) {
167:         *          File f = (File) o;
168:         *          if (!f.isDirectory() && !f.canWrite()) {
169:         *              return UIManager.getColor ("controlShadow");
170:         *          }
171:         *          return null;
172:         *      }
173:         *      
174:         *      public javax.swing.Icon getIcon(Object o) {
175:         *          return null;
176:         *      }
177:         *      
178:         *      public String getTooltipText(Object o) {
179:         *          return ((File) o).getAbsolutePath();
180:         *      }
181:         *      
182:         *      public boolean isHtmlDisplayName(Object o) {
183:         *          return false;
184:         *      }
185:         *   }
186:         * </pre>
187:         *
188:         * @author  Tim Boudreau
189:         */
190:        public final class Outline extends JTable {
191:            //XXX plenty of methods missing here - add/remove tree expansion listeners,
192:            //better path info/queries, etc.
193:
194:            private boolean initialized = false;
195:            private Boolean cachedRootVisible = null;
196:            private RenderDataProvider renderDataProvider = null;
197:            private ComponentListener componentListener = null;
198:
199:            /** Creates a new instance of Outline */
200:            public Outline() {
201:                init();
202:            }
203:
204:            public Outline(OutlineModel mdl) {
205:                super (mdl);
206:                init();
207:            }
208:
209:            private void init() {
210:                initialized = true;
211:                setDefaultRenderer(Object.class,
212:                        new DefaultOutlineCellRenderer());
213:            }
214:
215:            /** Always returns the default renderer for Object.class for the tree column */
216:            public TableCellRenderer getCellRenderer(int row, int column) {
217:                TableCellRenderer result;
218:                if (column == 0) {
219:                    result = getDefaultRenderer(Object.class);
220:                } else {
221:                    result = super .getCellRenderer(row, column);
222:                }
223:                return result;
224:            }
225:
226:            /** Get the RenderDataProvider which is providing text, icons and tooltips
227:             * for items in the tree column.  The default property for this value is
228:             * null, in which case standard JTable/JTree object -> icon/string 
229:             * conventions are used */
230:            public RenderDataProvider getRenderDataProvider() {
231:                return renderDataProvider;
232:            }
233:
234:            /** Set the RenderDataProvider which will provide text, icons and tooltips
235:             * for items in the tree column.  The default is null.  If null, 
236:             * the data displayed will be generated in the standard JTable/JTree way - 
237:             * calling <code>toString()</code> on objects in the tree model and 
238:             * using the look and feel's default tree folder and tree leaf icons.  */
239:            public void setRenderDataProvider(RenderDataProvider provider) {
240:                if (provider != renderDataProvider) {
241:                    RenderDataProvider old = renderDataProvider;
242:                    renderDataProvider = provider;
243:                    firePropertyChange("renderDataProvider", old, provider); //NOI18N
244:                }
245:            }
246:
247:            /** Get the TreePathSupport object which manages path expansion for this
248:             * Outline. */
249:            TreePathSupport getTreePathSupport() {
250:                OutlineModel mdl = getOutlineModel();
251:                if (mdl != null) {
252:                    return mdl.getTreePathSupport();
253:                } else {
254:                    return null;
255:                }
256:            }
257:
258:            /** Get the layout cache which manages layout data for the Outline.
259:             * <strong>Under no circumstances directly call the methods on the
260:             * layout cache which change the expanded state - such changes will not
261:             * be propagated into the table model, and will leave the model and
262:             * its layout in inconsistent states.  Any calls that affect expanded
263:             * state must go through <code>getTreePathSupport()</code>.</strong> */
264:            AbstractLayoutCache getLayoutCache() {
265:                OutlineModel mdl = getOutlineModel();
266:                if (mdl != null) {
267:                    return mdl.getLayout();
268:                } else {
269:                    return null;
270:                }
271:            }
272:
273:            boolean isTreeColumnIndex(int column) {
274:                //XXX fixme - this is not true if columns have been dragged
275:                return column == 0;
276:            }
277:
278:            public boolean isVisible(TreePath path) {
279:                if (getTreePathSupport() != null) {
280:                    return getTreePathSupport().isVisible(path);
281:                }
282:                return false;
283:            }
284:
285:            /** Overridden to pass the fixed row height to the tree layout cache */
286:            public void setRowHeight(int val) {
287:                super .setRowHeight(val);
288:                if (getLayoutCache() != null) {
289:                    getLayoutCache().setRowHeight(val);
290:                }
291:            }
292:
293:            /** Set whether or not the root is visible */
294:            public void setRootVisible(boolean val) {
295:                if (getOutlineModel() == null) {
296:                    cachedRootVisible = val ? Boolean.TRUE : Boolean.FALSE;
297:                }
298:                if (val != isRootVisible()) {
299:                    //TODO - need to force a property change on the model,
300:                    //the layout cache doesn't have direct listener support
301:                    getLayoutCache().setRootVisible(val);
302:                    firePropertyChange("rootVisible", !val, val); //NOI18N
303:                }
304:            }
305:
306:            /** Is the tree root visible.  Default value is true. */
307:            public boolean isRootVisible() {
308:                if (getLayoutCache() == null) {
309:                    return cachedRootVisible != null ? cachedRootVisible
310:                            .booleanValue() : true;
311:                } else {
312:                    return getLayoutCache().isRootVisible();
313:                }
314:            }
315:
316:            /** Overridden to throw an exception if the passed model is not an instance
317:             * of <code>OutlineModel</code> (with the exception of calls from the 
318:             * superclass constructor) */
319:            public void setModel(TableModel mdl) {
320:                if (initialized && (!(mdl instanceof  OutlineModel))) {
321:                    throw new IllegalArgumentException(
322:                            "Table model for an Outline must be an instance of "
323:                                    + "OutlineModel"); //NOI18N
324:                }
325:                if (mdl instanceof  OutlineModel) {
326:                    AbstractLayoutCache layout = ((OutlineModel) mdl)
327:                            .getLayout();
328:                    if (cachedRootVisible != null) {
329:
330:                        layout.setRootVisible(cachedRootVisible.booleanValue());
331:
332:                    }
333:
334:                    layout.setRowHeight(getRowHeight());
335:
336:                    if (((OutlineModel) mdl).isLargeModel()) {
337:                        addComponentListener(getComponentListener());
338:                        layout.setNodeDimensions(new ND());
339:                    } else {
340:                        if (componentListener != null) {
341:                            removeComponentListener(componentListener);
342:                            componentListener = null;
343:                        }
344:                    }
345:                }
346:
347:                super .setModel(mdl);
348:            }
349:
350:            /** Convenience getter for the <code>TableModel</code> as an instance of
351:             * OutlineModel.  If no OutlineModel has been set, returns null. */
352:            public OutlineModel getOutlineModel() {
353:                TableModel mdl = getModel();
354:                if (mdl instanceof  OutlineModel) {
355:                    return (OutlineModel) getModel();
356:                } else {
357:                    return null;
358:                }
359:            }
360:
361:            /** Expand a tree path */
362:            public void expandPath(TreePath path) {
363:                getTreePathSupport().expandPath(path);
364:            }
365:
366:            public void collapsePath(TreePath path) {
367:                getTreePathSupport().collapsePath(path);
368:            }
369:
370:            public Rectangle getPathBounds(TreePath path) {
371:                Insets i = getInsets();
372:                Rectangle bounds = getLayoutCache().getBounds(path, null);
373:
374:                if (bounds != null && i != null) {
375:                    bounds.x += i.left;
376:                    bounds.y += i.top;
377:                }
378:                return bounds;
379:            }
380:
381:            public TreePath getClosestPathForLocation(int x, int y) {
382:                Insets i = getInsets();
383:                if (i != null) {
384:                    return getLayoutCache().getPathClosestTo(x - i.left,
385:                            y - i.top);
386:                } else {
387:                    return getLayoutCache().getPathClosestTo(x, y);
388:                }
389:            }
390:
391:            public boolean editCellAt(int row, int column, EventObject e) {
392:                //If it was on column 0, it may be a request to expand a tree
393:                //node - check for that first.
394:                if (isTreeColumnIndex(column) && e instanceof  MouseEvent) {
395:                    MouseEvent me = (MouseEvent) e;
396:                    TreePath path = getLayoutCache().getPathClosestTo(
397:                            me.getX(), me.getY());
398:                    if (!getOutlineModel().isLeaf(path.getLastPathComponent())) {
399:                        int handleWidth = DefaultOutlineCellRenderer
400:                                .getExpansionHandleWidth();
401:                        Insets ins = getInsets();
402:                        int handleStart = ins.left
403:                                + ((path.getPathCount() - 1) * DefaultOutlineCellRenderer
404:                                        .getNestingWidth());
405:                        int handleEnd = ins.left + handleStart + handleWidth;
406:
407:                        //TODO: Translate x/y to position of column if non-0
408:
409:                        if ((me.getX() > ins.left && me.getX() >= handleStart && me
410:                                .getX() <= handleEnd)
411:                                || me.getClickCount() > 1) {
412:
413:                            boolean expanded = getLayoutCache()
414:                                    .isExpanded(path);
415:                            if (!expanded) {
416:                                getTreePathSupport().expandPath(path);
417:                            } else {
418:                                getTreePathSupport().collapsePath(path);
419:                            }
420:                            return false;
421:                        }
422:                    }
423:                }
424:
425:                return super .editCellAt(row, column, e);
426:            }
427:
428:            private boolean needCalcRowHeight = true;
429:
430:            /** Calculate the height of rows based on the current font.  This is
431:             *  done when the first paint occurs, to ensure that a valid Graphics
432:             *  object is available.  */
433:            private void calcRowHeight(Graphics g) {
434:                //Users of themes can set an explicit row height, so check for it
435:                Integer i = (Integer) UIManager
436:                        .get("netbeans.outline.rowHeight"); //NOI18N
437:
438:                int rowHeight;
439:                if (i != null) {
440:                    rowHeight = i.intValue();
441:                } else {
442:                    //Derive a row height to accomodate the font and expando icon
443:                    Font f = getFont();
444:                    FontMetrics fm = g.getFontMetrics(f);
445:                    rowHeight = Math.max(fm.getHeight() + 3,
446:                            DefaultOutlineCellRenderer
447:                                    .getExpansionHandleHeight());
448:                }
449:                //Clear the flag
450:                needCalcRowHeight = false;
451:                //Set row height.  If displayable, this will generate a new call
452:                //to paint()
453:                setRowHeight(rowHeight);
454:            }
455:
456:            public void tableChanged(TableModelEvent e) {
457:                //        System.err.println("Table got tableChanged " + e);
458:                super .tableChanged(e);
459:                //        System.err.println("row count is " + getRowCount());
460:            }
461:
462:            public void paint(Graphics g) {
463:                if (needCalcRowHeight) {
464:                    calcRowHeight(g);
465:                    //CalcRowHeight will trigger a repaint
466:                    return;
467:                }
468:                super .paint(g);
469:            }
470:
471:            /** Create a component listener to handle size changes if the table model
472:             * is large-model */
473:            private ComponentListener getComponentListener() {
474:                if (componentListener == null) {
475:                    componentListener = new SizeManager();
476:                }
477:                return componentListener;
478:            }
479:
480:            private JScrollPane getScrollPane() {
481:                JScrollPane result = null;
482:                if (getParent() instanceof  JViewport) {
483:                    if (((JViewport) getParent()).getParent() instanceof  JScrollPane) {
484:                        result = (JScrollPane) ((JViewport) getParent())
485:                                .getParent();
486:                    }
487:                }
488:                return result;
489:            }
490:
491:            private void change() {
492:                revalidate();
493:                repaint();
494:            }
495:
496:            private class ND extends AbstractLayoutCache.NodeDimensions {
497:
498:                public Rectangle getNodeDimensions(Object value, int row,
499:                        int depth, boolean expanded, Rectangle bounds) {
500:
501:                    int wid = Outline.this .getColumnModel().getColumn(0)
502:                            .getPreferredWidth();
503:                    bounds.setBounds(0, row * getRowHeight(), wid,
504:                            getRowHeight());
505:                    return bounds;
506:                }
507:
508:            }
509:
510:            /** A component listener.  If we're a large model table, we need
511:             * to inform the FixedHeightLayoutCache when the size changes, so it
512:             * can update its mapping of visible nodes */
513:            private class SizeManager extends ComponentAdapter implements 
514:                    ActionListener {
515:                protected Timer timer = null;
516:                protected JScrollBar scrollBar = null;
517:
518:                public void componentMoved(ComponentEvent e) {
519:                    if (timer == null) {
520:                        JScrollPane scrollPane = getScrollPane();
521:
522:                        if (scrollPane == null) {
523:                            change();
524:                        } else {
525:                            scrollBar = scrollPane.getVerticalScrollBar();
526:                            if (scrollBar == null
527:                                    || !scrollBar.getValueIsAdjusting()) {
528:                                // Try the horizontal scrollbar.
529:                                if ((scrollBar = scrollPane
530:                                        .getHorizontalScrollBar()) != null
531:                                        && scrollBar.getValueIsAdjusting()) {
532:
533:                                    startTimer();
534:                                } else {
535:                                    change();
536:                                }
537:                            } else {
538:                                startTimer();
539:                            }
540:                        }
541:                    }
542:                }
543:
544:                protected void startTimer() {
545:                    if (timer == null) {
546:                        timer = new Timer(200, this );
547:                        timer.setRepeats(true);
548:                    }
549:                    timer.start();
550:                }
551:
552:                public void actionPerformed(ActionEvent ae) {
553:                    if (scrollBar == null || !scrollBar.getValueIsAdjusting()) {
554:                        if (timer != null)
555:                            timer.stop();
556:                        change();
557:                        timer = null;
558:                        scrollBar = null;
559:                    }
560:                }
561:
562:                public void componentHidden(ComponentEvent e) {
563:                }
564:
565:                public void componentResized(ComponentEvent e) {
566:                }
567:
568:                public void componentShown(ComponentEvent e) {
569:                }
570:            }
571:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.