package org.ripple.power.ui.view.log;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.ripple.power.config.LSystem;
import org.ripple.power.ui.UIConfig;
import org.ripple.power.ui.UIRes;
import org.ripple.power.ui.graphics.LColor;
public class LogView {
private static final int MAX_LINE = 2048;
private static LogView instance;
private JFrame frame;
private JTextArea textArea;
private JScrollPane scrollPane;
private JViewport viewpoint;
private int lastScrollHeight = -1;
private int lastViewHeight = -1;
private boolean changedFlg = false;
private boolean close = false;
private StringBuffer buffer = new StringBuffer();
private LogAppender logAppender;
public static LogView get() {
if (instance == null) {
instance = new LogView();
}
return instance;
}
public LogView() {
this(LSystem.applicationName + " Log View", 640, 480);
}
public LogView(String title) {
this(title, 640, 480);
}
public LogView(String title, int width, int height) {
frame = new JFrame(title);
if (width != -1 && height != -1) {
Dimension dim = new Dimension(width, height);
frame.setPreferredSize(dim);
frame.setSize(dim);
}
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
closed();
}
@Override
public void windowClosed(WindowEvent e) {
closed();
}
@Override
public void windowActivated(WindowEvent e) {
}
});
frame.setIconImage(UIRes.getIcon());
frame.pack();
frame.setLocationRelativeTo(LSystem.applicationMain);
Font font = UIRes.getFont();
textArea = new JTextArea();
textArea.setFont(font);
textArea.setEditable(false);
textArea.setBackground(UIConfig.dialogbackground);
textArea.setForeground(LColor.white);
scrollPane = new JScrollPane(textArea);
viewpoint = scrollPane.getViewport();
{
viewpoint.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent arg0) {
Rectangle rect = viewpoint.getViewRect();
if (lastScrollHeight == textArea.getHeight()
&& lastViewHeight == rect.height
&& changedFlg == false) {
return;
}
if (lastScrollHeight - lastViewHeight == rect.y) {
rect.setLocation(rect.x, textArea.getHeight()
- rect.height);
textArea.scrollRectToVisible(rect);
}
lastScrollHeight = textArea.getHeight();
lastViewHeight = rect.height;
changedFlg = false;
}
});
}
frame.add(scrollPane);
(logAppender = new LogAppender()).start();
}
public void show() {
if (!frame.isVisible()) {
frame.setVisible(true);
frame.setState(JFrame.NORMAL);
}
this.close = false;
if (logAppender == null) {
(logAppender = new LogAppender()).start();
}
}
public void hide() {
if (frame.isVisible()) {
frame.setVisible(false);
}
}
public void closed() {
this.close = true;
if (logAppender != null) {
logAppender.interrupt();
logAppender = null;
}
this.hide();
}
public Rectangle getBounds() {
return frame.getBounds();
}
public void setBounds(Rectangle r) {
frame.setBounds(r);
}
public void append(String str) {
synchronized (buffer) {
buffer.append(str);
buffer.notify();
}
}
public void append(byte[] b) {
synchronized (buffer) {
buffer.append(b);
buffer.notify();
}
}
public void append(byte[] b, int off, int len) {
append(new String(b, off, len));
}
public void append(int b) {
synchronized (buffer) {
buffer.append(b);
buffer.notify();
}
}
private class LogAppender extends Thread {
public void run() {
for (; !close;) {
synchronized (buffer) {
try {
buffer.wait();
} catch (InterruptedException e) {
}
textArea.append(buffer.toString());
buffer.delete(0, buffer.length());
}
if (textArea.getLineCount() > MAX_LINE) {
try {
int offset = textArea.getLineEndOffset(textArea
.getLineCount() - MAX_LINE - 1);
textArea.getDocument().remove(0, offset);
} catch (Exception exc) {
ErrorLog.get().logException("LogView Appender", exc);
}
}
changedFlg = true;
}
}
}
public static void main(String[] args) {
final Logger log = new Logger("test");
Thread thread = new Thread() {
public void run() {
for (;;) {
log.debug("ffffffffffffffffffffffff");
}
}
};
thread.start();
}
}