Language Basics Java

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.EventListener;
import java.util.EventObject;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class ExceptionCatcherTester {
  public ExceptionCatcherTester() {
    JFrame f = new JFrame("Exception Catcher Tester");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    final JTextArea textArea = new JTextArea();
    textArea.setEditable(false);
    JButton button = new JButton("Alive");
    ActionListener buttonListener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        System.out.println("I'm Alive");
      }
    };
    button.addActionListener(buttonListener);
    final JTextField textField = new JTextField();
    ActionListener textFieldListener = new ActionListener() {
      public void actionPerformed(final ActionEvent e) {
        // Code to load URL contents in separate thread
        Runnable r = new Runnable() {
          public void run() {
            textField.setEditable(false);
            String urlString = e.getActionCommand();
            try {
              System.out.println("Loading " + urlString);
              textArea.setText("");
              URL url = new URL(urlString);
              InputStream is = url.openStream();
              InputStreamReader isr = new InputStreamReader(is);
              BufferedReader br = new BufferedReader(isr);
              StringWriter sw = new StringWriter();
              char buf[] = new char[1024];
              int count;
              while ((count = br.read(buf, 0, 1024)) != -1) {
                sw.write(buf, 0, count);
              }
              System.out.println("Done Loading");
              updateTextArea(textArea, sw.toString());
            } catch (IOException e) {
              throw new ThreadException(this, e);
            } finally {
              textField.setEditable(true);
            }
          }
        };
        ExceptionCatcherThread runner = new ExceptionCatcherThread(r);
        // Listener in case of exception
        ThreadListener threadListener = new ThreadListener() {
          public void exceptionHappened(ThreadException e) {
            Throwable t = e.getSourceException();
            final String message = t.getClass().getName() + ": "
                + t.getMessage();
            Runnable r = new Runnable() {
              public void run() {
                JOptionPane.showMessageDialog(null, message);
              }
            };
            SwingUtilities.invokeLater(r);
          }
        };
        runner.addThreadExceptionListener(threadListener);
        runner.start();
      }
    };
    textField.addActionListener(textFieldListener);
    Container c = f.getContentPane();
    c.add(textField, BorderLayout.NORTH);
    JScrollPane pane = new JScrollPane(textArea);
    c.add(pane, BorderLayout.CENTER);
    c.add(button, BorderLayout.SOUTH);
    f.setSize(300, 300);
    f.show();
  }
  public void updateTextArea(final JTextArea ta, final String text) {
    // Because file loading happening not blocking event thread
    // We have to set text area in event thread
    Runnable r = new Runnable() {
      public void run() {
        ta.setText(text);
        ta.setCaretPosition(0);
      }
    };
    SwingUtilities.invokeLater(r);
  }
  public static void main(String args[]) {
    new ExceptionCatcherTester();
  }
}
class ExceptionCatcherThread extends ThreadGroup {
  private Runnable runnable;
  private Thread runner;
  private Vector listenerList = new Vector(3);
  /* For autonumbering our group. */
  private static int threadInitNumber;
  private static synchronized int nextThreadNum() {
    return threadInitNumber++;
  }
  public ExceptionCatcherThread(Runnable r) {
    super("ExceptionCatcherThread-" + nextThreadNum());
    runnable = r;
    // Create thread in this group
    runner = new Thread(this, runnable);
  }
  public void start() {
    runner.start();
  }
  /* Listener registration methods */
  public synchronized void addThreadExceptionListener(ThreadListener t) {
    listenerList.add(t);
  }
  public synchronized void removeThreadExceptionListener(ThreadListener t) {
    listenerList.remove(t);
  }
  public void uncaughtException(Thread source, Throwable t) {
    fireExceptionHappened(t);
    super.uncaughtException(source, t);
  }
  protected void fireExceptionHappened(Throwable t) {
    ThreadException e = (t instanceof ThreadException) ? (ThreadException) t
        : new ThreadException(runnable, t);
    Vector l;
    synchronized (this) {
      l = (Vector) listenerList.clone();
    }
    for (int i = 0, n = listenerList.size(); i < n; i++) {
      ThreadListener tl = (ThreadListener) l.get(i);
      tl.exceptionHappened(e);
    }
  }
}
class ThreadException extends RuntimeException {
  Runnable runnable;
  Throwable exception;
  public ThreadException(Runnable r, Throwable t) {
    runnable = r;
    exception = t;
  }
  public ThreadException(Runnable r, Throwable t, String message) {
    super(message);
    runnable = r;
    exception = t;
  }
  public Runnable getRunnable() {
    return runnable;
  }
  public Throwable getSourceException() {
    return exception;
  }
}
class ThreadExceptionEvent extends EventObject {
  public ThreadExceptionEvent(ThreadException source) {
    super(source);
  }
  public Runnable getRunnable() {
    ThreadException source = (ThreadException) getSource();
    return (Runnable) source.getRunnable();
  }
}
interface ThreadListener extends EventListener {
  public void exceptionHappened(ThreadException e);
}