isami100のSwingin' Seasar日記

2004-07-06

メニューバー&ツールバーの設定(ラッパ作成)

ここで、メニューバーとツールバーの設定を先にやっておきたいと思います。まずはラッパ群の作成から。

SMenuItem.java
package s2study.ui;
import javax.swing.Icon;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;

public class SMenuItem extends SAbstructButton {
    public SMenuItem() {
        super(new JMenuItem());
    }
    public SMenuItem(JMenu menu) {
        super(menu);
    }
    public SMenuItem(String text) {
        super(new JMenuItem(text));
    }
    public SMenuItem(String text, Icon icon) {
        super(new JMenuItem(text, icon));
    }
    public SMenuItem(String text, int mnemonic) {
        super(new JMenuItem(text, mnemonic));
    }
    public void setAccelerator(KeyStroke keyStroke) {
        getJMenuItem().setAccelerator(keyStroke);
    }
    public JMenuItem getJMenuItem() {
        return (JMenuItem) getOriginal();
    }
}
SMenu.java
package s2study.ui;
import javax.swing.JMenu;

public class SMenu extends SMenuItem {
    public SMenu() {
        super(new JMenu());
    }
    public SMenu(String text) {
        super(new JMenu(text));
    }
    public void add(SMenuItem menuItem) {
        getJMenu().add(menuItem.getJMenuItem());
    }
    public void addSeparator() {
        getJMenu().addSeparator();
    }
    public JMenu getJMenu() {
        return (JMenu) getOriginal();
    }
}
SMenuBar.java
package s2study.ui;
import javax.swing.JMenuBar;

public class SMenuBar extends SContainer {
    public SMenuBar() {
        super(new JMenuBar());
    }
    public void add(SMenu menu) {
        getJMenuBar().add(menu.getJMenu());
    }
    public JMenuBar getJMenuBar() {
        return (JMenuBar) getOriginal();
    }
}
SToolBar.java
package s2study.ui;
import javax.swing.JToolBar;

public class SToolBar extends SContainer {
    public SToolBar() {
        super(new JToolBar());
    }
    public JToolBar getJToolBar() {
        return (JToolBar) getOriginal();
    }
    public void addSeparator() {
        getJToolBar().addSeparator();
    }
    public void setFloatable(boolean isFloatable) {
        getJToolBar().setFloatable(isFloatable);
    }
    public void setBorderPainted(boolean isBorderPainted) {
        getJToolBar().setBorderPainted(isBorderPainted);
    }
    public void setRollover(boolean isRollover) {
        getJToolBar().setRollover(isRollover);
    }
}

SFrameにはメニューバー設定メソッドを追加。

SFrame.java(変更箇所のみ)
    public void setJMenuBar(SMenuBar menuBar) {
        getFrame().setJMenuBar(menuBar.getJMenuBar());
    }

SAbstractButtonにはアクションとニーモニック設定メソッドを追加。

SAbstractButton.java(変更箇所のみ)
    public void setAction(Action action) {
        getButton().setAction(action);
    }
    public void setMnemonic(int mnemonic) {
        getButton().setMnemonic(mnemonic);
    }

また、ActionAdapterをAbstractActionを継承する形に変更。

ActionAdapter.java
package s2study.ui;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;

public class ActionAdapter extends AbstractAction {
    public void actionPerformed(ActionEvent e) {
    }
}

メニューバー&ツールバーの設定(diconファイル設定)

メニューバーとツールバー用のdiconファイルは別に分けて作成します。とりあえず、SearchExitの2メニューを作成。表示名やニーモニックなどのプロパティはメニューやツールボタンに紐付けるアクション側に設定します。

ツールバーについては、HBoxを使って位置の調整をします。

EmployeeRefMenu.dicon


"http://www.seasar.org/dtd/components.dtd">
<components namespace="EmployeeRefMenu">
    <!-- MenuBar -->
    <component name="menuBar" class="s2study.ui.SMenuBar">
        <initMethod name="add"><arg>
            <component name="menu" class="s2study.ui.SMenu">
                <arg>"Menu"</arg>
                <property name="mnemonic">@java.awt.event.KeyEvent@VK_M</property>
                <initMethod name="add"><arg>
                    <component name="search" class="s2study.ui.SMenuItem">
                        <arg>"Search"</arg>
                        <property name="action">searchTrigger</property>
                    </component>
                </arg></initMethod>
                <initMethod name="addSeparator"/>
                <initMethod name="add"><arg>
                    <component name="exit" class="s2study.ui.SMenuItem">
                        <arg>"Exit"</arg>
                        <property name="action">exitTrigger</property>
                    </component>
                </arg></initMethod>
            </component>
        </arg></initMethod>
    </component>

    <!-- ToolBar -->
    <component name="toolBar" class="s2study.ui.SToolBar">
        <property name="borderPainted">false</property>
        <property name="floatable">false</property>
        <property name="rollover">true</property>
        <initMethod name="add"><arg>
            <component name="btnExit" class="s2study.ui.SButton">
                <arg>"Exit"</arg>
                <property name="action">exitTrigger</property>
            </component>
        </arg></initMethod>
        <initMethod name="add"><arg>
            <component name="btnSearch" class="s2study.ui.SButton">
                <arg>"Search"</arg>
                <property name="action">searchTrigger</property>
            </component>
        </arg></initMethod>
    </component>
    <component name="boxToolBar" class="s2study.ui.HBox">
        <initMethod name="add"><arg>toolBar</arg></initMethod>
        <initMethod name="addGlue"/>
    </component>
</components>

アクション用diconファイルはこんな感じ。あと、ログインで作成したExitActionはs2study.app.common.actionに移動。

Action本体はトリガとしての役割をさせる(空実装)ので、○○Triggerという名前にしてます。アクションの実体はAspectで実装します。(アスペクト乱用防止委員会から警告されそうですが。。。)

EmployeeRefAction.dicon


"http://www.seasar.org/dtd/components.dtd">
<components namespace="EmployeeRefAction">
    <!-- Interceptors -->
    <component name="exitAction" class="s2study.app.common.action.ExitAction"/>

    <!-- Listeners -->
    <component name="searchTrigger" class="s2study.ui.ActionAdapter">
        <initMethod name="putValue">
            <arg>@javax.swing.Action@NAME</arg>
            <arg>"Search"</arg>
        </initMethod>
        <initMethod name="putValue">
            <arg>@javax.swing.Action@ACCELERATOR_KEY</arg>
            <arg>@javax.swing.KeyStroke@getKeyStroke(@java.awt.event.KeyEvent@VK_F3, 0)</arg>
        </initMethod>
        <initMethod name="putValue">
            <arg>@javax.swing.Action@MNEMONIC_KEY</arg>
            <arg>@java.awt.event.KeyEvent@VK_S</arg>
        </initMethod>
    </component>
    <component name="exitTrigger" class="s2study.ui.ActionAdapter">
        <initMethod name="putValue">
            <arg>@javax.swing.Action@NAME</arg>
            <arg>"Exit"</arg>
        </initMethod>
        <initMethod name="putValue">
            <arg>@javax.swing.Action@ACCELERATOR_KEY</arg>
            <arg>@javax.swing.KeyStroke@getKeyStroke(@java.awt.event.KeyEvent@VK_F4, @java.awt.event.InputEvent@ALT_MASK )</arg>
        </initMethod>
        <initMethod name="putValue">
            <arg>@javax.swing.Action@MNEMONIC_KEY</arg>
            <arg>@java.awt.event.KeyEvent@VK_X</arg>
        </initMethod>
        <aspect pointcut="actionPerformed">exitAction</aspect>
    </component>
</components>

フレーム用diconファイルでは、メニューバーはSFrameのプロパティとして、ツールバーはBoxに追加する形で設定。

EmployeeRefFrame.dicon(変更箇所のみ)
    <component name="boxVRoot" class="s2study.ui.VBox">
        <initMethod name="add"><arg>boxToolBar</arg></initMethod>
        <initMethod name="add"><arg>boxCondition</arg></initMethod>
        <initMethod name="addStrut"><arg>440</arg></initMethod>
        <initMethod name="addGlue"/>
        <initMethod name="add"><arg>boxWidth</arg></initMethod>
    </component>

    <component name="frame" class="s2study.ui.SFrame">
        <arg>"Employee Reference"</arg>
        <property name="defaultCloseOperation">@javax.swing.JFrame@EXIT_ON_CLOSE</property>
        <property name="jMenuBar">menuBar</property>
        <property name="resizable">false</property>
        <property name="centering">true</property>
        <initMethod name="add"><arg>boxRoot</arg></initMethod>
        <initMethod name="display"/>
    </component>

最後に、EmployeeRef.dicon に EmployeeRefMenu.dicon と EmployeeRefAction.dicon をinclude。

だんだんと、diconファイルが読みづらくなって参りました。なんとかスッキリならないものか。。

higayasuohigayasuo2004/07/06 15:05もうラッパー作らなくてもいけると思う。変なプロパティはしかとするようにしたので。後、initMethodでは直接OGNLを呼び出したほうが記述がシンプルになります。

isami100isami1002004/07/07 09:54ありがとうございます!さっそく試してみます。