プログレスバーの類い(プログレスダイアログでも何でもいいんだけど、とにかくある動作の進行状況を通知する機能)って、どうやって実現するんだっけ?
プログラミング言語とそのフレームワークごとに違うはずで、ここでは、JavaとSwingについて。ちょっと調べてみればすぐわかるし、本(Swing Tipsなど)を見れば一発なんだけど、課題としてあげておく。
とくに、メインフレーム(あるいはダイアログ)内に埋め込まれたウィジェットでそれを表現するには、どうしたらいいんだっけ?

以下は、課題のサンプルプログラム。結構めんどくさい。DeveloperWorksの「Merlinの魔術: 不確定プログレス・バー」によるプログレスバーのサンプル。(ちょっと変更、inner class, anonymous classなどをやめた。)
まず、プログレスバーを動かすスレッド。動かすプログレスバーをコンストラクタでもらっている。

class ProgressRunner implements Runnable {
  private JProgressBar progressBar;

  ProgressRunner(JProgressBar pbar) {
    progressBar = pbar;
  }

  public void run() {
    int value = progressBar.getValue();
    progressBar.setValue(value+1);
  }
}

次は、プログレスバーで進行状況を表示したいタスクスレッド。実際には、500ms待ちながらカウンターを増やしていって、カウンターが最大値になったら、スレッドは、終了する。プログレスバーを動かすスレッドをあらかじめ用意しておき、run()内で、カウンターを増やすたびに、プログレスバーを動かすスレッドを引数に指定して、SwingUtilities.invokeAndWait()を呼ぶところがミソらしい。そのために、コンストラクタでプログレスバーをこのクラスの利用側からもらっている。

class BarThread extends Thread {
  private static int DELAY = 500;
  JProgressBar progressBar;

  public BarThread(JProgressBar bar) {
    progressBar = bar;
  }

  public void run() {
    int minimum = progressBar.getMinimum();
    int maximum = progressBar.getMaximum();
    ProgressRunner runner = new ProgressRunner(progressBar);
    for (int i=minimum; i<maximum; i++) {
      try {
        SwingUtilities.invokeAndWait(runner);
        // Our task for each step is to just sleep
        Thread.sleep(DELAY);
      } catch (InterruptedException ignoredException) {
      } catch (InvocationTargetException ignoredException) {
      }
    }
  }
}

あとは、タスクスレッドを開始するボタンのActionListenerとGUI本体。
ボタンが押されたら、ボタンをdisableにして、タスクスレッドを作って、開始する。
GUI本体は、プログレスバーとボタンを作って、JFrameに配置している。

class ButtonActionListener implements ActionListener {
  private JButton aJButton;
  private JProgressBar aJProgressBar;

  ButtonActionListener(JButton btn, JProgressBar pbar) {
    aJButton = btn;
    aJProgressBar = pbar;
  }

  public void actionPerformed(ActionEvent e) {
    aJButton.setEnabled(false);
    Thread stepper = new BarThread(aJProgressBar);
    stepper.start();
  }
}

public class ProgressSample {
  public static void main(String args[]) {
    // Initialize
    final JProgressBar aJProgressBar = new JProgressBar(0, 100);
    final JButton aJButton = new JButton("Start");
    aJButton.addActionListener(new ButtonActionListener(aJButton, aJProgressBar));
    JFrame theFrame = new JFrame("Progress Bars");
    theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container contentPane = theFrame.getContentPane();
    contentPane.add(aJProgressBar, BorderLayout.NORTH);
    contentPane.add(aJButton, BorderLayout.SOUTH);
    theFrame.setSize(300, 100);
    theFrame.setVisible(true);
  }
}