Source Code Cross Referenced for LoggingPanel.java in  » GIS » GeoTools-2.4.1 » org » geotools » gui » 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 » GIS » GeoTools 2.4.1 » org.geotools.gui.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
005:         *    (C) 2002, Institut de Recherche pour le Développement
006:         *
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation; either
010:         *    version 2.1 of the License, or (at your option) any later version.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.gui.swing;
018:
019:        // Swing dependencies
020:        import javax.swing.JTable;
021:        import javax.swing.JPanel;
022:        import javax.swing.JFrame;
023:        import javax.swing.JDialog;
024:        import javax.swing.JComponent;
025:        import javax.swing.JScrollPane;
026:        import javax.swing.JDesktopPane;
027:        import javax.swing.JInternalFrame;
028:        import javax.swing.table.TableModel;
029:        import javax.swing.table.TableColumn;
030:        import javax.swing.table.TableColumnModel;
031:        import javax.swing.table.DefaultTableCellRenderer;
032:        import javax.swing.event.TableColumnModelListener;
033:        import javax.swing.event.TableColumnModelEvent;
034:        import javax.swing.event.ListSelectionEvent;
035:        import javax.swing.event.ChangeEvent;
036:
037:        // AWT
038:        import java.awt.Color;
039:        import java.awt.Frame;
040:        import java.awt.Dialog;
041:        import java.awt.Component;
042:        import java.awt.BorderLayout;
043:        import java.awt.event.WindowEvent;
044:        import java.awt.event.WindowAdapter;
045:
046:        // Logging
047:        import java.util.logging.Level;
048:        import java.util.logging.Logger;
049:        import java.util.logging.Handler;
050:        import java.util.logging.LogRecord;
051:
052:        // Collections
053:        import java.util.List;
054:        import java.util.Arrays;
055:        import java.util.ArrayList;
056:
057:        // Resources
058:        import org.geotools.util.logging.Logging;
059:        import org.geotools.resources.XArray;
060:        import org.geotools.resources.i18n.Vocabulary;
061:        import org.geotools.resources.i18n.VocabularyKeys;
062:        import org.geotools.resources.SwingUtilities;
063:
064:        /**
065:         * A panel displaying logging messages. The windows displaying Geotools's logging messages
066:         * can be constructed with the following code:
067:         *
068:         * <blockquote><pre>
069:         * new LoggingPanel("org.geotools").{@link #show(Component) show}(null);
070:         * </pre></blockquote>
071:         *
072:         * This panel is initially set to listen to messages of level {@link Level#CONFIG} or higher.
073:         * This level can be changed with <code>{@link #getHandler}.setLevel(aLevel)</code>.
074:         *
075:         * @since 2.0
076:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/widgets-swing/src/main/java/org/geotools/gui/swing/LoggingPanel.java $
077:         * @version $Id: LoggingPanel.java 27862 2007-11-12 19:51:19Z desruisseaux $
078:         * @author Martin Desruisseaux
079:         */
080:        public class LoggingPanel extends JPanel {
081:            /**
082:             * Enumeration class for columns to be shown in a {@link LoggingPanel}.
083:             * Valid columns include {@link #LOGGER LOGGER}, {@link #CLASS CLASS},
084:             * {@link #METHOD METHOD}, {@link #TIME_OF_DAY TIME_OF_DAY}, {@link #LEVEL LEVEL}
085:             * and {@link #MESSAGE MESSAGE}.
086:             *
087:             * @todo Use the enum keyword once J2SE 1.5 will be available.
088:             */
089:            public static final class Column {
090:                final int index;
091:
092:                Column(final int index) {
093:                    this .index = index;
094:                }
095:            }
096:
097:            /*
098:             * NOTE: Values for the following contants MUST match
099:             * index in the LoggingTableModel.COLUMN_NAMES array.
100:             */
101:            /** Constant for {@link #setColumnVisible}. */
102:            public static final Column LOGGER = new Column(0);
103:            /** Constant for {@link #setColumnVisible}. */
104:            public static final Column CLASS = new Column(1);
105:            /** Constant for {@link #setColumnVisible}. */
106:            public static final Column METHOD = new Column(2);
107:            /** Constant for {@link #setColumnVisible}. */
108:            public static final Column TIME_OF_DAY = new Column(3);
109:            /** Constant for {@link #setColumnVisible}. */
110:            public static final Column LEVEL = new Column(4);
111:            /** Constant for {@link #setColumnVisible}. */
112:            public static final Column MESSAGE = new Column(5);
113:
114:            /**
115:             * The background color for the columns prior to the logging message.
116:             */
117:            private static final Color INFO_BACKGROUND = new Color(240, 240,
118:                    240);
119:
120:            /**
121:             * The model for this component.
122:             */
123:            private final LoggingTableModel model = new LoggingTableModel();
124:
125:            /**
126:             * The table for displaying logging messages.
127:             */
128:            private final JTable table = new JTable(model);
129:
130:            /**
131:             * The levels for colors enumerated in {@code levelColors}. This array
132:             * <strong>must</strong> be in increasing order. Logging messages of level
133:             * {@code levelValues[i]} or higher will be displayed with foreground
134:             * color <code>levelColors[i*2]</code> and background color <code>levelColors[i*2+1]</code>.
135:             *
136:             * @see Level#intValue
137:             * @see #getForeground(LogRecord)
138:             * @see #getBackground(LogRecord)
139:             */
140:            private int[] levelValues = new int[0];
141:
142:            /**
143:             * Pairs of foreground and background colors to use for displaying logging messages.
144:             * Logging messages of level {@code levelValues[i]} or higher will be displayed
145:             * with foreground color <code>levelColors[i*2]</code> and background color
146:             * <code>levelColors[i*2+1]</code>.
147:             *
148:             * @see #getForeground(LogRecord)
149:             * @see #getBackground(LogRecord)
150:             */
151:            private final List levelColors = new ArrayList();
152:
153:            /**
154:             * The logger specified at construction time, or {@code null} if none.
155:             */
156:            private Logger logger;
157:
158:            /**
159:             * Constructs a new logging panel. This panel is not registered to any logger.
160:             * Registration can be done with the following code:
161:             *
162:             * <blockquote><pre>
163:             * logger.{@link Logger#addHandler addHandler}({@link #getHandler});
164:             * </pre></blockquote>
165:             */
166:            public LoggingPanel() {
167:                super (new BorderLayout());
168:                table.setShowGrid(false);
169:                table.setCellSelectionEnabled(false);
170:                table.setGridColor(Color.LIGHT_GRAY);
171:                table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
172:                table.setDefaultRenderer(Object.class, new CellRenderer());
173:
174:                if (true) {
175:                    int width = 300;
176:                    final TableColumnModel columns = table.getColumnModel();
177:                    for (int i = model.getColumnCount(); --i >= 0;) {
178:                        columns.getColumn(i).setPreferredWidth(width);
179:                        width = 80;
180:                    }
181:                }
182:
183:                final JScrollPane scroll = new JScrollPane(table);
184:                new AutoScroll(scroll.getVerticalScrollBar().getModel());
185:                add(scroll, BorderLayout.CENTER);
186:
187:                setLevelColor(Level.ALL, Color.GRAY, null);
188:                setLevelColor(Level.CONFIG, null, null);
189:                setLevelColor(Level.WARNING, Color.RED, null);
190:                setLevelColor(Level.SEVERE, Color.WHITE, Color.RED);
191:            }
192:
193:            /**
194:             * Constructs a new logging panel and register it to the specified logger.
195:             *
196:             * @param logger The logger to listen to, or {@code null} for the root logger.
197:             */
198:            public LoggingPanel(Logger logger) {
199:                this ();
200:                if (logger == null) {
201:                    logger = Logging.getLogger("");
202:                }
203:                logger.addHandler(getHandler());
204:                this .logger = logger;
205:            }
206:
207:            /**
208:             * Construct a logging panel and register it to the specified logger.
209:             *
210:             * @param logger The logger name to listen to, or {@code null} for the root logger.
211:             */
212:            public LoggingPanel(final String logger) {
213:                this (org.geotools.util.logging.Logging
214:                        .getLogger(logger != null ? logger : ""));
215:            }
216:
217:            /**
218:             * Returns the logging handler.
219:             */
220:            public Handler getHandler() {
221:                return model;
222:            }
223:
224:            /**
225:             * Returns {@code true} if the given column is visible.
226:             *
227:             * @param column The column to show or hide. May be one of {@link #LOGGER}, {@link #CLASS},
228:             *               {@link #METHOD}, {@link #TIME_OF_DAY}, {@link #LEVEL} or {@link #MESSAGE}.
229:             */
230:            public boolean isColumnVisible(final Column column) {
231:                return model.isColumnVisible(column.index);
232:            }
233:
234:            /**
235:             * Show or hide the given column.
236:             *
237:             * @param column The column to show or hide. May be one of {@link #LOGGER}, {@link #CLASS},
238:             *               {@link #METHOD}, {@link #TIME_OF_DAY}, {@link #LEVEL} or {@link #MESSAGE}.
239:             * @param visible The visible state for the specified column.
240:             */
241:            public void setColumnVisible(final Column column,
242:                    final boolean visible) {
243:                model.setColumnVisible(column.index, visible);
244:            }
245:
246:            /**
247:             * Returns the capacity. This is the maximum number of {@link LogRecord}s the handler
248:             * can memorize. If more messages are logged, then the earliest messages will be discarted.
249:             */
250:            public int getCapacity() {
251:                return model.getCapacity();
252:            }
253:
254:            /**
255:             * Set the capacity. This is the maximum number of {@link LogRecord}s the handler can
256:             * memorize. If more messages are logged, then the earliest messages will be discarted.
257:             */
258:            public void setCapacity(final int capacity) {
259:                model.setCapacity(capacity);
260:            }
261:
262:            /**
263:             * Returns the foreground color for the specified log record. This method is invoked at
264:             * rendering time for every cell in the table's "message" column. The default implementation
265:             * returns a color based on the record's level, using colors set with {@link #setLevelColor}.
266:             *
267:             * @param  record The record to get the foreground color.
268:             * @return The foreground color for the specified record,
269:             *         or {@code null} for the default color.
270:             */
271:            public Color getForeground(final LogRecord record) {
272:                return getColor(record, 0);
273:            }
274:
275:            /**
276:             * Returns the background color for the specified log record. This method is invoked at
277:             * rendering time for every cell in the table's "message" column. The default implementation
278:             * returns a color based on the record's level, using colors set with {@link #setLevelColor}.
279:             *
280:             * @param  record The record to get the background color.
281:             * @return The background color for the specified record,
282:             *         or {@code null} for the default color.
283:             */
284:            public Color getBackground(final LogRecord record) {
285:                return getColor(record, 1);
286:            }
287:
288:            /**
289:             * Returns the foreground or background color for the specified record.
290:             *
291:             * @param  record The record to get the color.
292:             * @param  offset 0 for the foreground color, or 1 for the background color.
293:             * @return The color for the specified record, or {@code null} for the default color.
294:             */
295:            private Color getColor(final LogRecord record, final int offset) {
296:                int i = Arrays.binarySearch(levelValues, record.getLevel()
297:                        .intValue());
298:                if (i < 0) {
299:                    i = ~i - 1; // "~" is the tild symbol, not minus.
300:                    if (i < 0) {
301:                        return null;
302:                    }
303:                }
304:                return (Color) levelColors.get(i * 2 + offset);
305:            }
306:
307:            /**
308:             * Set the foreground and background colors for messages of the specified level.
309:             * The specified colors will apply on any messages of level {@code level} or
310:             * greater, up to the next level set with an other call to {@code setLevelColor(...)}.
311:             *
312:             * @param level       The minimal level to set color for.
313:             * @param foreground  The foreground color, or {@code null} for the default color.
314:             * @param background  The background color, or {@code null} for the default color.
315:             */
316:            public void setLevelColor(final Level level,
317:                    final Color foreground, final Color background) {
318:                final int value = level.intValue();
319:                int i = Arrays.binarySearch(levelValues, value);
320:                if (i >= 0) {
321:                    i *= 2;
322:                    levelColors.set(i + 0, foreground);
323:                    levelColors.set(i + 1, background);
324:                } else {
325:                    i = ~i;
326:                    levelValues = XArray.insert(levelValues, i, 1);
327:                    levelValues[i] = value;
328:                    i *= 2;
329:                    levelColors.add(i + 0, foreground);
330:                    levelColors.add(i + 1, background);
331:                }
332:                assert XArray.isSorted(levelValues);
333:                assert levelValues.length * 2 == levelColors.size();
334:            }
335:
336:            /**
337:             * Layout this component. This method give all the remaining space, if any,
338:             * to the last table's column. This column is usually the one with logging
339:             * messages.
340:             */
341:            public void doLayout() {
342:                final TableColumnModel model = table.getColumnModel();
343:                final int messageColumn = model.getColumnCount() - 1;
344:                Component parent = table.getParent();
345:                int delta = parent.getWidth();
346:                if ((parent = parent.getParent()) instanceof  JScrollPane) {
347:                    delta -= ((JScrollPane) parent).getVerticalScrollBar()
348:                            .getPreferredSize().width;
349:                }
350:                for (int i = 0; i < messageColumn; i++) {
351:                    delta -= model.getColumn(i).getWidth();
352:                }
353:                final TableColumn column = model.getColumn(messageColumn);
354:                if (delta > Math.max(column.getWidth(), column
355:                        .getPreferredWidth())) {
356:                    column.setPreferredWidth(delta);
357:                }
358:                super .doLayout();
359:            }
360:
361:            /**
362:             * Convenience method showing this logging panel into a frame.
363:             * Different kinds of frame can be constructed according {@code owner} class:
364:             *
365:             * <ul>
366:             *   <li>If {@code owner} or one of its parent is a {@link JDesktopPane},
367:             *       then {@code panel} is added into a {@link JInternalFrame}.</li>
368:             *   <li>If {@code owner} or one of its parent is a {@link Frame} or a {@link Dialog},
369:             *       then {@code panel} is added into a {@link JDialog}.</li>
370:             *   <li>Otherwise, {@code panel} is added into a {@link JFrame}.</li>
371:             * </ul>
372:             *
373:             * @param  owner The owner, or {@code null} to show
374:             *         this logging panel in a top-level window.
375:             * @return The frame. May be a {@link JInternalFrame},
376:             *         a {@link JDialog} or a {@link JFrame}.
377:             */
378:            public Component show(final Component owner) {
379:                final Component frame = SwingUtilities.toFrame(owner, this ,
380:                        Vocabulary.format(VocabularyKeys.EVENT_LOGGER),
381:                        new WindowAdapter() {
382:                            public void windowClosed(WindowEvent event) {
383:                                dispose();
384:                            }
385:                        });
386:                frame.setSize(750, 300);
387:                frame.setVisible(true);
388:                doLayout();
389:                return frame;
390:            }
391:
392:            /**
393:             * Free any resources used by this {@code LoggingPanel}. If a {@link Logger} was
394:             * specified at construction time, then this method unregister the {@code LoggingPanel}'s
395:             * handler from the specified logger. Next, {@link Handler#close} is invoked.
396:             * <br><br>
397:             * This method is invoked automatically when the user close the windows created
398:             * with {@link #show(Component)}. If this {@code LoggingPanel} is displayed
399:             * by some other ways (for example if it has been added into a {@link JPanel}),
400:             * then this {@code dispose()} should be invoked explicitely when the container
401:             * is being discarted.
402:             */
403:            public void dispose() {
404:                final Handler handler = getHandler();
405:                while (logger != null) {
406:                    logger.removeHandler(handler);
407:                    logger = logger.getParent();
408:                }
409:                handler.close();
410:            }
411:
412:            /**
413:             * Display cell contents. This class is used for changing
414:             * the cell's color according the log record level.
415:             */
416:            private final class CellRenderer extends DefaultTableCellRenderer
417:                    implements  TableColumnModelListener {
418:                /**
419:                 * Default color for the foreground.
420:                 */
421:                private Color foreground;
422:
423:                /**
424:                 * Default color for the background.
425:                 */
426:                private Color background;
427:
428:                /**
429:                 * The index of messages column.
430:                 */
431:                private int messageColumn;
432:
433:                /**
434:                 * The last row for which the side has been computed.
435:                 */
436:                private int lastRow;
437:
438:                /**
439:                 * Construct a new cell renderer.
440:                 */
441:                public CellRenderer() {
442:                    foreground = super .getForeground();
443:                    background = super .getBackground();
444:                    table.getColumnModel().addColumnModelListener(this );
445:                }
446:
447:                /**
448:                 * Set the foreground color.
449:                 */
450:                public void setForeground(final Color foreground) {
451:                    super .setForeground(this .foreground = foreground);
452:                }
453:
454:                /**
455:                 * Set the background colior
456:                 */
457:                public void setBackground(final Color background) {
458:                    super .setBackground(this .background = background);
459:                }
460:
461:                /**
462:                 * Returns the component to use for painting the cell.
463:                 */
464:                public Component getTableCellRendererComponent(
465:                        final JTable table, final Object value,
466:                        final boolean isSelected, final boolean hasFocus,
467:                        final int rowIndex, final int columnIndex) {
468:                    Color foreground = this .foreground;
469:                    Color background = this .background;
470:                    final boolean isMessage = (columnIndex == messageColumn);
471:                    if (!isMessage) {
472:                        background = INFO_BACKGROUND;
473:                    }
474:                    if (rowIndex >= 0) {
475:                        final TableModel candidate = table.getModel();
476:                        if (candidate instanceof  LoggingTableModel) {
477:                            final LoggingTableModel model = (LoggingTableModel) candidate;
478:                            final LogRecord record = model
479:                                    .getLogRecord(rowIndex);
480:                            Color color;
481:                            color = LoggingPanel.this .getForeground(record);
482:                            if (color != null)
483:                                foreground = color;
484:                            color = LoggingPanel.this .getBackground(record);
485:                            if (color != null)
486:                                background = color;
487:                        }
488:                    }
489:                    super .setBackground(background);
490:                    super .setForeground(foreground);
491:                    final Component component = super 
492:                            .getTableCellRendererComponent(table, value,
493:                                    isSelected, hasFocus, rowIndex, columnIndex);
494:                    /*
495:                     * If a new record is being painted and this new record is wider
496:                     * than previous ones, then make the message column width larger.
497:                     */
498:                    if (isMessage) {
499:                        if (rowIndex > lastRow) {
500:                            final int width = component.getPreferredSize().width + 15;
501:                            final TableColumn column = table.getColumnModel()
502:                                    .getColumn(columnIndex);
503:                            if (width > column.getPreferredWidth()) {
504:                                column.setPreferredWidth(width);
505:                            }
506:                            if (rowIndex == lastRow + 1) {
507:                                lastRow = rowIndex;
508:                            }
509:                        }
510:                    }
511:                    return component;
512:                }
513:
514:                /**
515:                 * Invoked when the message column may have moved. This method update the
516:                 * {@link #messageColumn} field, so that the message column will continue
517:                 * to be paint with special colors.
518:                 */
519:                private final void update() {
520:                    messageColumn = table.convertColumnIndexToView(model
521:                            .getColumnCount() - 1);
522:                }
523:
524:                public void columnAdded(TableColumnModelEvent e) {
525:                    update();
526:                }
527:
528:                public void columnMarginChanged(ChangeEvent e) {
529:                    update();
530:                }
531:
532:                public void columnMoved(TableColumnModelEvent e) {
533:                    update();
534:                }
535:
536:                public void columnRemoved(TableColumnModelEvent e) {
537:                    update();
538:                }
539:
540:                public void columnSelectionChanged(ListSelectionEvent e) {
541:                    update();
542:                }
543:            }
544:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.