Swing と Windows Form と SWT

太一

2008/11/21

たいち(id:taichitaichi)について

  • プログラマ
  • eclipse pluginとjavascriptに時間を使ってる感じ
  • いたづら大好き(id:warufuzaketaichi)
  • 今は、カルドセプト(4511-3526-0665)。
    • みんなカルドセプトを買うべき。

本日のテクノロジ

  • Swing
  • .NETにおけるWindowsForm
  • The Standard Widget Toolkit(SWT)

比較項目

何か気付いたら、70人とか応募が来ちゃってて、どうしようかなーと。
直感的に理解し易い話と、分り辛いけど、必要な話を用意しました。

  • UIデザイナ
  • UIスレッドとワーカースレッドのディスパッチ
  • 以下ボツネタ。

UIデザイナの話 (1)

まずは、使用するツール

UIデザイナの話 NetBeans (1)

NetBeansの全景

UIデザイナの話 NetBeans (2)

コンポーネントレイアウト部分

UIデザイナの話 NetBeans (3)

プロパティ部分

UIデザイナの話 VisualStudio (1)

VisualStudioの全景

UIデザイナの話 VisualStudio (2)

コンポーネントレイアウト部分

UIデザイナの話 VisualStudio (3)

プロパティ部分

UIデザイナの話 Eclipse (1)

Eclipseの全景

UIデザイナの話 Eclipse (2)

コンポーネントレイアウト部分

UIデザイナの話 Eclipse (3)

プロパティ部分

UIデザイナの話 まとめ

  • NetBeansとVisualStudioにUIデザイナの機能面で、殆ど差は見られない
  • 但し、NetBeansで画面数が増えた時の挙動は、検証していないので要注意
  • 明らかにeclipseのVisualEditorが一人負け
  • 配布の仕組みである、JavaWebStartもチェックしてね

UIスレッドとワーカースレッドのディスパッチ

スタート、ストップ、その他の3つのボタン及び、
プログレスバーのあるUIを実装する事で、
プログラミングモデルの違いを明らかにします。

まずは、それぞれが完成した状態のUI

swing
SWT
WindowsForm

Swingの場合 (1)

Swing版を実装するに当って、
Swing Application Framework(SAF)を使用しています。

SAFでは、@Actionを使ってメソッドを
ApplicationContextのActionMapに登録し、
それをコンポーネント作成時に取り出して、
AbstractButton#setActionに引き渡す事で、
イベントと紐付ける事が出来ます。

イベントを処理するメソッドでは、
SwingWorkerを継承したTaskオブジェクトを返す事で、
処理内容を非同期化する事が可能になります。

この説明は、正直眠い!

Swingの場合 (2)

という訳でコードの抜粋

ActionMap actionMap = Application.getInstance(
   desktopapplication1.DesktopApplication1.class)
  .getContext()
  .getActionMap(DesktopApplication1View.class, this);
jButton1.setAction(actionMap.get("startProgress"));
〜〜〜
@Action(block = Task.BlockingScope.ACTION)
public Task startProgress() {
  switchButton(false);
  this.progressTask = new StartProgressTask(getApplication());
  return this.progressTask;
}

Swingの場合 (3)

Taskの中

private class StartProgressTask extends 
    org.jdesktop.application.Task {
    StartProgressTask(org.jdesktop.application.Application app) {
      super(app);
    }
    @Override
    protected Object doInBackground() {
        for (int i = 0; i < 100 && isCancelled() == false; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {}
            setProgress(i);
        }
        return null;
    }
    @Override
    protected void succeeded(Object result) {
    }
}

Swingの場合 (4)

まとめて全部

WindowsFormの場合 (1)

WindowsFormでは、BackgroundWorkerと言うAPIを使います。

このAPIを使うのは非常に簡単で、
以下の3つのイベントを実装するだけです。

WindowsFormの場合 (2)

DoWorkイベントの抜粋

private void backgroundWorker1_DoWork
  (object sender, DoWorkEventArgs e) {
  BackgroundWorker bw = sender as BackgroundWorker;
  for (int i = 0; i < 100; i++) {
    if (e.Cancel = bw.CancellationPending) {
      return;
    } else {
      Thread.Sleep(100);
      bw.ReportProgress(1);
    }
  }
}

WindowsFormの場合 (3)

ProgressChanged、RunWorkerCompletedイベントの抜粋

private void backgroundWorker1_ProgressChanged
  (object sender, ProgressChangedEventArgs e) {
  progressBar1.Increment(e.ProgressPercentage);
}

private void backgroundWorker1_RunWorkerCompleted
  (object sender, RunWorkerCompletedEventArgs e) {
  if (e.Cancelled == false) {
    MessageBox.Show(this,"Finished");
  }
  this.progressBar1.Value = 0;
  switchButton(true);
}

WindowsFormの場合 (4)

partial classを除くユーザコード

WindowsFormの場合 (5)

VisualStudioが生成するpartialコード

SWTの場合 (1)

SWTでは、Rich Client Platform(RCP)上にUIを構築します。
RCPは、SWTによるスタンドアロンアプリケーションを実装する為の環境です。

RCPでは、Jobと言うクラスを使ってバックグラウンド処理を実現します。
Jobでは、そのサブクラス毎に実装するメソッドが違うのですが、
今回はrunメソッドを実装します。

SWTの場合 (2)

Jobの実装とその実行

Job job = new Job("heavy work") { //$NON-NLS-1$
  @Override
  protected IStatus run(IProgressMonitor monitor) {
    try {
      for (int i = 0; i < 100; i++) {
        if (monitor.isCanceled()) {
          return Status.CANCEL_STATUS;
        } else {
          Thread.sleep(100);
          monitor.worked(1);
        }
      }
    } catch (InterruptedException e) {
      return Status.CANCEL_STATUS;
    } finally {
      monitor.done();
    }
    return Status.OK_STATUS;
  }
};
job.schedule();

SWTの場合 (3)

まとめて全部

UIスレッドとワーカースレッドのディスパッチ まとめ

まとめ

ご清聴ありがとうございました。

色々と至らない部分があるかと思いますが、
何はともあれ、最後までお聞き頂きありがとうございました。