c203664b93ca5df594007505c641b49984addd4c
[jSite2.git] / src / net / pterodactylus / jsite / gui / LogWindow.java
1 /*
2  * jSite2 - LoggingWindow.java -
3  * Copyright © 2008 David Roden
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 package net.pterodactylus.jsite.gui;
21
22 import java.awt.BorderLayout;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.logging.Level;
30 import java.util.logging.LogRecord;
31 import java.util.logging.Logger;
32
33 import javax.swing.BorderFactory;
34 import javax.swing.JComboBox;
35 import javax.swing.JFrame;
36 import javax.swing.JPanel;
37 import javax.swing.JScrollPane;
38 import javax.swing.JTable;
39 import javax.swing.ScrollPaneConstants;
40 import javax.swing.table.AbstractTableModel;
41 import javax.swing.table.DefaultTableColumnModel;
42 import javax.swing.table.JTableHeader;
43 import javax.swing.table.TableColumn;
44
45 import net.pterodactylus.jsite.i18n.I18n;
46 import net.pterodactylus.jsite.i18n.gui.I18nLabel;
47 import net.pterodactylus.jsite.main.Version;
48 import net.pterodactylus.util.logging.Logging;
49 import net.pterodactylus.util.logging.LoggingListener;
50 import net.pterodactylus.util.swing.SwingUtils;
51
52 /**
53  * Frame that shows log messages as they occur.
54  * 
55  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
56  * @version $Id$
57  */
58 public class LogWindow extends JFrame implements LoggingListener, ActionListener {
59
60         /** The logger. */
61         private static final Logger logger = Logging.getLogger(LogWindow.class.getName());
62
63         /** The “log level” label. */
64         private I18nLabel logLevelLabel;
65
66         /** The “log level” combo box. */
67         private JComboBox logLevelComboBox;
68
69         /** The log table. */
70         private JTable logTable;
71
72         /** The table model for the log table. */
73         private LogRecordTableModel logTableModel;
74
75         /**
76          * Creates a new log window.
77          */
78         public LogWindow() {
79                 super(I18n.get("logWindow.title") + " – jSite " + Version.getVersion());
80                 initActions();
81                 initComponents();
82                 pack();
83                 SwingUtils.center(this);
84         }
85
86         //
87         // PRIVATE METHODS
88         //
89
90         /**
91          * Initializes all actions used in this window.
92          */
93         private void initActions() {
94                 /* TODO */
95         }
96
97         /**
98          * Initializes all components in this window.
99          */
100         private void initComponents() {
101                 JPanel contentPane = new JPanel(new BorderLayout(12, 12));
102                 contentPane.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
103
104                 JPanel logLevelPanel = new JPanel(new BorderLayout(12, 12));
105                 contentPane.add(logLevelPanel, BorderLayout.PAGE_START);
106
107                 logLevelComboBox = new JComboBox(new Object[] { Level.ALL, Level.FINEST, Level.FINER, Level.FINE, Level.INFO, Level.WARNING, Level.SEVERE });
108                 logLevelPanel.add(logLevelComboBox, BorderLayout.CENTER);
109                 logLevelComboBox.addActionListener(this);
110
111                 logLevelLabel = new I18nLabel("logWindow.label.logLevel", logLevelComboBox);
112                 logLevelPanel.add(logLevelLabel, BorderLayout.LINE_START);
113
114                 DefaultTableColumnModel logTableColumnModel = new DefaultTableColumnModel();
115                 logTableColumnModel.addColumn(new TableColumn(0));
116                 logTableColumnModel.addColumn(new TableColumn(1));
117                 logTableColumnModel.addColumn(new TableColumn(2));
118                 logTableModel = new LogRecordTableModel();
119                 logTable = new JTable(logTableModel);
120                 logTable.setTableHeader(new JTableHeader(logTableColumnModel));
121                 logTable.setColumnModel(logTableColumnModel);
122                 JScrollPane scrollPane = new JScrollPane(logTable);
123                 scrollPane.setCorner(ScrollPaneConstants.UPPER_LEADING_CORNER, logTable.getTableHeader());
124                 contentPane.add(scrollPane, BorderLayout.CENTER);
125
126                 setContentPane(contentPane);
127         }
128
129         //
130         // INTERFACE LoggingListener
131         //
132
133         /**
134          * {@inheritDoc}
135          */
136         public void logged(LogRecord logRecord) {
137                 logTableModel.addLogRecord(logRecord);
138         }
139
140         //
141         // INTERFACE ActionListener
142         //
143
144         /**
145          * {@inheritDoc}
146          */
147         public void actionPerformed(ActionEvent actionEvent) {
148                 if (actionEvent.getSource() == logLevelComboBox) {
149                         Level newLevel = (Level) logLevelComboBox.getSelectedItem();
150                         logger.log(Level.INFO, "setting new log level to “" + newLevel.getName() + "”…");
151                 }
152         }
153
154         /**
155          * Table model for the log message table.
156          * 
157          * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
158          * @version $Id$
159          */
160         private class LogRecordTableModel extends AbstractTableModel {
161
162                 /** The column names. */
163                 private final String[] COLUMN_NAMES = new String[] { I18n.get("logWindow.table.column.time.name"), I18n.get("logWindow.table.column.level.name"), I18n.get("logWindow.table.column.message.name") };
164
165                 /** The column classes. */
166                 private final Class<?>[] COLUMN_CLASSES = new Class<?>[] { Date.class, Level.class, String.class };
167
168                 /** The log records. */
169                 private List<LogRecord> logRecords = Collections.synchronizedList(new ArrayList<LogRecord>());
170
171                 /**
172                  * Empty constructor.
173                  */
174                 LogRecordTableModel() {
175                         /* do nothing. */
176                 }
177
178                 /**
179                  * Adds a log record.
180                  * 
181                  * @param logRecord
182                  *            The log record to add
183                  */
184                 @SuppressWarnings("synthetic-access")
185                 public synchronized void addLogRecord(LogRecord logRecord) {
186                         logRecords.add(logRecord);
187                         fireTableRowsInserted(logRecords.size() - 1, logRecords.size() - 1);
188                 }
189
190                 /**
191                  * {@inheritDoc}
192                  */
193                 public int getColumnCount() {
194                         return 3;
195                 }
196
197                 /**
198                  * {@inheritDoc}
199                  */
200                 @Override
201                 public String getColumnName(int column) {
202                         return COLUMN_NAMES[column];
203                 }
204
205                 /**
206                  * {@inheritDoc}
207                  */
208                 @Override
209                 public Class<?> getColumnClass(int columnIndex) {
210                         return COLUMN_CLASSES[columnIndex];
211                 }
212
213                 /**
214                  * {@inheritDoc}
215                  */
216                 public int getRowCount() {
217                         return logRecords.size();
218                 }
219
220                 /**
221                  * {@inheritDoc}
222                  */
223                 public Object getValueAt(int rowIndex, int columnIndex) {
224                         if (rowIndex >= logRecords.size()) {
225                                 return null;
226                         }
227                         LogRecord logRecord = logRecords.get(rowIndex);
228                         switch (columnIndex) {
229                         case 0:
230                                 return logRecord.getMillis();
231                         case 1:
232                                 return logRecord.getLevel();
233                         case 2:
234                                 return logRecord.getMessage();
235                         }
236                         return null;
237                 }
238
239         }
240
241 }