TITLE:Resourceファイルからメニューバーを生成
#navi(../)
*Resourceファイルからメニューバーを生成 [#mc12a27d]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2003-09-25~
更新日:&lastmod;

#contents

**概要 [#h8d32078]
リソースファイルを使ってメニューバーやツールバーを生成します。詳しくは ''%JAVA_HOME%/demo/jfc/Notepad/src/Notepad.java'' を参照してください。

#screenshot

**サンプルコード [#t11a6578]
#code{{
 public JMenuBar createMenubar() {
   JMenuBar mb = new JMenuBar();
   String[] menuKeys = tokenize(getResourceString("menubar"));
   for(int i=0;i<menuKeys.length;i++) {
     JMenu m = createMenu(menuKeys[i]);
     if(m != null) {
       mb.add(m);
     }
   }
   return mb;
 }
 
 private JMenu createMenu(String key) {
   String[] itemKeys = tokenize(getResourceString(key));
   String mitext = getResourceString(key + labelSuffix);
   JMenu menu = new JMenu(mitext);
   String mn = getResourceString(key + mneSuffix);
   if(mn!=null) {
     String tmp = mn.toUpperCase().trim();
     if(tmp.length()==1) {
       if(mitext.indexOf(tmp)<0) {
         menu.setText(mitext+" ("+tmp+")");
       }
       byte[] bt = tmp.getBytes();
       menu.setMnemonic((int) bt[0]);
     }
   }
   for(int i=0;i<itemKeys.length;i++) {
     if(itemKeys[i].equals("-")) {
       menu.addSeparator();
     }else{
       JMenuItem mi = createMenuItem(itemKeys[i]);
       menu.add(mi);
     }
   }
   menus.put(key, menu);
   return menu;
 }
 
 private JMenuItem createMenuItem(String cmd) {
   String mitext = getResourceString(cmd + labelSuffix);
   JMenuItem mi = new JMenuItem(mitext);
   URL url = getResource(cmd+imageSuffix);
   if(url!=null) {
     mi.setHorizontalTextPosition(JButton.RIGHT);
     mi.setIcon(new ImageIcon(url));
   }
   String astr = getResourceString(cmd + actionSuffix);
   if(astr == null) {
     astr = cmd;
   }
   String mn = getResourceString(cmd + mneSuffix);
   if(mn!=null) {
     String tmp = mn.toUpperCase().trim();
     if(tmp.length()==1) {
       if(mitext.indexOf(tmp)<0) {
         mi.setText(mitext+" ("+tmp+")");
       }
       byte[] bt = tmp.getBytes();
       mi.setMnemonic((int) bt[0]);
     }
   }
   mi.setActionCommand(astr);
   Action a = getAction(astr);
   if(a!=null) {
     mi.addActionListener(a);
     //a.addPropertyChangeListener(createActionChangeListener(mi));
     mi.setEnabled(a.isEnabled());
   }else{
     mi.setEnabled(false);
   }
   menuItems.put(cmd, mi);
   return mi;
 }
 
 public JMenuItem getMenuItem(String cmd) {
   return (JMenuItem) menuItems.get(cmd);
 }
 
 public JMenu getMenu(String cmd) {
   return (JMenu) menus.get(cmd);
 }
 
 public Action getAction(String cmd) {
   return (Action) commands.get(cmd);
 }
 
 public Action[] getActions() {
   return actions;
 }
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#ae955fd5]
アプリケーションの起動時に、リソースファイルからメニューのテキストの生成、アイコン、ショートカットなどの指定を行います。

上記のサンプルでは、バージョンと終了しか機能しないので、このページにあるsrc.zipの"Main.properties.utf8"、"Main_ja_JP.properties.utf8"(日本語用)といったリソースファイルを編集したり、新しいリソースファイルを作成してみてください。

ソースコードの方では以下のように"defaultActions"に、上記のpropertiesファイルに書いたActionを追加します。
#code{{
 public Action[] defaultActions={
   new NewAction(),
   //new OpenAction(),
   new ExitAction(),
   new HelpAction(),
   new VersionAction(),
 };
}}

リソースファイルで日本語などをそのまま使用することは出来ないので、以下のように ant から native2ascii でユニコードエスケープしています。
 <condition property="have.resources">
  <available file="${res.dir}" />
 </condition>
 <target name="prepare-resource" depends="prepare" if="have.resources">
  <mkdir dir="${build.res}" />
  <native2ascii encoding="UTF-8" src="${res.dir}" dest="${build.res}"
                includes="**/*.properties.utf8" ext="" />
  <copy todir="${build.res}">
   <fileset dir="${res.dir}" excludes="**/*.properties.*, **/*.bak" />
  </copy>
 </target>

面倒な場合は、Java 5 での、XML に対応した Properties を使用するようにしてみてください。
-参考: [[J2SE 5.0 Tiger 虎の穴 Properties>http://www.javainthebox.net/laboratory/J2SE1.5/TinyTips/Properties/Properties.html]]

//**参考リンク
**コメント [#u53b57cb]
#comment