import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
public List<URI> getCandidateURIs() throws IOException {
List<URI> uris = new ArrayList<URI>();
// リソース中の既定 (ロケール識別あり)
- for (File localizedFile : expandLocalizedSuffix(new File(getClass()
- .getResource("/" + CONFIG_NAME).getPath()), null)) {
- uris.add(localizedFile.toURI());
- }
+ getAppConfigResourceURI(uris);
+ // システムプロパティでappConfig.xmlを明示している場合は、それを読み込む。
+ // (appConfigFileシステムプロパティが空の場合は、リソース埋め込みの既定の設定だけをよみこむ)
String specifiedAppConfig = System.getProperty("appConfigFile");
if (specifiedAppConfig != null) {
- // システムプロパティでappConfig.xmlを明示している場合は、それを読み込む。
- // (appConfigFileシステムプロパティが空の場合は、リソース埋め込みの既定の設定だけをよみこむ)
if (specifiedAppConfig.trim().length() > 0) {
File specifiedAppConfigFile = new File(specifiedAppConfig);
uris.add(specifiedAppConfigFile.toURI());
}
/**
+ * リソース上のAppConfigの読み込みURIを追記して返す
+ * @param uris
+ */
+ protected void getAppConfigResourceURI(List<URI> uris) {
+ for (File localizedFile : expandLocalizedSuffix(new File(getClass()
+ .getResource("/" + CONFIG_NAME).getPath()), null)) {
+ uris.add(localizedFile.toURI());
+ }
+ }
+
+ /**
* 保存先の試行順序ごとのファイルのリスト。
*
* @return 保存先(優先順)
* 存在しないか、読み取りに失敗した場合は、該当ファイルはスキップされる.<br>
*/
public void loadConfig() {
+ try {
+ loadConfig(getCandidateURIs());
+ } catch (IOException ex) {
+ throw new RuntimeException("appConfig.xml loading failed.", ex);
+ }
+ }
+
+ /**
+ * プロパティをロードする.<br>
+ * 存在しないか、読み取りに失敗した場合は、該当ファイルはスキップされる.<br>
+ * @param uris パラメーターの読み込み順
+ */
+ public void loadConfig(List<URI> uris) {
+ if (uris == null) {
+ uris = Collections.emptyList();
+ }
Properties config = new Properties();
try {
- for (URI uri : getCandidateURIs()) {
+ for (URI uri : uris) {
if (uri == null) {
continue; // リソースがない場合はnullになる
}
}
}
- } catch (IOException ex) {
- throw new RuntimeException("appConfig.xml loading failed.", ex);
} catch (RuntimeException ex) {
throw new RuntimeException("appConfig.xml loading failed.", ex);
}
}
/**
+ * アプリケーション設定値のデフォルト値(リソース上のAppConfigのみ)を取得する
+ * @return
+ */
+ public static Map<String, Object> getDefaultProperties() {
+ PropertyAccessorMap<AppConfig> accessorMap = BeanPropertiesUtilities.getPropertyAccessorMap(AppConfig.class);
+
+ AppConfig dummy = new AppConfig(); // アプリケーションから参照されないダミーのインスタンスを作成する.
+
+ // リソース上のAppConfigのみ読み込み
+ List<URI> uris = new ArrayList<URI>();
+ dummy.getAppConfigResourceURI(uris);
+ dummy.loadConfig(uris);
+
+ accessorMap.setBean(dummy);
+
+ // 読み込んだプロパティの書き出し
+ Map<String, Object> defMap = new HashMap<String, Object>();
+ for (Map.Entry<String, PropertyAccessor> propEntry : accessorMap.entrySet()) {
+ String name = propEntry.getKey();
+ PropertyAccessor accessor = propEntry.getValue();
+ Object value = accessor.getValue();
+ defMap.put(name, value);
+ }
+ return defMap;
+ }
+
+ /**
* Propertiesの値を設定した場合に設定できない項目があるかチェックする.<br>
* このメソッドを呼び出しても、アプリケーション設定自身は何も影響されない.<br>
*
}
HashSet<String> rejectedNames = new HashSet<String>();
- PropertyAccessorMap accessorMap = BeanPropertiesUtilities.getPropertyAccessorMap(AppConfig.class);
+ PropertyAccessorMap<AppConfig> accessorMap = BeanPropertiesUtilities.getPropertyAccessorMap(AppConfig.class);
accessorMap.setBean(bean);
for (Map.Entry<String, Object> propEntry : props.entrySet()) {
onSetupLocalization();
}
};
+ Action actResetSettings = new AbstractAction(strings.getProperty("btn.resetSettingsToDefault")) {
+ private static final long serialVersionUID = 1L;
+ public void actionPerformed(ActionEvent e) {
+ onResetSettings();
+ }
+ };
+
+ Box pnlButtons = Box.createHorizontalBox();
+ pnlButtons.add(new JButton(actLocalization));
+ pnlButtons.add(new JButton(actResetSettings));
chkResetDoNotAskAgain = new JCheckBox(strings.getProperty("chk.askForCharactersDir"));
chkResetDoNotAskAgain.addActionListener(new ActionListener() {
gbc.ipady = 0;
gbc.weightx = 1.;
gbc.weighty = 0.;
- btnPanel.add(new JButton(actLocalization), gbc);
+ btnPanel.add(pnlButtons, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
.getLocalizedProperties("languages/appconfigdialog");
// AppConfigへのアクセッサを取得する
- PropertyAccessorMap accessorMap = BeanPropertiesUtilities.getPropertyAccessorMap(AppConfig.class);
+ PropertyAccessorMap<AppConfig> accessorMap = BeanPropertiesUtilities.getPropertyAccessorMap(AppConfig.class);
AppConfig appConfig = AppConfig.getInstance();
accessorMap.setBean(appConfig);
}
/**
+ * 設定値を初期化する
+ */
+ protected void onResetSettings() {
+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
+ .getLocalizedProperties("languages/appconfigdialog");
+ if (JOptionPane.showConfirmDialog(this, strings.getProperty("confirm.resetSettingsToDefault"),
+ strings.getProperty("confirm.close.caption"), JOptionPane.YES_NO_OPTION,
+ JOptionPane.QUESTION_MESSAGE) != JOptionPane.YES_OPTION) {
+ return;
+ }
+
+ Map<String, Object> defMap = AppConfig.getDefaultProperties();
+ for (AppConfigRow rowItem : appConfigTableModel.getItems()) {
+ String name = rowItem.getName();
+ if (defMap.containsKey(name)) {
+ Object value = defMap.get(name);
+ rowItem.setValue(value);
+ }
+ }
+ appConfigTableModel.fireTableDataChanged();
+ }
+
+ /**
* ローカライズリソースをユーザディレクトリ上に展開する.
*/
protected void onSetupLocalization() {
* プロパティへのアクセッサをまとめたもの。
* 実際にビーンにアクセスするためには、{@link #setBean(Object)}でビーンを設定する必要がある。
*/
- public static class PropertyAccessorMap extends AbstractMap<String, PropertyAccessor> {
+ public static class PropertyAccessorMap<T> extends AbstractMap<String, PropertyAccessor> {
- private final BeanHolder beanHolder;
+ private final BeanHolder<T> beanHolder;
private final Map<String, PropertyAccessor> accessorMap;
- public PropertyAccessorMap(Map<String, PropertyAccessor> accessorMap, BeanHolder beanHolder) {
+ public PropertyAccessorMap(Map<String, PropertyAccessor> accessorMap, BeanHolder<T> beanHolder) {
this.accessorMap = accessorMap;
this.beanHolder = beanHolder;
}
- public Object getBean() {
+ public T getBean() {
return beanHolder.getBean();
}
- public void setBean(Object bean) {
+ public void setBean(T bean) {
beanHolder.setBean(bean);
}
* アクセッサからビーンを間接参照するためのホルダ。
* (実際にビーンにアクセスするまでビーンの設定を遅延させるため。)
*/
- public static class BeanHolder {
+ public static class BeanHolder<T> {
- private Object bean;
+ private T bean;
- public Object getBean() {
+ public T getBean() {
return bean;
}
- public void setBean(Object bean) {
+ public void setBean(T bean) {
this.bean = bean;
}
}
* @return
* @throws IntrospectionException
*/
- public static PropertyAccessorMap getPropertyAccessorMap(final Class<?> beanClass) {
+ public static <T> PropertyAccessorMap<T> getPropertyAccessorMap(final Class<T> beanClass) {
if (beanClass == null) {
throw new NullPointerException("beanClass");
}
Map<String, PropertyAccessor> accessorMap = new TreeMap<String, PropertyAccessor>();
- final BeanHolder beanHolder = new BeanHolder();
+ final BeanHolder<T> beanHolder = new BeanHolder<T>();
BeanInfo beanInfo;
try {
}
@Override
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
- T annt = mtdReader.getAnnotation(annotationClass);
+ public <E extends Annotation> E getAnnotation(Class<E> annotationClass) {
+ E annt = mtdReader.getAnnotation(annotationClass);
if (annt == null) {
annt = mtdWriter.getAnnotation(annotationClass);
}
accessorMap.put(name, accessor);
}
}
- return new PropertyAccessorMap(accessorMap, beanHolder);
+ return new PropertyAccessorMap<T>(accessorMap, beanHolder);
}
/**
}
HashSet<String> rejectNames = new HashSet<String>();
- PropertyAccessorMap accessorMap = getPropertyAccessorMap(bean.getClass());
+ @SuppressWarnings("unchecked")
+ PropertyAccessorMap<Object> accessorMap = (PropertyAccessorMap<Object>)getPropertyAccessorMap(bean.getClass());
accessorMap.setBean(bean);
for (Map.Entry<String, PropertyAccessor> accessorEntry : accessorMap.entrySet()) {
}
try {
- PropertyAccessorMap accessorMap = getPropertyAccessorMap(bean.getClass());
+ @SuppressWarnings("unchecked")
+ PropertyAccessorMap<Object> accessorMap = (PropertyAccessorMap<Object>) getPropertyAccessorMap(
+ bean.getClass());
accessorMap.setBean(bean);
for (Map.Entry<String, PropertyAccessor> accessorEntry : accessorMap.entrySet()) {
If the file already exists, the file is overwritten.]]></entry>
<entry key="confirm.setupLocalization.caption">Confirm</entry>
+<entry key="btn.resetSettingsToDefault">Reset settings to default.</entry>
+<entry key="confirm.resetSettingsToDefault">Are you sure you want to reset the setting?</entry>
+
<entry key="compressionQuality">01;Compression Quality</entry>
<entry key="enablePNGSupportForWindows">02;Use the transparency image in Clipboard.(Windows/OSX)</entry>
<entry key="zipNameEncoding">03;ZIP File Encoding</entry>
既にファイルが存在する場合は上書きされます。]]></entry>
<entry key="confirm.setupLocalization.caption">確認</entry>
+<entry key="btn.resetSettingsToDefault">設定のリセット</entry>
+<entry key="confirm.resetSettingsToDefault">設定をリセットしてもよろしいですか?</entry>
+
<entry key="compressionQuality">01;JPEG圧縮時のクオリティ(1が最大、0.1が最小)</entry>
<entry key="enablePNGSupportForWindows">02;クリップボードの透過サポートを有効にする.(Windows/OSX)</entry>
<entry key="zipNameEncoding">03;ZIPファイルに格納されているファイル名のエンコーディング(csWindows31Jが標準)</entry>
如果文件已存在则会被覆盖]]></entry>
<entry key="confirm.setupLocalization.caption">确认</entry>
+<entry key="btn.resetSettingsToDefault">将设置重置为默认值</entry>
+<entry key="confirm.resetSettingsToDefault">您确定要重置设置吗?</entry>
+
<entry key="compressionQuality">01;JPEG压缩质量(1最好,0.1最差)</entry>
<entry key="enablePNGSupportForWindows">02;复制到剪贴板时使用透明图像(Windows/OSX)</entry>
<entry key="zipNameEncoding">03;ZIP解码(默认为csWindows31J)</entry>