Additional Source Code is Available ~zip file

Listing 1

package example;

import java.lang.reflect.*;
import java.util.concurrent.*;
import java.awt.*;

public final class SwingProxy {

  private static class TargetInvoker implements Runnable {

    private Object target;
    private Object returnValue;
    private Throwable exception;
    private Method method;
    private Object[] arguments;

    public TargetInvoker(Object target, Method method,
       Object[] arguments) {
      this.target = target;
      this.method = method;
      this.arguments = arguments;
    }

    public boolean threwException() {
      return exception != null;
    }

    public Throwable getException() {
      return exception;
    }

    public Object getReturnValue() {
      return returnValue;
    }

    public void run() {
      try {
        returnValue = method.invoke(target, arguments);
      } catch(Throwable t) {
        exception = t;
      }
    }
  }
  
  private static class CallHandler implements InvocationHandler {
   
    private static final ExecutorService threadPool 
        = Executors.newCachedThreadPool();
    private Class targetClass;
    private Object target;
    
    public CallHandler(Object target) {
      this.target = target;
      this.targetClass = target.getClass();
    }
    
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
      
      Method targetMethod = targetClass.getMethod(
            method.getName(), method.getParameterTypes());
      TargetInvoker targetInvoker = new TargetInvoker(
          target, targetMethod, args);
      if (EventQueue.isDispatchThread()) {
        threadPool.execute(targetInvoker);
      } else if (method.getReturnType() == void.class) {
        EventQueue.invokeLater(targetInvoker);
      } else {
        EventQueue.invokeAndWait(targetInvoker);
        if (targetInvoker.threwException()) {
          throw targetInvoker.getException();
        } else {
          return targetInvoker.getReturnValue();
        }
      }
      
      return null;
    }
  }
  
  private SwingProxy() {
  }
  
  public static Object newSwingProxy(Object target) {
    return Proxy.newProxyInstance(
        SwingProxy.class.getClassLoader(),
        target.getClass().getInterfaces(),
        new CallHandler(target));
  }
}


Listing 2

package example;

public class Mediator implements IProgressDialogMediator,
    IDivisionFrameMediator, IDivisionListener {
  
  private IDivider divider;
  private IDivisionFrame divisionFrame;
  private IProgressDialog progressDialog;
  private Thread divideThread;
  
  public void setDivider(IDivider divider) {
    this.divider = divider;
  }
  
  public void setDivisionFrame(IDivisionFrame divisionFrame) {
    this.divisionFrame = divisionFrame;
  }
  
  public void setProgressDialog(IProgressDialog progressMonitor) {
    this.progressDialog = progressMonitor;
  }
  
  public void divide(String dividendStr, String divisorStr) {
    DivisionFrameParser dividendParser 
        = new DivisionFrameParser(dividendStr);
    DivisionFrameParser divisorParser 
        = new DivisionFrameParser(divisorStr);
    divisionFrame.showDivisionResult("");
    divisionFrame.showValid(dividendParser.isFieldValid(), 
        divisorParser.isFieldValid());

    if (dividendParser.isFieldValid() 
        && divisorParser.isFieldValid()) {
      try {
        progressDialog.start();
        synchronized(this) {
          divideThread = Thread.currentThread();
        }
        DivisionResult divisionResult = divider.divide(
            dividendParser.getField(), 
            divisorParser.getField(), this);
        synchronized(this) {
          divideThread = null;
        }
        if (divisionResult == null) {
          divisionFrame.showDivisionResult("[Cancelled]");
        } else {
          divisionFrame.showDivisionResult(
            divisionResult.getQuotient() 
				+ " R " + divisionResult.getRemainder());
        }
      } catch(ArithmeticException e) {
        divisionFrame.showDivisionResult("NaN");
      } finally {
        progressDialog.end();
      }
    }
  }
  
  public synchronized void requestCancel() {
    if (divideThread != null) {
      divideThread.interrupt();
    }
  }
  
  public void computationPerformed(int percentage) {
    progressDialog.setProgress("Computing...", percentage);
  }
}

Additional Source Code is Available ~zip file