001 /****************************************************************************** 002 * Copyright (C) MActor Developers. All rights reserved. * 003 * ---------------------------------------------------------------------------* 004 * This file is part of MActor. * 005 * * 006 * MActor is free software; you can redistribute it and/or modify * 007 * it under the terms of the GNU General Public License as published by * 008 * the Free Software Foundation; either version 2 of the License, or * 009 * (at your option) any later version. * 010 * * 011 * MActor is distributed in the hope that it will be useful, * 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 014 * GNU General Public License for more details. * 015 * * 016 * You should have received a copy of the GNU General Public License * 017 * along with MActor; if not, write to the Free Software * 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * 019 ******************************************************************************/ 020 package org.mactor.ui.gui; 021 022 import java.awt.BorderLayout; 023 import java.awt.Component; 024 import java.awt.Dimension; 025 import java.util.ArrayList; 026 import java.util.Calendar; 027 028 import javax.swing.Icon; 029 import javax.swing.JPanel; 030 import javax.swing.JScrollPane; 031 import javax.swing.JTable; 032 import javax.swing.ListSelectionModel; 033 import javax.swing.SwingUtilities; 034 import javax.swing.table.AbstractTableModel; 035 import javax.swing.table.DefaultTableCellRenderer; 036 037 import org.apache.log4j.Appender; 038 import org.apache.log4j.AppenderSkeleton; 039 import org.apache.log4j.Level; 040 import org.apache.log4j.LogManager; 041 import org.apache.log4j.spi.LoggingEvent; 042 import org.mactor.brokers.MessageBrokerManager.MessageInfo; 043 import org.mactor.brokers.MessageBrokerManager.MessageInfoListener; 044 import org.mactor.framework.MactorException; 045 046 public class EventLogPanel extends JPanel { 047 private JTable table; 048 EventHistoryTableModel model = new EventHistoryTableModel(); 049 public EventLogPanel() throws MactorException { 050 super(new BorderLayout()); 051 LogManager.getLogger("org.mactor").addAppender(a); 052 LogManager.getLogger("MactorIncomingMessage").addAppender(new MessageLogAppender(INCOMING_ICON)); 053 LogManager.getLogger("MactorIncomingResponse").addAppender(new MessageLogAppender(INCOMING_RESP_ICON)); 054 LogManager.getLogger("MactorOutgingMessage").addAppender(new MessageLogAppender(OUTGOING_ICON)); 055 LogManager.getLogger("MactorOutgingResponse").addAppender(new MessageLogAppender(OUTGOING_RESP_ICON)); 056 table = new JTable(model); 057 table.getColumnModel().getColumn(0).setCellRenderer(new MessageTableCellRendere()); 058 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 059 // summaryTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 060 table.getColumnModel().getColumn(0).setMaxWidth(25); 061 table.getColumnModel().getColumn(1).setMaxWidth(200); 062 JScrollPane tableSp = new JScrollPane(table); 063 tableSp.setPreferredSize(new Dimension(100, 100)); 064 add(tableSp, BorderLayout.CENTER); 065 } 066 MessageInfoListener miListener = new MessageInfoListener() { 067 public void onMessageInfo(final MessageInfo messageInfo) { 068 final Event event = new Event(); 069 event.message = messageInfo.getChannel() + (messageInfo.isResponse() ? " (response)" : "") + " : " + messageInfo.getArchivePath(); 070 event.time = GuiUtil.format(messageInfo.getCreatedTime()); 071 if (messageInfo.isIncoming()) { 072 if (messageInfo.isResponse()) 073 event.icon = INCOMING_RESP_ICON; 074 else 075 event.icon = INCOMING_ICON; 076 } else if (messageInfo.isResponse()) 077 event.icon = OUTGOING_RESP_ICON; 078 else 079 event.icon = OUTGOING_ICON; 080 SwingUtilities.invokeLater(new Runnable() { 081 public void run() { 082 model.addEvent(event); 083 } 084 }); 085 }; 086 }; 087 private class MessageLogAppender extends AppenderSkeleton { 088 Icon icon; 089 MessageLogAppender(Icon icon) { 090 this.icon = icon; 091 } 092 @Override 093 protected void append(LoggingEvent logEvent) { 094 if (!logEvent.getLevel().isGreaterOrEqual(Level.INFO)) 095 return; 096 final Event event = new Event(); 097 event.message = logEvent.getMessage() + ""; 098 Calendar t = Calendar.getInstance(); 099 t.setTimeInMillis(logEvent.timeStamp); 100 event.time = GuiUtil.format(t); 101 event.icon = icon; 102 SwingUtilities.invokeLater(new Runnable() { 103 public void run() { 104 model.addEvent(event); 105 } 106 }); 107 } 108 @Override 109 public void close() { 110 } 111 @Override 112 public boolean requiresLayout() { 113 return false; 114 } 115 } 116 Appender a = new AppenderSkeleton() { 117 @Override 118 protected void append(LoggingEvent logEvent) { 119 if (!logEvent.getLevel().isGreaterOrEqual(Level.INFO)) 120 return; 121 final Event event = new Event(); 122 event.message = logEvent.getLocationInformation().getClassName() + " : " + logEvent.getMessage(); 123 Calendar t = Calendar.getInstance(); 124 t.setTimeInMillis(logEvent.getStartTime()); 125 event.time = GuiUtil.format(t); 126 if (Level.INFO.equals(logEvent.getLevel())) 127 event.icon = INFO_ICON; 128 else if (Level.WARN.equals(logEvent.getLevel())) 129 event.icon = WARN_ICON; 130 else if (Level.ERROR.equals(logEvent.getLevel())) 131 event.icon = ERROR_ICON; 132 SwingUtilities.invokeLater(new Runnable() { 133 public void run() { 134 model.addEvent(event); 135 } 136 }); 137 } 138 @Override 139 public void close() { 140 } 141 @Override 142 public boolean requiresLayout() { 143 return false; 144 } 145 }; 146 public void stop() throws MactorException { 147 // MessageBrokerManager.getInstance().removeMessageInfoListener(channel, 148 // miListener); 149 } 150 private static final Icon ERROR_ICON = GuiUtil.loadIcon("/error_16.PNG"); 151 private static final Icon INFO_ICON = GuiUtil.loadIcon("/info_16.PNG"); 152 private static final Icon WARN_ICON = GuiUtil.loadIcon("/warning_16.PNG"); 153 private static final Icon INCOMING_ICON = GuiUtil.loadIcon("/incoming_16.PNG"); 154 private static final Icon INCOMING_RESP_ICON = GuiUtil.loadIcon("/incoming_resp_16.PNG"); 155 private static final Icon OUTGOING_ICON = GuiUtil.loadIcon("/outgoing_16.PNG"); 156 private static final Icon OUTGOING_RESP_ICON = GuiUtil.loadIcon("/outgoing_resp_16.PNG"); 157 private class Event { 158 Icon icon; 159 String time; 160 String message; 161 public Event() { 162 } 163 public Event(Icon icon, String time, String message) { 164 super(); 165 this.icon = icon; 166 this.time = time; 167 this.message = message; 168 } 169 } 170 static final int MAX = 2000; 171 static final int HYST = 500; 172 private static class EventHistoryTableModel extends AbstractTableModel { 173 ArrayList<Event> history = new ArrayList<Event>(); 174 String[] colums = new String[] { "", "Timestamp", "Message" }; 175 @Override 176 public String getColumnName(int col) { 177 return colums[col]; 178 } 179 public void addEvent(Event event) { 180 this.history.add(event); 181 adjust(); 182 super.fireTableDataChanged(); 183 } 184 final private void adjust() { 185 if (this.history.size() > MAX) 186 this.history = new ArrayList<Event>(this.history.subList((history.size() - MAX) + HYST, history.size() - 1)); 187 } 188 public int getColumnCount() { 189 return colums.length; 190 } 191 public int getRowCount() { 192 if (history == null) 193 return 0; 194 return history.size(); 195 } 196 public Object getValueAt(int row, int col) { 197 if (history == null) 198 return null; 199 Event event = history.get(history.size() - 1 - row); 200 if (col == 0) 201 return event.icon; 202 if (col == 1) 203 return event.time; 204 if (col == 2) 205 return event.message; 206 throw new RuntimeException("Invalid column '" + col + "'"); 207 } 208 } 209 public class MessageTableCellRendere extends DefaultTableCellRenderer { 210 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 211 if (value instanceof Icon) 212 setIcon((Icon) value); 213 else 214 setIcon(null); 215 setText(null); 216 return this; 217 } 218 } 219 }