Swing/ResourceMenuBar の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/ResourceMenuBar へ行く。
- Swing/ResourceMenuBar の差分を削除
--- category: swing folder: ResourceMenuBar title: Resourceファイルからメニューバーを生成 tags: [JMenuBar, JMenu, JMenuItem, Properties, ResourceBundle] author: aterai pubdate: 2003-10-06 description: リソースファイルを使ってメニューバーやツールバーを生成します。 image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTR15q_ELI/AAAAAAAAAh0/2H6dW1g0eiY/s800/ResourceMenuBar.png --- * 概要 [#summary] リソースファイルを使ってメニューバーやツールバーを生成します。 #download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTR15q_ELI/AAAAAAAAAh0/2H6dW1g0eiY/s800/ResourceMenuBar.png) * サンプルコード [#sourcecode] #code(link){{ 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; } }} * 解説 [#explanation] アプリケーションの起動時にリソースファイルからメニューのテキストの生成、アイコン、ショートカットなどの指定を行います。 - 上記のサンプルでは、バージョンと終了メニューのみ動作してその他のメニューはダミー - 上記のサンプルでは、バージョンと終了メニューのみ動作してその他のメニューは何も実行しない - `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`でユニコードエスケープする必要がある%% `JDK 1.6.0`で変更 -- `JDK 1.5.0`で導入された`XML`に対応した`Properties`で代用する方法もある -- 参考: [http://www.javainthebox.net/laboratory/J2SE1.5/TinyTips/Properties/Properties.html J2SE 5.0 Tiger 虎の穴 Properties] #code{{ <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> }} ---- - `JDK 1.6.0`以降なら`native2ascii`で変換しなくてもリソースファイルのエンコードを指定しての読み込みが可能 -- 参考: [http://d.hatena.ne.jp/shin/20090707/p4 Java 小ネタ千夜一夜 第13夜 Java SE 6はnative2ascii使わなくていいのはみんな知っていると思うが] -- `Java 9`からプロパティファイルはデフォルトで`UTF-8`になったため、以下のような`ResourceBundle`を作成する必要もなくなった --- [https://docs.oracle.com/javase/jp/9/intl/internationalization-enhancements-jdk-9.htm#GUID-974CF488-23E8-4963-A322-82006A7A14C7 UTF-8プロパティ・ファイル - JDK 9における国際化の拡張機能] #code{{ ResourceBundle res = ResourceBundle.getBundle(baseName, new ResourceBundle.Control() { @Override public java.util.List<String> getFormats(String baseName) { if (baseName == null) throw new NullPointerException(); return Arrays.asList("properties"); } @Override public ResourceBundle newBundle( String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { if (baseName == null || locale == null || format == null || loader == null) throw new NullPointerException(); ResourceBundle bundle = null; if (format.equals("properties")) { String bundleName = toBundleName(baseName, locale); String resourceName = toResourceName(bundleName, format); InputStream stream = null; if (reload) { URL url = loader.getResource(resourceName); if (url != null) { URLConnection connection = url.openConnection(); if (connection != null) { connection.setUseCaches(false); stream = connection.getInputStream(); } } } else { stream = loader.getResourceAsStream(resourceName); } if (stream != null) { //BufferedInputStream bis = new BufferedInputStream(stream); try (Reader r = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { bundle = new PropertyResourceBundle(r); } } } return bundle; } }); }} * 参考リンク [#reference] - [https://docs.oracle.com/javase/jp/8/docs/api/java/util/ResourceBundle.Control.html ResourceBundle.Control (Java Platform SE 8)] - `%JAVA_HOME%/demo/jfc/Notepad/src/Notepad.java` - [https://docs.oracle.com/javase/jp/9/intl/internationalization-enhancements-jdk-9.htm#GUID-974CF488-23E8-4963-A322-82006A7A14C7 UTF-8プロパティ・ファイル - JDK 9における国際化の拡張機能] - [https://bugs.openjdk.org/browse/JDK-8027607 JDK-8027607 (rb) Provide UTF-8 based properties resource bundles - Java Bug System] * コメント [#comment] #comment #comment