Source Code Cross Referenced for LoggingTableModel.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:        // Logging
020:        import java.util.logging.Level;
021:        import java.util.logging.Logger;
022:        import java.util.logging.Handler;
023:        import java.util.logging.LogRecord;
024:        import java.util.logging.SimpleFormatter;
025:
026:        // Table model
027:        import javax.swing.table.TableModel;
028:        import javax.swing.table.TableColumn;
029:        import javax.swing.table.TableColumnModel;
030:        import javax.swing.event.TableModelEvent;
031:        import javax.swing.event.TableModelListener;
032:        import javax.swing.event.EventListenerList;
033:        import java.awt.EventQueue;
034:
035:        // Collections
036:        import java.util.Map;
037:        import java.util.List;
038:        import java.util.ArrayList;
039:        import java.util.LinkedHashMap;
040:
041:        // Formatting
042:        import java.util.Date;
043:        import java.text.DateFormat;
044:
045:        // Resources
046:        import org.geotools.resources.XArray;
047:        import org.geotools.resources.i18n.Vocabulary;
048:        import org.geotools.resources.i18n.VocabularyKeys;
049:
050:        /**
051:         * A logging {@link Handler} storing {@link LogRecords} as a {@link TableModel}.
052:         * This model is used by {@link LoggingPanel} for displaying logging messages in
053:         * a {@link javax.swing.JTable}.
054:         *
055:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/widgets-swing/src/main/java/org/geotools/gui/swing/LoggingTableModel.java $
056:         * @version $Id: LoggingTableModel.java 20883 2006-08-07 13:48:09Z jgarnett $
057:         * @author Martin Desruisseaux
058:         */
059:        final class LoggingTableModel extends Handler implements  TableModel {
060:            /**
061:             * Resource keys for default column names. <STRONG>NOTE: Order is significant.</STRONG>
062:             * If the order is changed, then the constants in {@link LoggingPanel} must be updated.
063:             */
064:            private static final int[] COLUMN_NAMES = new int[] {
065:                    VocabularyKeys.LOGGER, VocabularyKeys.CLASS,
066:                    VocabularyKeys.METHOD, VocabularyKeys.TIME_OF_DAY,
067:                    VocabularyKeys.LEVEL, VocabularyKeys.MESSAGE };
068:
069:            /**
070:             * Resource keys for column names. This is usuall the same array than {@code COLUMN_NAMES}.
071:             * However, method {@link #setColumnVisible} may add or remove column in this list.
072:             */
073:            private int[] columnNames = COLUMN_NAMES;
074:
075:            /**
076:             * The last {@link LogRecord}s stored. This array will grows as needed up to
077:             * {@link #capacity}. Once the maximal capacity is reached, early records
078:             * are discarted.
079:             */
080:            private LogRecord[] records = new LogRecord[16];
081:
082:            /**
083:             * The maximum amount of records that can be stored in this logging panel.
084:             * If more than {@link #capacity} messages are logged, early messages will
085:             * be discarted.
086:             */
087:            private int capacity = 500;
088:
089:            /**
090:             * The total number of logging messages published by this panel. This number may be
091:             * greater than the amount of {@link LogRecord} actually memorized, since early records
092:             * may have been discarted. The slot in {@code records} where to write the next
093:             * message can be computed by <code>recordCount % capacity</code>.
094:             */
095:            private int recordCount;
096:
097:            /**
098:             * String representations of latest required records. Keys are {@link LogRecord} objects
099:             * and values are {@code String[]}. This is a cache for faster rendering.
100:             */
101:            private final Map cache = new LinkedHashMap() {
102:                protected boolean removeEldestEntry(final Map.Entry eldest) {
103:                    return size() >= Math.min(capacity, 80);
104:                }
105:            };
106:
107:            /**
108:             * The list of registered listeners.
109:             */
110:            private final EventListenerList listenerList = new EventListenerList();
111:
112:            /**
113:             * The format to use for formatting time.
114:             */
115:            private final DateFormat dateFormat = DateFormat
116:                    .getTimeInstance(DateFormat.MEDIUM);
117:
118:            /**
119:             * Construct the handler.
120:             */
121:            public LoggingTableModel() {
122:                setLevel(Level.CONFIG);
123:                setFormatter(new SimpleFormatter());
124:            }
125:
126:            /**
127:             * Returns the capacity. This is the maximum number of {@link LogRecord}s this handler
128:             * can memorize. If more messages are logged, then the oldiest messages will be discarted.
129:             */
130:            public int getCapacity() {
131:                return capacity;
132:            }
133:
134:            /**
135:             * Set the capacity. This is the maximum number of {@link LogRecord}s this handler can
136:             * memorize. If more messages are logged, then the oldiest messages will be discarted.
137:             */
138:            public synchronized void setCapacity(final int capacity) {
139:                if (recordCount != 0) {
140:                    throw new IllegalStateException("Not yet implemented.");
141:                }
142:                this .capacity = capacity;
143:            }
144:
145:            /**
146:             * Returns {@code true} if the given column is visible.
147:             *
148:             * @param index One of {@link LoggingPanel} constants, which maps to entries in
149:             *        {@link COLUMN_NAMES}. For example {@code 0} for the logger,
150:             *        {@code 1} for the class, etc.
151:             */
152:            final boolean isColumnVisible(int index) {
153:                final int key = COLUMN_NAMES[index];
154:                for (int i = 0; i < columnNames.length; i++) {
155:                    if (columnNames[i] == key) {
156:                        return true;
157:                    }
158:                }
159:                return false;
160:            }
161:
162:            /**
163:             * Show or hide the given column.
164:             *
165:             * @param index One of {@link LoggingPanel} constants, which maps to entries in
166:             *        {@link COLUMN_NAMES}. For example {@code 0} for the logger,
167:             *        {@code 1} for the class, etc.
168:             * @param visible The visible state for the specified column.
169:             */
170:            final void setColumnVisible(final int index, final boolean visible) {
171:                final int key = COLUMN_NAMES[index];
172:                int[] names = new int[COLUMN_NAMES.length];
173:                int count = 0;
174:                for (int i = 0; i < COLUMN_NAMES.length; i++) {
175:                    final int toTest = COLUMN_NAMES[i];
176:                    if (toTest == key) {
177:                        if (visible) {
178:                            names[count++] = toTest;
179:                        }
180:                        continue;
181:                    }
182:                    for (int j = 0; j < columnNames.length; j++) {
183:                        if (columnNames[j] == toTest) {
184:                            names[count++] = toTest;
185:                            break;
186:                        }
187:                    }
188:                }
189:                columnNames = names = XArray.resize(names, count);
190:                cache.clear();
191:                fireTableChanged(new TableModelEvent(this ,
192:                        TableModelEvent.HEADER_ROW));
193:                assert isColumnVisible(index) == visible : visible;
194:            }
195:
196:            /**
197:             * Publish a {@link LogRecord}. If the maximal capacity has been reached,
198:             * the oldiest record will be discarted.
199:             */
200:            public synchronized void publish(final LogRecord record) {
201:                if (!isLoggable(record)) {
202:                    return;
203:                }
204:                final int nextSlot = recordCount % capacity;
205:                if (nextSlot >= records.length) {
206:                    records = (LogRecord[]) XArray.resize(records, Math.min(
207:                            records.length * 2, capacity));
208:                }
209:                records[nextSlot] = record;
210:                final TableModelEvent event;
211:                if (++recordCount <= capacity) {
212:                    event = new TableModelEvent(this , nextSlot, nextSlot,
213:                            TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT);
214:                } else {
215:                    event = new TableModelEvent(this , 0, capacity - 1,
216:                            TableModelEvent.ALL_COLUMNS, TableModelEvent.UPDATE);
217:                }
218:                //
219:                // Notify all listeners that a record has been added.
220:                //
221:                EventQueue.invokeLater(new Runnable() {
222:                    public void run() {
223:                        fireTableChanged(event);
224:                    }
225:                });
226:            }
227:
228:            /**
229:             * Returns the log record for the specified row.
230:             *
231:             * @param row The row in the table. This is the visible row,
232:             *            not the record number from the first record.
233:             */
234:            public synchronized LogRecord getLogRecord(int row) {
235:                assert row < getRowCount();
236:                if (recordCount > capacity) {
237:                    row += (recordCount % capacity);
238:                    row %= capacity;
239:                }
240:                return records[row];
241:            }
242:
243:            /**
244:             * Returns the number of columns in the model.
245:             */
246:            public int getColumnCount() {
247:                return columnNames.length;
248:            }
249:
250:            /**
251:             * Returns the number of rows in the model.
252:             */
253:            public synchronized int getRowCount() {
254:                return Math.min(recordCount, capacity);
255:            }
256:
257:            /**
258:             * Returns the most specific superclass for all the cell values in the column.
259:             */
260:            public Class getColumnClass(final int columnIndex) {
261:                return String.class;
262:            }
263:
264:            /**
265:             * Returns the name of the column at {@code columnIndex}.
266:             */
267:            public String getColumnName(final int columnIndex) {
268:                return Vocabulary.format(columnNames[columnIndex]);
269:            }
270:
271:            /**
272:             * Returns the value for the cell at {@code columnIndex} and {@code rowIndex}.
273:             */
274:            public synchronized Object getValueAt(final int rowIndex,
275:                    final int columnIndex) {
276:                final LogRecord record = getLogRecord(rowIndex);
277:                String[] row = (String[]) cache.get(record);
278:                if (row == null) {
279:                    row = new String[getColumnCount()];
280:                    for (int i = 0; i < row.length; i++) {
281:                        final String value;
282:                        switch (columnNames[i]) {
283:                        case VocabularyKeys.LOGGER:
284:                            value = record.getLoggerName();
285:                            break;
286:                        case VocabularyKeys.CLASS:
287:                            value = getShortClassName(record
288:                                    .getSourceClassName());
289:                            break;
290:                        case VocabularyKeys.METHOD:
291:                            value = record.getSourceMethodName();
292:                            break;
293:                        case VocabularyKeys.TIME_OF_DAY:
294:                            value = dateFormat.format(new Date(record
295:                                    .getMillis()));
296:                            break;
297:                        case VocabularyKeys.LEVEL:
298:                            value = record.getLevel().getLocalizedName();
299:                            break;
300:                        case VocabularyKeys.MESSAGE:
301:                            value = getFormatter().formatMessage(record);
302:                            break;
303:                        default:
304:                            throw new AssertionError(i);
305:                        }
306:                        row[i] = value;
307:                    }
308:                    cache.put(record, row);
309:                    assert cache.size() <= capacity;
310:                }
311:                return row[columnIndex];
312:            }
313:
314:            /**
315:             * Returns the class name in a shorter form (without package).
316:             */
317:            private static String getShortClassName(String name) {
318:                if (name != null) {
319:                    final int dot = name.lastIndexOf('.');
320:                    if (dot >= 0) {
321:                        name = name.substring(dot + 1);
322:                    }
323:                    name = name.replace('$', '.');
324:                }
325:                return name;
326:            }
327:
328:            /**
329:             * Do nothing since cells are not editable.
330:             */
331:            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
332:            }
333:
334:            /**
335:             * Returns {@code false} since cells are not editable.
336:             */
337:            public boolean isCellEditable(int rowIndex, int columnIndex) {
338:                return false;
339:            }
340:
341:            /**
342:             * Adds a listener that is notified each time a change to the data model occurs.
343:             */
344:            public void addTableModelListener(final TableModelListener listener) {
345:                listenerList.add(TableModelListener.class, listener);
346:            }
347:
348:            /**
349:             * Removes a listener from the list that is notified each time a change occurs.
350:             */
351:            public void removeTableModelListener(
352:                    final TableModelListener listener) {
353:                listenerList.remove(TableModelListener.class, listener);
354:            }
355:
356:            /**
357:             * Forwards the given notification event to all {@link TableModelListeners}.
358:             */
359:            private void fireTableChanged(final TableModelEvent event) {
360:                final Object[] listeners = listenerList.getListenerList();
361:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
362:                    if (listeners[i] == TableModelListener.class) {
363:                        ((TableModelListener) listeners[i + 1])
364:                                .tableChanged(event);
365:                    }
366:                }
367:            }
368:
369:            /**
370:             * Flush any buffered output.
371:             */
372:            public void flush() {
373:            }
374:
375:            /**
376:             * Close the {@code Handler} and free all associated resources.
377:             */
378:            public void close() {
379:            }
380:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.