package com.robonobo.gui.frames;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
import com.robonobo.common.concurrent.CatchingRunnable;
import com.robonobo.core.Platform;
/**
* Writes everything from the log4j root logger into a swing frame
* @author macavity
*
*/
public class Log4jMonitorFrame extends JFrame {
int idealTextSize = 32768;
JTextArea textArea;
TextAreaAppender appender;
public Log4jMonitorFrame(RobonoboFrame frame) {
setTitle("robonobo log");
setIconImage(RobonoboFrame.getRobonoboIconImage());
if(Platform.getPlatform().shouldSetMenuBarOnDialogs())
setJMenuBar(Platform.getPlatform().getMenuBar(frame));
appender = new TextAreaAppender();
PatternLayout logLayout = new PatternLayout();
logLayout.setConversionPattern("%d{HH:mm:ss:SSS} [%-5p] %-16t : %m (%C)%n");
appender.setLayout(logLayout);
Logger.getRootLogger().addAppender(appender);
textArea = new JTextArea();
textArea.setEditable(false);
textArea.setRows(20);
textArea.setColumns(150);
textArea.setFont(new Font("Monospaced", 0, 12));
getContentPane().add(new JScrollPane(textArea), BorderLayout.CENTER);
pack();
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
Logger.getRootLogger().removeAppender(appender);
}
});
}
class TextAreaAppender extends AppenderSkeleton {
@Override
protected void append(LoggingEvent e) {
final String msg = layout.format(e);
SwingUtilities.invokeLater(new CatchingRunnable() {
public void doRun() throws Exception {
textArea.append(msg);
// Make sure the last line is always visible
textArea.setCaretPosition(textArea.getDocument().getLength());
int maxExcess = idealTextSize / 2;
int excess = textArea.getDocument().getLength() - idealTextSize;
if (excess >= maxExcess)
textArea.replaceRange("", 0, excess);
}
});
}
@Override
public void close() {
}
@Override
public boolean requiresLayout() {
return true;
}
}
public int getIdealTextSize() {
return idealTextSize;
}
public void setIdealTextSize(int maxTextSize) {
this.idealTextSize = maxTextSize;
}
}