Resourceファイルからメニューバーを生成
Total: 12768
, Today: 1
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
リソースファイルを使ってメニューバーやツールバーを生成します。
Screenshot
Advertisement
サンプルコード
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;
}
View in GitHub: Java, Kotlin解説
アプリケーションの起動時にリソースファイルからメニューのテキストの生成、アイコン、ショートカットなどの指定を行います。
- 上記のサンプルでは、バージョンと終了メニューのみ動作してその他のメニューは何も実行しない
src.zip
のMain.properties.utf8
、Main_ja_JP.properties.utf8
(日本語用)などのリソースファイルを編集してメニュー作成したり、以下のようにdefaultActions
に上記のproperties
ファイルに書いたAction
を追加してテストが可能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
で代用する方法もある- 参考: J2SE 5.0 Tiger 虎の穴 Properties
<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
で変換しなくてもリソースファイルのエンコードを指定しての読み込みが可能- 参考: Java 小ネタ千夜一夜 第13夜 Java SE 6はnative2ascii使わなくていいのはみんな知っていると思うが
Java 9
からプロパティファイルはデフォルトでUTF-8
になったため、以下のようなResourceBundle
を作成する必要もなくなった
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;
}
});
参考リンク
- ResourceBundle.Control (Java Platform SE 8)
%JAVA_HOME%/demo/jfc/Notepad/src/Notepad.java
- UTF-8プロパティ・ファイル - JDK 9における国際化の拡張機能
- JDK-8027607 (rb) Provide UTF-8 based properties resource bundles - Java Bug System