Source Code Cross Referenced for PropertySheetTable.java in  » Swing-Library » l2fprod-common » com » l2fprod » common » propertysheet » 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 » Swing Library » l2fprod common » com.l2fprod.common.propertysheet 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * L2FProd.com Common Components 7.3 License.
003:         *
004:         * Copyright 2005-2007 L2FProd.com
005:         *
006:         * Licensed under the Apache License, Version 2.0 (the "License");
007:         * you may not use this file except in compliance with the License.
008:         * You may obtain a copy of the License at
009:         *
010:         *     http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing, software
013:         * distributed under the License is distributed on an "AS IS" BASIS,
014:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:         * See the License for the specific language governing permissions and
016:         * limitations under the License.
017:         */package com.l2fprod.common.propertysheet;
018:
019:        import com.l2fprod.common.propertysheet.PropertySheetTableModel.Item;
020:        import com.l2fprod.common.swing.HeaderlessColumnResizer;
021:
022:        import java.awt.Color;
023:        import java.awt.Component;
024:        import java.awt.Dimension;
025:        import java.awt.Graphics;
026:        import java.awt.Insets;
027:        import java.awt.event.ActionEvent;
028:        import java.awt.event.KeyEvent;
029:        import java.awt.event.MouseAdapter;
030:        import java.awt.event.MouseEvent;
031:        import java.beans.PropertyEditor;
032:
033:        import javax.swing.AbstractAction;
034:        import javax.swing.CellEditor;
035:        import javax.swing.Icon;
036:        import javax.swing.JTable;
037:        import javax.swing.KeyStroke;
038:        import javax.swing.ListSelectionModel;
039:        import javax.swing.UIManager;
040:        import javax.swing.border.Border;
041:        import javax.swing.event.TableModelEvent;
042:        import javax.swing.event.TableModelListener;
043:        import javax.swing.table.DefaultTableCellRenderer;
044:        import javax.swing.table.TableCellEditor;
045:        import javax.swing.table.TableCellRenderer;
046:        import javax.swing.table.TableModel;
047:
048:        /**
049:         * A table which allows the editing of Properties through
050:         * PropertyEditors. The PropertyEditors can be changed by using the
051:         * PropertyEditorRegistry.
052:         */
053:        public class PropertySheetTable extends JTable {
054:
055:            private static final int HOTSPOT_SIZE = 18;
056:
057:            private static final String TREE_EXPANDED_ICON_KEY = "Tree.expandedIcon";
058:            private static final String TREE_COLLAPSED_ICON_KEY = "Tree.collapsedIcon";
059:            private static final String TABLE_BACKGROUND_COLOR_KEY = "Table.background";
060:            private static final String TABLE_FOREGROUND_COLOR_KEY = "Table.foreground";
061:            private static final String TABLE_SELECTED_BACKGROUND_COLOR_KEY = "Table.selectionBackground";
062:            private static final String TABLE_SELECTED_FOREGROUND_COLOR_KEY = "Table.selectionForeground";
063:            private static final String PANEL_BACKGROUND_COLOR_KEY = "Panel.background";
064:
065:            private PropertyEditorFactory editorFactory;
066:            private PropertyRendererFactory rendererFactory;
067:
068:            private TableCellRenderer nameRenderer;
069:
070:            private boolean wantsExtraIndent = false;
071:
072:            /**
073:             * Cancel editing when editing row is changed
074:             */
075:            private TableModelListener cancelEditing;
076:
077:            // Colors used by renderers
078:            private Color categoryBackground;
079:            private Color categoryForeground;
080:            private Color propertyBackground;
081:            private Color propertyForeground;
082:            private Color selectedPropertyBackground;
083:            private Color selectedPropertyForeground;
084:            private Color selectedCategoryBackground;
085:            private Color selectedCategoryForeground;
086:
087:            public PropertySheetTable() {
088:                this (new PropertySheetTableModel());
089:            }
090:
091:            public PropertySheetTable(PropertySheetTableModel dm) {
092:                super (dm);
093:                initDefaultColors();
094:
095:                // select only one property at a time
096:                getSelectionModel().setSelectionMode(
097:                        ListSelectionModel.SINGLE_SELECTION);
098:
099:                // hide the table header, we do not need it
100:                Dimension nullSize = new Dimension(0, 0);
101:                getTableHeader().setPreferredSize(nullSize);
102:                getTableHeader().setMinimumSize(nullSize);
103:                getTableHeader().setMaximumSize(nullSize);
104:                getTableHeader().setVisible(false);
105:
106:                // table header not being visible, make sure we can still resize the columns
107:                new HeaderlessColumnResizer(this );
108:
109:                // default renderers and editors
110:                setRendererFactory(new PropertyRendererRegistry());
111:                setEditorFactory(new PropertyEditorRegistry());
112:
113:                nameRenderer = new NameRenderer();
114:
115:                // force the JTable to commit the edit when it losts focus
116:                putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
117:
118:                // only full rows can be selected
119:                setColumnSelectionAllowed(false);
120:                setRowSelectionAllowed(true);
121:
122:                // replace the edit action to always trigger the editing of the value column
123:                getActionMap().put("startEditing", new StartEditingAction());
124:
125:                // ensure navigating with "TAB" moves to the next row
126:                getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0),
127:                        "selectNextRowCell");
128:                getInputMap().put(
129:                        KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
130:                                KeyEvent.SHIFT_DOWN_MASK),
131:                        "selectPreviousRowCell");
132:
133:                // allow category toggle with SPACE and mouse
134:                getActionMap().put("toggle", new ToggleAction());
135:                getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
136:                        "toggle");
137:                addMouseListener(new ToggleMouseHandler());
138:            }
139:
140:            /**
141:             * Initializes the default set of colors used by the PropertySheetTable.
142:             * 
143:             * @see #categoryBackground
144:             * @see #categoryForeground
145:             * @see #selectedCategoryBackground
146:             * @see #selectedCategoryForeground
147:             * @see #propertyBackground
148:             * @see #propertyForeground
149:             * @see #selectedPropertyBackground
150:             * @see #selectedPropertyForeground
151:             */
152:            private void initDefaultColors() {
153:                this .categoryBackground = UIManager
154:                        .getColor(PANEL_BACKGROUND_COLOR_KEY);
155:                this .categoryForeground = UIManager.getColor(
156:                        TABLE_FOREGROUND_COLOR_KEY).darker().darker().darker();
157:
158:                this .selectedCategoryBackground = categoryBackground.darker();
159:                this .selectedCategoryForeground = categoryForeground;
160:
161:                this .propertyBackground = UIManager
162:                        .getColor(TABLE_BACKGROUND_COLOR_KEY);
163:                this .propertyForeground = UIManager
164:                        .getColor(TABLE_FOREGROUND_COLOR_KEY);
165:
166:                this .selectedPropertyBackground = UIManager
167:                        .getColor(TABLE_SELECTED_BACKGROUND_COLOR_KEY);
168:                this .selectedPropertyForeground = UIManager
169:                        .getColor(TABLE_SELECTED_FOREGROUND_COLOR_KEY);
170:
171:                setGridColor(categoryBackground);
172:            }
173:
174:            public Color getCategoryBackground() {
175:                return categoryBackground;
176:            }
177:
178:            /**
179:             * Sets the color used to paint a Category background.
180:             * 
181:             * @param categoryBackground
182:             */
183:            public void setCategoryBackground(Color categoryBackground) {
184:                this .categoryBackground = categoryBackground;
185:                repaint();
186:            }
187:
188:            public Color getCategoryForeground() {
189:                return categoryForeground;
190:            }
191:
192:            /**
193:             * Sets the color used to paint a Category foreground.
194:             * 
195:             * @param categoryForeground
196:             */
197:            public void setCategoryForeground(Color categoryForeground) {
198:                this .categoryForeground = categoryForeground;
199:                repaint();
200:            }
201:
202:            public Color getSelectedCategoryBackground() {
203:                return selectedCategoryBackground;
204:            }
205:
206:            /**
207:             * Sets the color used to paint a selected/focused Category background.
208:             * 
209:             * @param selectedCategoryBackground
210:             */
211:            public void setSelectedCategoryBackground(
212:                    Color selectedCategoryBackground) {
213:                this .selectedCategoryBackground = selectedCategoryBackground;
214:                repaint();
215:            }
216:
217:            public Color getSelectedCategoryForeground() {
218:                return selectedCategoryForeground;
219:            }
220:
221:            /**
222:             * Sets the color used to paint a selected/focused Category foreground.
223:             * 
224:             * @param selectedCategoryForeground
225:             */
226:            public void setSelectedCategoryForeground(
227:                    Color selectedCategoryForeground) {
228:                this .selectedCategoryForeground = selectedCategoryForeground;
229:                repaint();
230:            }
231:
232:            public Color getPropertyBackground() {
233:                return propertyBackground;
234:            }
235:
236:            /**
237:             * Sets the color used to paint a Property background.
238:             * 
239:             * @param propertyBackground
240:             */
241:            public void setPropertyBackground(Color propertyBackground) {
242:                this .propertyBackground = propertyBackground;
243:                repaint();
244:            }
245:
246:            public Color getPropertyForeground() {
247:                return propertyForeground;
248:            }
249:
250:            /**
251:             * Sets the color used to paint a Property foreground.
252:             * 
253:             * @param propertyForeground
254:             */
255:            public void setPropertyForeground(Color propertyForeground) {
256:                this .propertyForeground = propertyForeground;
257:                repaint();
258:            }
259:
260:            public Color getSelectedPropertyBackground() {
261:                return selectedPropertyBackground;
262:            }
263:
264:            /**
265:             * Sets the color used to paint a selected/focused Property background.
266:             * 
267:             * @param selectedPropertyBackground
268:             */
269:            public void setSelectedPropertyBackground(
270:                    Color selectedPropertyBackground) {
271:                this .selectedPropertyBackground = selectedPropertyBackground;
272:                repaint();
273:            }
274:
275:            public Color getSelectedPropertyForeground() {
276:                return selectedPropertyForeground;
277:            }
278:
279:            /**
280:             * Sets the color used to paint a selected/focused Property foreground.
281:             * 
282:             * @param selectedPropertyForeground
283:             */
284:            public void setSelectedPropertyForeground(
285:                    Color selectedPropertyForeground) {
286:                this .selectedPropertyForeground = selectedPropertyForeground;
287:                repaint();
288:            }
289:
290:            public void setEditorFactory(PropertyEditorFactory factory) {
291:                editorFactory = factory;
292:            }
293:
294:            public final PropertyEditorFactory getEditorFactory() {
295:                return editorFactory;
296:            }
297:
298:            /**
299:             * @param registry
300:             * @deprecated use {@link #setEditorFactory(PropertyEditorFactory)}
301:             */
302:            public void setEditorRegistry(PropertyEditorRegistry registry) {
303:                setEditorFactory(registry);
304:            }
305:
306:            /**
307:             * @deprecated use {@link #getEditorFactory()}
308:             * @throws ClassCastException if the current editor factory is not a
309:             *           PropertyEditorRegistry
310:             */
311:            public PropertyEditorRegistry getEditorRegistry() {
312:                return (PropertyEditorRegistry) editorFactory;
313:            }
314:
315:            public void setRendererFactory(PropertyRendererFactory factory) {
316:                rendererFactory = factory;
317:            }
318:
319:            public PropertyRendererFactory getRendererFactory() {
320:                return rendererFactory;
321:            }
322:
323:            /**
324:             * @deprecated use {@link #setRendererFactory(PropertyRendererFactory)}
325:             * @param registry
326:             */
327:            public void setRendererRegistry(PropertyRendererRegistry registry) {
328:                setRendererFactory(registry);
329:            }
330:
331:            /**
332:             * @deprecated use {@link #getRendererFactory()}
333:             * @throws ClassCastException if the current renderer factory is not a
334:             *           PropertyRendererRegistry
335:             */
336:            public PropertyRendererRegistry getRendererRegistry() {
337:                return (PropertyRendererRegistry) getRendererFactory();
338:            }
339:
340:            /* (non-Javadoc)
341:             * @see javax.swing.JTable#isCellEditable(int, int)
342:             */
343:            public boolean isCellEditable(int row, int column) {
344:                // names are not editable
345:                if (column == 0) {
346:                    return false;
347:                }
348:
349:                PropertySheetTableModel.Item item = getSheetModel()
350:                        .getPropertySheetElement(row);
351:                return item.isProperty() && item.getProperty().isEditable();
352:            }
353:
354:            /**
355:             * Gets the CellEditor for the given row and column. It uses the
356:             * editor registry to find a suitable editor for the property.
357:             * @see javax.swing.JTable#getCellEditor(int, int)
358:             */
359:            public TableCellEditor getCellEditor(int row, int column) {
360:                if (column == 0) {
361:                    return null;
362:                }
363:
364:                Item item = getSheetModel().getPropertySheetElement(row);
365:                if (!item.isProperty())
366:                    return null;
367:
368:                TableCellEditor result = null;
369:                Property propery = item.getProperty();
370:                PropertyEditor editor = getEditorFactory()
371:                        .createPropertyEditor(propery);
372:                if (editor != null)
373:                    result = new CellEditorAdapter(editor);
374:
375:                return result;
376:            }
377:
378:            /* (non-Javadoc)
379:             * @see javax.swing.JTable#getCellRenderer(int, int)
380:             */
381:            public TableCellRenderer getCellRenderer(int row, int column) {
382:                PropertySheetTableModel.Item item = getSheetModel()
383:                        .getPropertySheetElement(row);
384:
385:                switch (column) {
386:                case PropertySheetTableModel.NAME_COLUMN:
387:                    // name column gets a custom renderer
388:                    return nameRenderer;
389:
390:                case PropertySheetTableModel.VALUE_COLUMN: {
391:                    if (!item.isProperty())
392:                        return nameRenderer;
393:
394:                    // property value column gets the renderer from the factory
395:                    Property property = item.getProperty();
396:                    TableCellRenderer renderer = getRendererFactory()
397:                            .createTableCellRenderer(property);
398:                    if (renderer == null)
399:                        renderer = getCellRenderer(property.getType());
400:                    return renderer;
401:                }
402:                default:
403:                    // when will this happen, given the above?
404:                    return super .getCellRenderer(row, column);
405:                }
406:            }
407:
408:            /**
409:             * Helper method to lookup a cell renderer based on type.
410:             * @param type the type for which a renderer should be found
411:             * @return a renderer for the given object type
412:             */
413:            private TableCellRenderer getCellRenderer(Class type) {
414:                // try to create one from the factory
415:                TableCellRenderer renderer = getRendererFactory()
416:                        .createTableCellRenderer(type);
417:
418:                // if that fails, recursively try again with the superclass
419:                if (renderer == null && type != null)
420:                    renderer = getCellRenderer(type.getSuperclass());
421:
422:                // if that fails, just use the default Object renderer
423:                if (renderer == null)
424:                    renderer = super .getDefaultRenderer(Object.class);
425:
426:                return renderer;
427:            }
428:
429:            public final PropertySheetTableModel getSheetModel() {
430:                return (PropertySheetTableModel) getModel();
431:            }
432:
433:            /**
434:             * Overriden
435:             * <li>to prevent the cell focus rect to be painted
436:             * <li>to disable ({@link Component#setEnabled(boolean)} the renderer if the
437:             * Property is not editable
438:             */
439:            public Component prepareRenderer(TableCellRenderer renderer,
440:                    int row, int column) {
441:                Object value = getValueAt(row, column);
442:                boolean isSelected = isCellSelected(row, column);
443:                Component component = renderer.getTableCellRendererComponent(
444:                        this , value, isSelected, false, row, column);
445:
446:                PropertySheetTableModel.Item item = getSheetModel()
447:                        .getPropertySheetElement(row);
448:                if (item.isProperty()) {
449:                    component.setEnabled(item.getProperty().isEditable());
450:                }
451:                return component;
452:            }
453:
454:            /**
455:             * Overriden to register a listener on the model. This listener ensures
456:             * editing is cancelled when editing row is being changed.
457:             * 
458:             * @see javax.swing.JTable#setModel(javax.swing.table.TableModel)
459:             * @throws IllegalArgumentException
460:             *           if dataModel is not a {@link PropertySheetTableModel}
461:             */
462:            public void setModel(TableModel newModel) {
463:                if (!(newModel instanceof  PropertySheetTableModel)) {
464:                    throw new IllegalArgumentException(
465:                            "dataModel must be of type "
466:                                    + PropertySheetTableModel.class.getName());
467:                }
468:
469:                if (cancelEditing == null) {
470:                    cancelEditing = new CancelEditing();
471:                }
472:
473:                TableModel oldModel = getModel();
474:                if (oldModel != null) {
475:                    oldModel.removeTableModelListener(cancelEditing);
476:                }
477:                super .setModel(newModel);
478:                newModel.addTableModelListener(cancelEditing);
479:
480:                // ensure the "value" column can not be resized
481:                getColumnModel().getColumn(1).setResizable(false);
482:            }
483:
484:            /**
485:             * @see #setWantsExtraIndent(boolean)
486:             */
487:            public boolean getWantsExtraIndent() {
488:                return wantsExtraIndent;
489:            }
490:
491:            /**
492:             * By default, properties with children are painted with the same indent level
493:             * as other properties and categories. When nested properties exist within the
494:             * set of properties, the end-user might be confused by the category and
495:             * property handles. Sets this property to true to add an extra indent level
496:             * to properties.
497:             * 
498:             * @param wantsExtraIndent
499:             */
500:            public void setWantsExtraIndent(boolean wantsExtraIndent) {
501:                this .wantsExtraIndent = wantsExtraIndent;
502:                repaint();
503:            }
504:
505:            /**
506:             * Ensures the table uses the full height of its parent
507:             * {@link javax.swing.JViewport}.
508:             */
509:            public boolean getScrollableTracksViewportHeight() {
510:                return getPreferredSize().height < getParent().getHeight();
511:            }
512:
513:            /**
514:             * Commits on-going cell editing 
515:             */
516:            public void commitEditing() {
517:                TableCellEditor editor = getCellEditor();
518:                if (editor != null) {
519:                    editor.stopCellEditing();
520:                }
521:            }
522:
523:            /**
524:             * Cancels on-going cell editing 
525:             */
526:            public void cancelEditing() {
527:                TableCellEditor editor = getCellEditor();
528:                if (editor != null) {
529:                    editor.cancelCellEditing();
530:                }
531:            }
532:
533:            /**
534:             * Cancels the cell editing if any update happens while modifying a value.
535:             */
536:            private class CancelEditing implements  TableModelListener {
537:                public void tableChanged(TableModelEvent e) {
538:                    // in case the table changes for the following reasons:
539:                    // * the editing row has changed
540:                    // * the editing row was removed
541:                    // * all rows were changed
542:                    // * rows were added
543:                    //
544:                    // it is better to cancel the editing of the row as our editor
545:                    // may no longer be the right one. It happens when you play with
546:                    // the sorting while having the focus in one editor.
547:                    if (e.getType() == TableModelEvent.UPDATE) {
548:                        int first = e.getFirstRow();
549:                        int last = e.getLastRow();
550:                        int editingRow = PropertySheetTable.this 
551:                                .getEditingRow();
552:
553:                        TableCellEditor editor = PropertySheetTable.this 
554:                                .getCellEditor();
555:                        if (editor != null && first <= editingRow
556:                                && editingRow <= last) {
557:                            editor.cancelCellEditing();
558:                        }
559:                    }
560:                }
561:            }
562:
563:            /**
564:             * Starts value cell editing even if value cell does not have the focus but
565:             * only if row is selected.
566:             */
567:            private static class StartEditingAction extends AbstractAction {
568:                public void actionPerformed(ActionEvent e) {
569:                    JTable table = (JTable) e.getSource();
570:                    if (!table.hasFocus()) {
571:                        CellEditor cellEditor = table.getCellEditor();
572:                        if (cellEditor != null && !cellEditor.stopCellEditing()) {
573:                            return;
574:                        }
575:                        table.requestFocus();
576:                        return;
577:                    }
578:                    ListSelectionModel rsm = table.getSelectionModel();
579:                    int anchorRow = rsm.getAnchorSelectionIndex();
580:                    table.editCellAt(anchorRow,
581:                            PropertySheetTableModel.VALUE_COLUMN);
582:                    Component editorComp = table.getEditorComponent();
583:                    if (editorComp != null) {
584:                        editorComp.requestFocus();
585:                    }
586:                }
587:            }
588:
589:            /**
590:             * Toggles the state of a row between expanded/collapsed. Works only for rows
591:             * with "toggle" knob.
592:             */
593:            private class ToggleAction extends AbstractAction {
594:                public void actionPerformed(ActionEvent e) {
595:                    int row = PropertySheetTable.this .getSelectedRow();
596:                    Item item = PropertySheetTable.this .getSheetModel()
597:                            .getPropertySheetElement(row);
598:                    item.toggle();
599:                    PropertySheetTable.this .addRowSelectionInterval(row, row);
600:                }
601:
602:                public boolean isEnabled() {
603:                    int row = PropertySheetTable.this .getSelectedRow();
604:                    if (row != -1) {
605:                        Item item = PropertySheetTable.this .getSheetModel()
606:                                .getPropertySheetElement(row);
607:                        return item.hasToggle();
608:                    } else {
609:                        return false;
610:                    }
611:                }
612:            }
613:
614:            /**
615:             * @see ToggleAction
616:             */
617:            private static class ToggleMouseHandler extends MouseAdapter {
618:                public void mouseReleased(MouseEvent event) {
619:                    PropertySheetTable table = (PropertySheetTable) event
620:                            .getComponent();
621:                    int row = table.rowAtPoint(event.getPoint());
622:                    int column = table.columnAtPoint(event.getPoint());
623:                    if (row != -1 && column == 0) {
624:                        // if we clicked on an Item, see if we clicked on its hotspot
625:                        Item item = table.getSheetModel()
626:                                .getPropertySheetElement(row);
627:                        int x = event.getX() - getIndent(table, item);
628:                        if (x > 0 && x < HOTSPOT_SIZE)
629:                            item.toggle();
630:                    }
631:                }
632:            }
633:
634:            /**
635:             * Calculates the required left indent for a given item, given its type and
636:             * its hierarchy level.
637:             */
638:            static int getIndent(PropertySheetTable table, Item item) {
639:                int indent = 0;
640:
641:                if (item.isProperty()) {
642:                    // it is a property, it has no parent or a category, and no child
643:                    if ((item.getParent() == null || !item.getParent()
644:                            .isProperty())
645:                            && !item.hasToggle()) {
646:                        indent = table.getWantsExtraIndent() ? HOTSPOT_SIZE : 0;
647:                    } else {
648:                        // it is a property with children
649:                        if (item.hasToggle()) {
650:                            indent = item.getDepth() * HOTSPOT_SIZE;
651:                        } else {
652:                            indent = (item.getDepth() + 1) * HOTSPOT_SIZE;
653:                        }
654:                    }
655:
656:                    if (table.getSheetModel().getMode() == PropertySheet.VIEW_AS_CATEGORIES
657:                            && table.getWantsExtraIndent()) {
658:                        indent += HOTSPOT_SIZE;
659:                    }
660:
661:                } else {
662:                    // category has no indent
663:                    indent = 0;
664:                }
665:                return indent;
666:            }
667:
668:            /**
669:             * Paints the border around the name cell. It handles the indent from the left
670:             * side and the painting of the toggle knob.
671:             */
672:            private static class CellBorder implements  Border {
673:
674:                private int indentWidth; // space before hotspot
675:                private boolean showToggle;
676:                private boolean toggleState;
677:                private Icon expandedIcon;
678:                private Icon collapsedIcon;
679:                private Insets insets = new Insets(1, 0, 1, 1);
680:                private boolean isProperty;
681:
682:                public CellBorder() {
683:                    expandedIcon = (Icon) UIManager.get(TREE_EXPANDED_ICON_KEY);
684:                    collapsedIcon = (Icon) UIManager
685:                            .get(TREE_COLLAPSED_ICON_KEY);
686:                    if (expandedIcon == null) {
687:                        expandedIcon = new ExpandedIcon();
688:                    }
689:                    if (collapsedIcon == null) {
690:                        collapsedIcon = new CollapsedIcon();
691:                    }
692:                }
693:
694:                public void configure(PropertySheetTable table, Item item) {
695:                    isProperty = item.isProperty();
696:                    toggleState = item.isVisible();
697:                    showToggle = item.hasToggle();
698:
699:                    indentWidth = getIndent(table, item);
700:                    insets.left = indentWidth + (showToggle ? HOTSPOT_SIZE : 0)
701:                            + 2;
702:                    ;
703:                }
704:
705:                public Insets getBorderInsets(Component c) {
706:                    return insets;
707:                }
708:
709:                public void paintBorder(Component c, Graphics g, int x, int y,
710:                        int width, int height) {
711:                    if (!isProperty) {
712:                        Color oldColor = g.getColor();
713:                        g.setColor(c.getBackground());
714:                        g.fillRect(x, y, x + HOTSPOT_SIZE - 2, y + height);
715:                        g.setColor(oldColor);
716:                    }
717:
718:                    if (showToggle) {
719:                        Icon drawIcon = (toggleState ? expandedIcon
720:                                : collapsedIcon);
721:                        drawIcon.paintIcon(c, g, x + indentWidth
722:                                + (HOTSPOT_SIZE - 2 - drawIcon.getIconWidth())
723:                                / 2, y + (height - drawIcon.getIconHeight())
724:                                / 2);
725:                    }
726:                }
727:
728:                public boolean isBorderOpaque() {
729:                    return true;
730:                }
731:
732:            }
733:
734:            private static class ExpandedIcon implements  Icon {
735:                public void paintIcon(Component c, Graphics g, int x, int y) {
736:                    Color backgroundColor = c.getBackground();
737:
738:                    if (backgroundColor != null)
739:                        g.setColor(backgroundColor);
740:                    else
741:                        g.setColor(Color.white);
742:                    g.fillRect(x, y, 8, 8);
743:                    g.setColor(Color.gray);
744:                    g.drawRect(x, y, 8, 8);
745:                    g.setColor(Color.black);
746:                    g.drawLine(x + 2, y + 4, x + (6), y + 4);
747:                }
748:
749:                public int getIconWidth() {
750:                    return 9;
751:                }
752:
753:                public int getIconHeight() {
754:                    return 9;
755:                }
756:            }
757:
758:            private static class CollapsedIcon extends ExpandedIcon {
759:                public void paintIcon(Component c, Graphics g, int x, int y) {
760:                    super .paintIcon(c, g, x, y);
761:                    g.drawLine(x + 4, y + 2, x + 4, y + 6);
762:                }
763:            }
764:
765:            /**
766:             * A {@link TableCellRenderer} for property names.
767:             */
768:            private class NameRenderer extends DefaultTableCellRenderer {
769:
770:                private CellBorder border;
771:
772:                public NameRenderer() {
773:                    border = new CellBorder();
774:                }
775:
776:                private Color getForeground(boolean isProperty,
777:                        boolean isSelected) {
778:                    return (isProperty ? (isSelected ? selectedPropertyForeground
779:                            : propertyForeground)
780:                            : (isSelected ? selectedCategoryForeground
781:                                    : categoryForeground));
782:                }
783:
784:                private Color getBackground(boolean isProperty,
785:                        boolean isSelected) {
786:                    return (isProperty ? (isSelected ? selectedPropertyBackground
787:                            : propertyBackground)
788:                            : (isSelected ? selectedCategoryBackground
789:                                    : categoryBackground));
790:                }
791:
792:                public Component getTableCellRendererComponent(JTable table,
793:                        Object value, boolean isSelected, boolean hasFocus,
794:                        int row, int column) {
795:                    super .getTableCellRendererComponent(table, value,
796:                            isSelected, false, row, column);
797:                    PropertySheetTableModel.Item item = (Item) value;
798:
799:                    // shortcut if we are painting the category column
800:                    if (column == PropertySheetTableModel.VALUE_COLUMN
801:                            && !item.isProperty()) {
802:                        setBackground(getBackground(item.isProperty(),
803:                                isSelected));
804:                        setText("");
805:                        return this ;
806:                    }
807:
808:                    setBorder(border);
809:
810:                    // configure the border
811:                    border.configure((PropertySheetTable) table, item);
812:
813:                    setBackground(getBackground(item.isProperty(), isSelected));
814:                    setForeground(getForeground(item.isProperty(), isSelected));
815:
816:                    setEnabled(isSelected || !item.isProperty() ? true : item
817:                            .getProperty().isEditable());
818:                    setText(item.getName());
819:
820:                    return this;
821:                }
822:            }
823:
824:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.