Source Code Cross Referenced for XTreeTable.java in  » XML-UI » xui32 » com » xoetrope » swing » 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 » XML UI » xui32 » com.xoetrope.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package com.xoetrope.swing;
002:
003:        import com.xoetrope.swing.table.XAltRowTableCellRenderer;
004:        import com.xoetrope.swing.table.XColorTableCellRenderer;
005:        import com.xoetrope.swing.table.XTableHeaderRenderer;
006:        import com.xoetrope.swing.treetable.AbstractTreeTableModel;
007:        import com.xoetrope.swing.treetable.TreeTableModel;
008:        import com.xoetrope.swing.treetable.TreeTableModelAdapter;
009:        import com.xoetrope.swing.treetable.XTreeTableModelNode;
010:        import com.xoetrope.swing.table.XFormattedTableCellRenderer;
011:        import java.awt.Color;
012:
013:        import java.awt.Dimension;
014:        import java.awt.Component;
015:        import java.awt.Container;
016:        import java.awt.Graphics;
017:        import java.awt.Point;
018:        import java.awt.Rectangle;
019:
020:        import java.awt.event.MouseEvent;
021:
022:        import java.text.Format;
023:        import java.util.EventObject;
024:        import java.util.Hashtable;
025:
026:        import javax.swing.ImageIcon;
027:        import javax.swing.JScrollPane;
028:        import javax.swing.JTable;
029:        import javax.swing.JTree;
030:        import javax.swing.JViewport;
031:        import javax.swing.ListSelectionModel;
032:        import javax.swing.LookAndFeel;
033:        import javax.swing.SwingConstants;
034:        import javax.swing.SwingUtilities;
035:        import javax.swing.UIManager;
036:        import javax.swing.border.EmptyBorder;
037:        import javax.swing.event.ListSelectionEvent;
038:        import javax.swing.event.ListSelectionListener;
039:        import javax.swing.event.TableModelEvent;
040:        import javax.swing.table.DefaultTableColumnModel;
041:        import javax.swing.table.JTableHeader;
042:        import javax.swing.table.TableCellEditor;
043:        import javax.swing.table.TableCellRenderer;
044:        import javax.swing.table.TableColumn;
045:        import javax.swing.table.TableColumnModel;
046:        import javax.swing.table.TableModel;
047:        import javax.swing.tree.DefaultTreeCellRenderer;
048:        import javax.swing.tree.DefaultTreeSelectionModel;
049:        import javax.swing.tree.TreeCellRenderer;
050:        import javax.swing.tree.TreeModel;
051:        import javax.swing.tree.TreePath;
052:
053:        import net.xoetrope.xui.XAttributedComponent;
054:        import net.xoetrope.xui.XModelHolder;
055:        import net.xoetrope.xui.XProject;
056:        import net.xoetrope.xui.XProjectManager;
057:        import net.xoetrope.xui.data.XModel;
058:        import net.xoetrope.xui.data.XRowSelector;
059:        import net.xoetrope.xui.events.XHandlerInvoker;
060:        import net.xoetrope.xui.events.XListenerHelper;
061:        import net.xoetrope.xui.helper.XuiUtilities;
062:        import net.xoetrope.xui.style.XStyle;
063:        import net.xoetrope.xui.style.XStyleComponent;
064:        import net.xoetrope.xui.style.XStyleManager;
065:
066:        /**
067:         * This example shows how to create a simple XTreeTable component,
068:         * by using a JTree as a renderer (and editor) for the cells in a
069:         * particular column in the JTable.
070:         *
071:         * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
072:         * the GNU Public License (GPL), please see license.txt for more details. If
073:         * you make commercial use of this software you must purchase a commercial
074:         * license from Xoetrope.</p>
075:         * <p> $Revision: 1.22 $</p>
076:         */
077:        public class XTreeTable extends JTable implements  XModelHolder,
078:                XRowSelector, XAttributedComponent, XStyleComponent,
079:                XListenerHelper {
080:            protected XModel xmodel;
081:            protected AbstractTreeTableModel model;
082:
083:            protected boolean updateModelSelection = false;
084:            protected XHandlerInvoker invoker;
085:
086:            /** A subclass of JTree. */
087:            protected TreeTableCellRenderer tree;
088:            private XProject currentProject;
089:            protected Hashtable renderers;
090:
091:            protected Color altUnselectedForeground;
092:            protected Color altUnselectedBackground;
093:
094:            private ListToTreeSelectionModelWrapper selectionWrapper;
095:            private int percentage;
096:            private int selectedRow;
097:
098:            private String headingStyle, selectionStyle;
099:
100:            /**
101:             * Create a new XTreeTable
102:             */
103:            public XTreeTable() {
104:                super ();
105:                currentProject = XProjectManager.getCurrentProject();
106:                renderers = new Hashtable();
107:            }
108:
109:            public int getSelectedRow() {
110:                int r = super .getSelectedRow();
111:                return selectedRow = r;
112:            }
113:
114:            /**
115:             * Gets a field value object from the currently selected row
116:             * @param fieldIdx the field offset
117:             * @return the value
118:             */
119:            public Object getValue(int fieldIdx) {
120:                int row = getSelectedRow();
121:                return getValue(row, fieldIdx);
122:            }
123:
124:            /**
125:             * Gets a field value object from the specified row
126:             * @param rowIdx the row offset
127:             * @param fieldIdx the field offset
128:             * @return the value
129:             */
130:            public Object getValue(int rowIdx, int fieldIdx) {
131:                TreePath treePath = tree.getPathForRow(rowIdx);
132:                Object node = treePath.getLastPathComponent();
133:                return model.getValueAt(node, fieldIdx);
134:            }
135:
136:            /**
137:             * Gets a field value as a string from the currently selected row
138:             * @param fieldIdx the field offset
139:             * @return the value
140:             */
141:            public String getFieldValue(int fieldIdx) {
142:                return (String) getValue(fieldIdx);
143:
144:            }
145:
146:            /**
147:             * Gets a field value as a string from the specified row
148:             * @param rowIdx the row offset
149:             * @param fieldIdx the field offset
150:             * @return the value
151:             */
152:            public String getFieldValue(int rowIdx, int fieldIdx) {
153:                return (String) getValue(rowIdx, fieldIdx);
154:            }
155:
156:            /**
157:             * Update the table's model
158:             */
159:            public void update() {
160:                if (dataModel != null) {
161:                    /** @todo add some checks to ensure it is correct to restore the row selection in all cases */
162:                    getSelectedRow();
163:                    updateTable();
164:                    SwingUtilities.invokeLater(new Runnable() {
165:                        public void run() {
166:                            if (selectedRow >= 0)
167:                                setSelection(selectedRow);
168:                        }
169:                    });
170:                }
171:            }
172:
173:            /**
174:             * Force the table to update itself
175:             */
176:            public void updateTable() {
177:                if (model != null)
178:                    setModel(((XTreeTableModelNode.XNode) model.getRoot())
179:                            .getModel());
180:                tableChanged(new TableModelEvent(dataModel));
181:            }
182:
183:            public void setModel(XModel _xmodel) {
184:                setModel(_xmodel, null);
185:            }
186:
187:            /**
188:             * Set the XModel which we will be generating the table from
189:             * @param _xmodel The XModel of data
190:             */
191:            public void setModel(XModel _xmodel, TableModel delegModel) {
192:                xmodel = _xmodel;
193:                if (xmodel != null) {
194:                    xmodel.get();
195:
196:                    //      model = new XTreeTableModelNode( xmodel );
197:                    if (delegModel != null)
198:                        model = new XTreeTableModelNode(xmodel, delegModel);
199:                    else
200:                        model = new XTreeTableModelNode(xmodel);
201:
202:                    // Create the tree. It will be used as a renderer and editor.
203:                    tree = new TreeTableCellRenderer(model);
204:                    tree.setTreeIcons(null, null, null);
205:                    tree.setRootVisible(false);
206:                    tree.setShowsRootHandles(true);
207:                    tree.setAutoscrolls(true);
208:                    tree.setScrollsOnExpand(true);
209:
210:                    // Install a tableModel representing the visible rows in the tree.
211:                    super .setModel(new TreeTableModelAdapter(model, tree));
212:
213:                    // Force the JTable and JTree to share their row selection models.
214:                    if (selectionWrapper == null)
215:                        selectionWrapper = new ListToTreeSelectionModelWrapper();
216:                    tree.setSelectionModel(selectionWrapper);
217:                    setSelectionModel(selectionWrapper.getListSelectionModel());
218:
219:                    // Install the tree editor renderer and editor.
220:                    setDefaultRenderer(TreeTableModel.class, tree);
221:                    setDefaultEditor(TreeTableModel.class,
222:                            new TreeTableCellEditor());
223:
224:                    // No grid.
225:                    setShowGrid(false);
226:                    setHeaderRenderer();
227:
228:                    // No intercell spacing
229:                    setIntercellSpacing(new Dimension(0, 0));
230:
231:                    // And update the height of the trees row to match that of
232:                    // the table.
233:                    if (tree.getRowHeight() < 1)
234:                        setRowHeight(18);// Metal looks better like this.      
235:
236:                    reload(model.getRoot());
237:                }
238:            }
239:
240:            public void reload() {
241:                reload(model.getRoot());
242:            }
243:
244:            /**
245:             * Set the column width. Sets the maximum width as a workaround for a Swing problem
246:             * @param columnIdx the column index
247:             * @param width the new width
248:             */
249:            public void setColumnWidth(int columnIdx, int width) {
250:                if (isShowing() && isVisible()) {
251:                    DefaultTableColumnModel colModel = (DefaultTableColumnModel) getColumnModel();
252:                    TableColumn column = colModel.getColumn(columnIdx);
253:                    column.setMaxWidth(width);
254:                } else {
255:                    try {
256:                        final int w = width;
257:                        final int col = columnIdx;
258:                        SwingUtilities.invokeLater(new Runnable() {
259:                            public void run() {
260:                                setColumnWidth(col, w);
261:                            }
262:                        });
263:                    } catch (Exception e) {
264:                    }
265:                }
266:            }
267:
268:            /**
269:             * Set the colors for alternate ( odd ) row colors
270:             * @param frgd the foreground color
271:             * @param bkgd the background color
272:             */
273:            public void setAltUnselectedColors(Color frgd, Color bkgd) {
274:                altUnselectedForeground = frgd;
275:                altUnselectedBackground = bkgd;
276:            }
277:
278:            /**
279:             * Get a render for this cell
280:             */
281:            public TableCellRenderer getCellRenderer(int row, int column) {
282:                TableCellRenderer renderer = (TableCellRenderer) renderers
283:                        .get("" + column);
284:                if (renderer != null)
285:                    return renderer;
286:                else if (altUnselectedBackground != null) {
287:                    if (column > 0) {
288:                        XAltRowTableCellRenderer altRenderer = new XAltRowTableCellRenderer();
289:                        altRenderer.setAltUnselectedColors(
290:                                altUnselectedForeground,
291:                                altUnselectedBackground);
292:                        renderers.put("" + column, altRenderer);
293:                        return altRenderer;
294:                    }
295:                }
296:                return super .getCellRenderer(row, column);
297:            }
298:
299:            /**
300:             * Set the enabled state
301:             * @param b true to enable
302:             */
303:            public void setEnabled(boolean b) {
304:                super .setEnabled(b);
305:                getTableHeader().repaint();
306:                repaint();
307:            }
308:
309:            /**
310:             * Set the alignment of a column
311:             * @param column the column index
312:             * @param alignment the SwingContants aliignment constant
313:             */
314:            public void setAlignment(int column, int alignment) {
315:                TableCellRenderer tr = getCellRenderer(0, column);
316:                if (tr instanceof  XAltRowTableCellRenderer)
317:                    ((XAltRowTableCellRenderer) tr)
318:                            .setHorizontalAlignment(alignment);
319:            }
320:
321:            /**
322:             * Display the field as a numeric value
323:             * @param column the column or field index
324:             * @param format format the number format to use in displaying the field
325:             */
326:            public void displayAsNumericField(int column, Format format) {
327:                XFormattedTableCellRenderer renderer = new XFormattedTableCellRenderer(
328:                        format);
329:                renderer.setAltUnselectedColors(altUnselectedForeground,
330:                        altUnselectedBackground);
331:                renderer.setHorizontalAlignment(SwingConstants.RIGHT);
332:                renderers.put("" + column, renderer);
333:            }
334:
335:            /**
336:             * Display the field formatted with a background color from the hashtable such 
337:             * that the field value acts as a key into the hashtable of colors
338:             * @param column the column or field index
339:             * @param colors the color hashtable
340:             */
341:            public void displayAsColorField(int column, Hashtable colors) {
342:                XColorTableCellRenderer renderer = new XColorTableCellRenderer(
343:                        colors);
344:                renderers.put("" + column, renderer);
345:            }
346:
347:            /**
348:             * Add a cell renderer for the specified column
349:             * @param column the column or field index
350:             */
351:            public void addRenderer(int column, TableCellRenderer renderer) {
352:                renderers.put("" + column, renderer);
353:            }
354:
355:            /**
356:             * Set a header renderer for thetable.
357:             */
358:            public void setHeaderRenderer() {
359:                XTableHeaderRenderer renderer = new XTableHeaderRenderer(
360:                        getTableHeader());
361:                TableColumnModel columnModel = getColumnModel();
362:                int numColumns = columnModel.getColumnCount();
363:                for (int i = 0; i < numColumns; i++)
364:                    columnModel.getColumn(i).setHeaderRenderer(renderer);
365:            }
366:
367:            /**
368:             * Set one or more attributes of the component. Currently this handles the
369:             * attributes
370:             * <OL>
371:             * <LI>headingStyle, value=the table header style</LI>
372:             * <LI>selectionStyle, value=the selected row style</LI>
373:             * <LI>updateModel, value=true|false update the underlying model selection (the selected row)</LI>
374:             * <LI>border, 0 to turn off the border</LI>
375:             * </OL>
376:             * @param attribName the attribute name
377:             * @param attribValue the attribute value
378:             * @return 0 for success, non zero otherwise
379:             */
380:            public int setAttribute(String attribName, Object attribValue) {
381:                String attribNameLwr = attribName.toLowerCase();
382:                String attribValueStr = (String) attribValue;
383:                String attribValueLwr = attribValueStr.toLowerCase();
384:                if (attribNameLwr.equals("headingstyle")
385:                        || attribNameLwr.equals("headerstyle")) // headerstyle provided for backward compatibility
386:                    setHeadingStyle(attribValueStr);
387:                else if (attribNameLwr.equals("selectionstyle")
388:                        || attribNameLwr.equals("selectedstyle")) // headerstyle provided for backward compatibility
389:                    setSelectionStyle(attribValueStr);
390:                else if (attribNameLwr.equals("borderstyle"))
391:                    setBorderStyle(attribValueStr);
392:                else if (attribNameLwr.equals("border")) {
393:                    if ("0".equals(attribValueStr))
394:                        setBorder(new EmptyBorder(0, 0, 0, 0));
395:                } else if (attribNameLwr.equals("updatemodel"))
396:                    setUpdateModelSelection(attribValueLwr.equals("true"));
397:                else if (attribNameLwr.equals("altstyle"))
398:                    setAltStyle(attribValueStr);
399:
400:                return 0;
401:            }
402:
403:            /**
404:             * Set the general style of the XTable
405:             * @param style XStyle
406:             */
407:            public void setStyle(String style) {
408:                XStyleManager styleMgr = currentProject.getStyleManager();
409:                XStyle xstyle = styleMgr.getStyle(style);
410:                setForeground(xstyle.getStyleAsColor(XStyle.COLOR_FORE));
411:                setBackground(xstyle.getStyleAsColor(XStyle.COLOR_BACK));
412:                setFont(styleMgr.getFont(xstyle));
413:            }
414:
415:            /**
416:             * Set the style of the header data
417:             * @param style XStyle
418:             */
419:            public void setHeadingStyle(String style) {
420:                headingStyle = style;
421:                XStyleManager styleMgr = currentProject.getStyleManager();
422:                XStyle xstyle = styleMgr.getStyle(style);
423:                JTableHeader th = getTableHeader();
424:                th.setForeground(xstyle.getStyleAsColor(XStyle.COLOR_FORE));
425:                th.setBackground(xstyle.getStyleAsColor(XStyle.COLOR_BACK));
426:                th.setFont(styleMgr.getFont(xstyle));
427:            }
428:
429:            /**
430:             * Set the style of the selected row
431:             * @param style XStyle
432:             */
433:            public void setSelectionStyle(String style) {
434:                selectionStyle = style;
435:                XStyle xstyle = currentProject.getStyleManager()
436:                        .getStyle(style);
437:                setSelectionForeground(xstyle
438:                        .getStyleAsColor(XStyle.COLOR_FORE));
439:                setSelectionBackground(xstyle
440:                        .getStyleAsColor(XStyle.COLOR_BACK));
441:            }
442:
443:            /**
444:             * Set the style of the alternate rows
445:             * @param style XStyle
446:             */
447:            public void setAltStyle(String style) {
448:                XStyle xstyle = currentProject.getStyleManager()
449:                        .getStyle(style);
450:                altUnselectedForeground = xstyle
451:                        .getStyleAsColor(XStyle.COLOR_FORE);
452:                altUnselectedBackground = xstyle
453:                        .getStyleAsColor(XStyle.COLOR_BACK);
454:            }
455:
456:            /**
457:             * Set the style of the header data
458:             * @return the header styles
459:             */
460:            public String getHeadingStyle() {
461:                return headingStyle;
462:            }
463:
464:            /**
465:             * Get the style of the selected row
466:             * @return the selected style 
467:             */
468:            public String getSelectionStyle() {
469:                return selectionStyle;
470:            }
471:
472:            /**
473:             * Set the style of the border
474:             * @param style XStyle
475:             */
476:            public void setBorderStyle(String style) {
477:                //    content.setBorderStyle( style );
478:            }
479:
480:            /**
481:             * Set the row selection index
482:             * @param rowIdx the new row selection index (zero based)
483:             */
484:            public void setSelectedRow(int rowIdx) {
485:                setSelection(rowIdx);
486:            }
487:
488:            /**
489:             * Add an event handler response method to a component such that the page's
490:             * response method is invoked when the event occurs
491:             * @param page the page containing the method
492:             * @param handlerType the type of event handler
493:             * @param methodName the method to invoke
494:             * @throws NoSuchMethodException cannot add the handler
495:             */
496:            public void addHandler(Object page, String handlerType,
497:                    String methodName) throws NoSuchMethodException {
498:                invoker = new XHandlerInvoker(page, this , methodName);
499:            }
500:
501:            /**
502:             * Tie the model selection to this table's selection
503:             * @param doUpdate true to tie the selections together, false to ignore
504:             */
505:            public void setUpdateModelSelection(boolean doUpdate) {
506:                updateModelSelection = doUpdate;
507:            }
508:
509:            /**
510:             * Get the model selection update flag
511:             * @rreturn true if the selections and model are tied together
512:             */
513:            public boolean getUpdateModelSelection() {
514:                return updateModelSelection;
515:            }
516:
517:            /**
518:             * Overridden to message super and forward the method to the tree.
519:             * Since the tree is not actually in the component hieachy it will
520:             * never receive this unless we forward it in this manner.
521:             */
522:            public void updateUI() {
523:                super .updateUI();
524:                if (tree != null)
525:                    tree.updateUI();
526:
527:                // Use the tree's default foreground and background colors in the
528:                // table.
529:                LookAndFeel.installColorsAndFont(this , "Tree.background",
530:                        "Tree.foreground", "Tree.font");
531:            }
532:
533:            /* Workaround for BasicTableUI anomaly. Make sure the UI never tries to
534:             * paint the editor. The UI currently uses different techniques to
535:             * paint the renderers and editors and overriding setBounds() below
536:             * is not the right thing to do for an editor. Returning -1 for the
537:             * editing row in this case, ensures the editor is never painted.
538:             */
539:            public int getEditingRow() {
540:                return (getColumnClass(editingColumn) == TreeTableModel.class) ? -1
541:                        : editingRow;
542:            }
543:
544:            /**
545:             * Overridden to pass the new rowHeight to the tree.
546:             */
547:            public void setRowHeight(int rowHeight) {
548:                super .setRowHeight(rowHeight);
549:                if (tree != null && tree.getRowHeight() != rowHeight)
550:                    tree.setRowHeight(getRowHeight());
551:            }
552:
553:            /**
554:             * Returns the tree that is being shared between the model.
555:             */
556:            public JTree getTree() {
557:                return tree;
558:            }
559:
560:            /**
561:             * Select the nth visible row one level down from the parent.
562:             * @param rowIdx the row index
563:             */
564:            public void setSelection(int rowIdx) {
565:                selectedRow = rowIdx;
566:                TreePath selectedPath = tree.getPathForRow(rowIdx);
567:                tree.scrollPathToVisible(selectedPath);
568:                tree.expandPath(selectedPath);
569:                tree.setSelectionPath(selectedPath);
570:                Rectangle rect = getCellRect(rowIdx, 0, true);
571:                Container p = getParent();
572:                if (p instanceof  JViewport)
573:                    ((JViewport) p).setViewPosition(new Point(rect.x, Math.max(
574:                            0, rect.y
575:                                    - ((JScrollPane) p.getParent()).getHeight()
576:                                    / 2)));
577:            }
578:
579:            /**
580:             * Invoked to reload the children of a particular node. This will
581:             * also restart the timer.
582:             */
583:            protected void reload(Object node) {
584:                model.reloadChildren(node);
585:                //reload();
586:            }
587:
588:            /**
589:             * A TreeCellRenderer that displays a JTree.
590:             */
591:            public class TreeTableCellRenderer extends JTree implements 
592:                    TableCellRenderer {
593:                /** Last table/tree row asked to renderer. */
594:                protected int visibleRow;
595:
596:                public TreeTableCellRenderer(TreeModel model) {
597:                    super (model);
598:                    setCellRenderer(new TreeTableTreeCellRenderer());
599:                }
600:
601:                /**
602:                 * updateUI is overridden to set the colors of the Tree's renderer
603:                 * to match that of the table.
604:                 */
605:                public void updateUI() {
606:                    super .updateUI();
607:                    // Make the tree's cell renderer use the table's cell selection
608:                    // colors.
609:                    TreeCellRenderer tcr = getCellRenderer();
610:                    if (tcr instanceof  DefaultTreeCellRenderer) {
611:                        DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer) tcr);
612:                        // For 1.1 uncomment this, 1.2 has a bug that will cause an
613:                        // exception to be thrown if the border selection color is
614:                        // null.
615:                        // dtcr.setBorderSelectionColor(null);
616:                        dtcr.setTextSelectionColor(UIManager
617:                                .getColor("Table.selectionForeground"));
618:                        dtcr.setBackgroundSelectionColor(UIManager
619:                                .getColor("Table.selectionBackground"));
620:                    }
621:                }
622:
623:                public void setTreeIcons(ImageIcon leafIcon,
624:                        ImageIcon openIcon, ImageIcon closedIcon) {
625:                    TreeCellRenderer tcr = getCellRenderer();
626:                    if (tcr instanceof  DefaultTreeCellRenderer) {
627:                        DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer) tcr);
628:                        dtcr.setLeafIcon(leafIcon);
629:                        dtcr.setClosedIcon(closedIcon);
630:                        dtcr.setOpenIcon(openIcon);
631:                    }
632:                }
633:
634:                /**
635:                 * Sets the row height of the tree, and forwards the row height to
636:                 * the table.
637:                 */
638:                public void setRowHeight(int rowHeight) {
639:                    if (rowHeight > 0) {
640:                        super .setRowHeight(rowHeight);
641:                        if (XTreeTable.this  != null
642:                                && XTreeTable.this .getRowHeight() != rowHeight) {
643:                            XTreeTable.this .setRowHeight(getRowHeight());
644:                        }
645:                    }
646:                }
647:
648:                /**
649:                 * This is overridden to set the height to match that of the JTable.
650:                 */
651:                public void setBounds(int x, int y, int w, int h) {
652:                    super .setBounds(x, 0, w, XTreeTable.this .getHeight());
653:                }
654:
655:                /**
656:                 * Sublcassed to translate the graphics such that the last visible
657:                 * row will be drawn at 0,0.
658:                 */
659:                public void paint(Graphics g) {
660:                    g.translate(0, -visibleRow * getRowHeight());
661:                    super .paint(g);
662:                }
663:
664:                /**
665:                 * TreeCellRenderer method. Overridden to update the visible row.
666:                 */
667:                public Component getTableCellRendererComponent(JTable table,
668:                        Object value, boolean isSelected, boolean hasFocus,
669:                        int row, int column) {
670:                    percentage = 100;
671:                    if (!table.isEnabled())
672:                        percentage = 50;
673:
674:                    if (isSelected) {
675:                        setBackground(XuiUtilities.unsaturateColor(table
676:                                .getSelectionBackground(), percentage));
677:                    } else if (((row % 2) == 1)
678:                            && (altUnselectedBackground != null))
679:                        setBackground(XuiUtilities.unsaturateColor(
680:                                altUnselectedBackground, percentage));
681:                    else
682:                        setBackground(XuiUtilities.unsaturateColor(table
683:                                .getBackground(), percentage));
684:
685:                    if (isSelected)
686:                        setForeground(table.getSelectionForeground());
687:                    else if (((row % 2) == 1)
688:                            && (altUnselectedForeground != null))
689:                        setForeground(altUnselectedForeground);
690:                    else
691:                        setForeground(table.getForeground());
692:
693:                    visibleRow = row;
694:                    return this ;
695:                }
696:            }
697:
698:            public class TreeTableTreeCellRenderer extends
699:                    DefaultTreeCellRenderer {
700:                Color defaultBackgroundColor;
701:                Color defaultTextColor;
702:
703:                public TreeTableTreeCellRenderer() {
704:                    super ();
705:                    defaultBackgroundColor = getBackgroundNonSelectionColor();
706:                    defaultTextColor = getTextNonSelectionColor();
707:                }
708:
709:                /**
710:                 * TreeCellRenderer method. Overridden to update the visible row.
711:                 */
712:                public Component getTreeCellRendererComponent(JTree tree,
713:                        Object value, boolean isSelected, boolean expanded,
714:                        boolean leaf, int row, boolean hasFocus) {
715:                    super .getTreeCellRendererComponent(tree, value, isSelected,
716:                            expanded, leaf, row, hasFocus);
717:
718:                    if (!isSelected) {
719:                        if (((row % 2) == 1)
720:                                && (altUnselectedBackground != null))
721:                            setBackgroundNonSelectionColor(XuiUtilities
722:                                    .unsaturateColor(altUnselectedBackground,
723:                                            percentage));
724:                        else
725:                            setBackgroundNonSelectionColor(XuiUtilities
726:                                    .unsaturateColor(defaultBackgroundColor,
727:                                            percentage));
728:
729:                        if (((row % 2) == 1)
730:                                && (altUnselectedForeground != null))
731:                            setTextNonSelectionColor(XuiUtilities
732:                                    .unsaturateColor(altUnselectedForeground,
733:                                            percentage));
734:                        else
735:                            setTextNonSelectionColor(XuiUtilities
736:                                    .unsaturateColor(defaultTextColor,
737:                                            percentage));
738:                    }
739:
740:                    return this ;
741:                }
742:            }
743:
744:            /**
745:             * TreeTableCellEditor implementation. Component returned is the
746:             * JTree.
747:             */
748:            public class TreeTableCellEditor extends
749:                    com.xoetrope.swing.treetable.AbstractCellEditor implements 
750:                    TableCellEditor {
751:                public Component getTableCellEditorComponent(JTable table,
752:                        Object value, boolean isSelected, int r, int c) {
753:                    return tree;
754:                }
755:
756:                /**
757:                 * Overridden to return false, and if the event is a mouse event
758:                 * it is forwarded to the tree.<p>
759:                 * The behavior for this is debatable, and should really be offered
760:                 * as a property. By returning false, all keyboard actions are
761:                 * implemented in terms of the table. By returning true, the
762:                 * tree would get a chance to do something with the keyboard
763:                 * events. For the most part this is ok. But for certain keys,
764:                 * such as left/right, the tree will expand/collapse where as
765:                 * the table focus should really move to a different column. Page
766:                 * up/down should also be implemented in terms of the table.
767:                 * By returning false this also has the added benefit that clicking
768:                 * outside of the bounds of the tree node, but still in the tree
769:                 * column will select the row, whereas if this returned true
770:                 * that wouldn't be the case.
771:                 * <p>By returning false we are also enforcing the policy that
772:                 * the tree will never be editable (at least by a key sequence).
773:                 */
774:                public boolean isCellEditable(EventObject e) {
775:                    if (e instanceof  MouseEvent) {
776:                        for (int counter = getColumnCount() - 1; counter >= 0; counter--) {
777:                            if (getColumnClass(counter) == TreeTableModel.class) {
778:                                MouseEvent me = (MouseEvent) e;
779:                                MouseEvent newME = new MouseEvent(tree, me
780:                                        .getID(), me.getWhen(), me
781:                                        .getModifiers(), me.getX()
782:                                        - getCellRect(0, counter, true).x, me
783:                                        .getY(), me.getClickCount(), me
784:                                        .isPopupTrigger());
785:                                tree.dispatchEvent(newME);
786:                                break;
787:                            }
788:                        }
789:                    }
790:                    return false;
791:                }
792:            }
793:
794:            /**
795:             * ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel
796:             * to listen for changes in the ListSelectionModel it maintains. Once
797:             * a change in the ListSelectionModel happens, the paths are updated
798:             * in the DefaultTreeSelectionModel.
799:             */
800:            class ListToTreeSelectionModelWrapper extends
801:                    DefaultTreeSelectionModel {
802:                /** Set to true when we are updating the ListSelectionModel. */
803:                protected boolean updatingListSelectionModel;
804:
805:                public ListToTreeSelectionModelWrapper() {
806:                    super ();
807:                    getListSelectionModel().addListSelectionListener(
808:                            createListSelectionListener());
809:                }
810:
811:                /**
812:                 * Returns the list selection model. ListToTreeSelectionModelWrapper
813:                 * listens for changes to this model and updates the selected paths
814:                 * accordingly.
815:                 */
816:                ListSelectionModel getListSelectionModel() {
817:                    return listSelectionModel;
818:                }
819:
820:                /**
821:                 * This is overridden to set <code>updatingListSelectionModel</code>
822:                 * and message super. This is the only place DefaultTreeSelectionModel
823:                 * alters the ListSelectionModel.
824:                 */
825:                public void resetRowSelection() {
826:                    if (!updatingListSelectionModel) {
827:                        updatingListSelectionModel = true;
828:                        try {
829:                            super .resetRowSelection();
830:                        } finally {
831:                            updatingListSelectionModel = false;
832:                        }
833:                    }
834:                    // Notice how we don't message super if
835:                    // updatingListSelectionModel is true. If
836:                    // updatingListSelectionModel is true, it implies the
837:                    // ListSelectionModel has already been updated and the
838:                    // paths are the only thing that needs to be updated.
839:                }
840:
841:                /**
842:                 * Creates and returns an instance of ListSelectionHandler.
843:                 */
844:                protected ListSelectionListener createListSelectionListener() {
845:                    return new ListSelectionHandler();
846:                }
847:
848:                /**
849:                 * If <code>updatingListSelectionModel</code> is false, this will
850:                 * reset the selected paths from the selected rows in the list
851:                 * selection model.
852:                 */
853:                protected void updateSelectedPathsFromSelectedRows() {
854:                    if (!updatingListSelectionModel) {
855:                        updatingListSelectionModel = true;
856:                        try {
857:                            // This is way expensive, ListSelectionModel needs an
858:                            // enumerator for iterating.
859:                            int min = listSelectionModel.getMinSelectionIndex();
860:                            int max = listSelectionModel.getMaxSelectionIndex();
861:
862:                            clearSelection();
863:                            if (min != -1 && max != -1) {
864:                                for (int counter = min; counter <= max; counter++) {
865:                                    if (listSelectionModel
866:                                            .isSelectedIndex(counter)) {
867:                                        TreePath selPath = tree
868:                                                .getPathForRow(counter);
869:                                        if (selPath != null)
870:                                            addSelectionPath(selPath);
871:                                    }
872:                                }
873:                            }
874:                        } finally {
875:                            updatingListSelectionModel = false;
876:                        }
877:                    }
878:                }
879:
880:                /**
881:                 * Class responsible for calling updateSelectedPathsFromSelectedRows
882:                 * when the selection of the list changse.
883:                 */
884:                class ListSelectionHandler implements  ListSelectionListener {
885:                    public void valueChanged(ListSelectionEvent e) {
886:                        updateSelectedPathsFromSelectedRows();
887:                    }
888:                }
889:            }
890:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.