「流暢なインターフェイス」によるGUI構築支援

S2Swingでは、XML等による画面定義機能を提供しない代わりに、簡潔な記述でコンポーネント階層を構築できるビルダを用意しようと思っています。発想としてはGroupLayoutBuilderと同じで、以下のエントリも参考にしました。

現在のJavaで、ツリー構造の構築を上手く扱いたい場合は、static importと可変長引数を使った方が簡単でいいと思う。

流れないインタフェース - yojikのlog

このビルダを使うことで、例えば次のような画面を

これだけのコード量で構築できます。

public class Frame1 extends JFrame implements ViewObject {
    private JMenuBar menuBar;
    private JMenu fileMenu;
    private JButton toolButton1;
    private JButton toolButton2;
    private JLabel statusBar;

    private ViewManager viewManager;

    public void initializeComponents() {
        viewManager.createComponents();

        setJMenuBar(menuBar);
        getContentPane().setLayout(new BorderLayout());

        MenuBuilder mb = new MenuBuilder(viewManager.getActionMap());
        mb.build(menuBar,
                mb.menu(fileMenu, 
                        "fileNew", "fileOpen", 
                        mb.separator(), 
                        "fileSave", "fileSaveAs", 
                        mb.separator(),
                        "fileExit"
                )
        );

        ComponentBuilder cb = new ComponentBuilder();
        cb.build(getContentPane(),
                cb.component(new JToolBar(), BorderLayout.NORTH,
                        toolButton1, toolButton2
                ),
                cb.splitPane(BorderLayout.CENTER, 
                        cb.scrollPane(new JTree()), 
                        cb.tabbedPane(
                                cb.tab("Tab 1", cb.scrollPane(new JTextArea())),
                                cb.tab("Tab 2", cb.scrollPane(new JTextArea()))
                        )
                ),
                cb.component(statusBar, BorderLayout.SOUTH)
        );
    }

    ...
}

コンポーネントのキャプションはどこで指定しているかというと、propertiesファイルです。これは単に、Swing Application Frameworkの流儀に従っているだけです。もちろん、キャプション以外のプロパティ(フォント、背景色、etc)も指定できます。

  • resources/Frame1.properties
fileMenu.text=ファイル(&F)
toolButton1.text=ボタン1
toolButton2.text=ボタン2
statusBar.text=ステータスバー

fileNew.Action.text=新規作成(&N)...
fileOpen.Action.text=開く(&O)
fileSave.Action.text=上書き保存(&S)
fileSaveAs.Action.text=名前を付けて保存(&A)...
fileExit.Action.text=終了(&X)

このように、画面定義にXMLではなく「流暢なインターフェイス」(+propertiesファイル)を使う利点は、

  • XMLと比較しても、十分簡潔に書ける。
  • IDEの強力なコード補完を受けられる。
  • ロケール別にpropertiesファイルを用意でき、国際化に対応できる。

逆に欠点は、

  • フォーマッタを使うとインデントが崩れてしまう。

といったところだと思います。

それからもちろんですが、S2Swingにおいて、GUI構築にこの方法を使うことは強制されません。ビルダはユーティリティとして提供するだけなので、部分的に使うのも、全く使わないのも完全に自由です。

あと、yojikさんのエントリのようなstatic importを使わない理由は、IDEの自動コード補完が効かなくなってしまう(Eclipseの場合はPreferences -> Java -> Editor -> Content Assist -> Favoritesにクラス名を登録する必要がある)からです。