import javax.imageio.*;
import java.awt.image.*;
import java.awt.*;
import java.security.NoSuchAlgorithmException;
import java.security.MessageDigest;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
import javax.swing.text.*;
import javax.swing.*;
import java.util.concurrent.*;
import java.util.regex.*;
import java.util.List;
import java.util.zip.*;
import java.util.*;

public class main {
  static LogView logView;
  
  static class LogView extends JScrollPane {
  JTextArea textArea;

  LogView() {
    textArea = new JTextArea();
    textArea.setEditable(false);
    setViewportView(textArea);
  }

  // thread safe
  public void logText(final String text) {
    SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {

      textArea.append(text);

      // todo: scroll?
    } catch (Exception _e) {
  throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } }
});
  }
  
  // thread safe
  void print(String text) {
    logText(text);
  }

  // log some pure text and add a line feed
  // thread safe
  public void println(String line) {
    logText(line + "\n");
  }
  
  // thread safe
  public void clear() {
    SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
 textArea.setText(""); } catch (Exception _e) {
  throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } }
});
  }
} // LogView

  public static void main(String[] args) throws Exception {
    SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {

      JFrame frame = new JFrame("LogView Test");
    
      logView = new LogView();
      
      redirectStdOutAndErrTo(logView);

      //logView.println("Hello Agnes");
      //logView.println("Hello Julia");
  
      frame.add(logView);
      frame.setBounds(100, 100, 500, 400);
      print("Showing");
      frame.setVisible(true);
      exitOnFrameClose(frame);
      print("Done showing");
      
      logView.println("Hello Julia");
      print("yup");
    } catch (Exception _e) {
  throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } }
});
  }
  
  static void redirectStdOutAndErrTo(final LogView lg) {
    OutputStream outputStream = new OutputStream() {
      public void write(int b) {
        try {
          lg.print(new String(new byte[] {(byte) b}, "UTF-8")); // This is crap
        } catch (UnsupportedEncodingException e) {}
      }
      
      @Override
      public void write(byte[] b, int off, int len) {
        try {
          lg.print(new String(b, off, len, "UTF-8")); // This is crap
        } catch (UnsupportedEncodingException e) {}
      }
    };
    
    PrintStream ps = new PrintStream(outputStream, true);
    System.setOut(ps);
    System.setErr(ps);
  }

static void print() {
  System.out.println();
}

static void print(Object o) {
  System.out.println(o);
}

static void print(long i) {
  System.out.println(i);
}

  static void exitOnFrameClose(JFrame frame) {
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

}