• R/O
  • SSH
  • HTTPS

charactermanaj: コミット


コミットメタ情報

リビジョン85 (tree)
日時2013-11-25 07:46:55
作者seraphy

ログメッセージ

キャラクターデータの独自独自テンプレートの作成機能の追加

変更サマリ

差分

--- trunk/src/charactermanaj/graphics/io/ImageSaveHelper.java (revision 84)
+++ trunk/src/charactermanaj/graphics/io/ImageSaveHelper.java (revision 85)
@@ -238,7 +238,7 @@
238238
239239 // ファイルが存在すれば上書き確認する.
240240 if (outFile.exists()) {
241- Properties strings = LocalizedResourcePropertyLoader.getInstance()
241+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
242242 .getLocalizedProperties(STRINGS_RESOURCE);
243243
244244 if (JOptionPane.showConfirmDialog(this,
@@ -542,7 +542,7 @@
542542
543543 public OutputOptionPanel(OutputOption outputOption) {
544544
545- Properties strings = LocalizedResourcePropertyLoader.getInstance()
545+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
546546 .getLocalizedProperties(ImageSaveHelper.STRINGS_RESOURCE);
547547
548548 setBorder(BorderFactory.createCompoundBorder(
--- trunk/src/charactermanaj/graphics/io/UkagakaImageSaveHelper.java (revision 84)
+++ trunk/src/charactermanaj/graphics/io/UkagakaImageSaveHelper.java (revision 85)
@@ -93,7 +93,7 @@
9393 * コンストラクタ
9494 */
9595 public UkagakaImageSaveHelper() {
96- Properties strings = LocalizedResourcePropertyLoader.getInstance()
96+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
9797 .getLocalizedProperties(STRINGS_RESOURCE);
9898
9999 lastUseSaveName = strings.getProperty("default.lastUseSaveName");
@@ -120,7 +120,7 @@
120120 }
121121
122122 if (save && outFile.exists()) {
123- Properties strings = LocalizedResourcePropertyLoader.getInstance()
123+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
124124 .getLocalizedProperties(STRINGS_RESOURCE);
125125
126126 if (JOptionPane.showConfirmDialog(this,
--- trunk/src/charactermanaj/model/io/CharacterDataDefaultProvider.java (revision 84)
+++ trunk/src/charactermanaj/model/io/CharacterDataDefaultProvider.java (revision 85)
@@ -1,9 +1,17 @@
11 package charactermanaj.model.io;
22
3+import java.io.BufferedInputStream;
4+import java.io.BufferedOutputStream;
5+import java.io.File;
6+import java.io.FileInputStream;
37 import java.io.FileNotFoundException;
8+import java.io.FileOutputStream;
49 import java.io.IOException;
510 import java.io.InputStream;
611 import java.net.URL;
12+import java.sql.Timestamp;
13+import java.util.EnumSet;
14+import java.util.Enumeration;
715 import java.util.LinkedHashMap;
816 import java.util.Map;
917 import java.util.Properties;
@@ -11,8 +19,10 @@
1119 import java.util.logging.Logger;
1220
1321 import charactermanaj.model.CharacterData;
22+import charactermanaj.util.ConfigurationDirUtilities;
1423 import charactermanaj.util.LocalizedResourcePropertyLoader;
1524 import charactermanaj.util.ResourceLoader;
25+import charactermanaj.util.SetupLocalization;
1626
1727 /**
1828 * デフォルトキャラクターセットのプロバイダ
@@ -19,7 +29,7 @@
1929 *
2030 * @author seraphy
2131 */
22-public class CharacterDataDefaultProvider extends ResourceLoader {
32+public class CharacterDataDefaultProvider {
2333
2434 /**
2535 * リソースに格納されているデフォルトのキャラクター定義のリソースパスまでのプレフィックス.<br>
@@ -27,6 +37,11 @@
2737 public static final String DEFAULT_CHARACTER_PREFIX = "template/";
2838
2939 /**
40+ * テンプレートをリストしているXML形式のプロパティファイル名
41+ */
42+ public static final String TEMPLATE_LIST_XML = "characterDataTemplates";
43+
44+ /**
3045 * デフォルトのキャラクターセット名(ver2)
3146 */
3247 public static final String DEFAULT_CHARACTER_NAME_V2 = "character2.xml";
@@ -95,11 +110,16 @@
95110 * @return 順序付マップ
96111 */
97112 public Map<String, String> getCharacterDataTemplates() {
98- Properties props = LocalizedResourcePropertyLoader.getInstance()
99- .getLocalizedProperties("template/characterDataTemplates");
113+ // テンプレートリソースは実行中に増減する可能性があるため、
114+ // 共有キャッシュには入れない.
115+ LocalizedResourcePropertyLoader propLoader = new LocalizedResourcePropertyLoader(
116+ null);
117+ Properties props = propLoader.getLocalizedProperties("template/"
118+ + TEMPLATE_LIST_XML);
100119
101120 LinkedHashMap<String, String> results = new LinkedHashMap<String, String>();
102121
122+ // 順序優先
103123 String strOrders = props.getProperty("displayOrder");
104124 if (strOrders != null) {
105125 for (String key : strOrders.split(",")) {
@@ -106,6 +126,24 @@
106126 key = key.trim();
107127 String val = props.getProperty(key);
108128 if (val != null && val.trim().length() > 0) {
129+ String resKey = DEFAULT_CHARACTER_PREFIX + key;
130+ if (getResource(resKey) != null) {
131+ // 現存するテンプレートのみ登録
132+ results.put(key, val);
133+ }
134+ }
135+ }
136+ }
137+
138+ // 順序が指定されていないアイテムの追加
139+ Enumeration<?> enm = props.propertyNames();
140+ while (enm.hasMoreElements()) {
141+ String key = (String) enm.nextElement();
142+ String val = props.getProperty(key);
143+ if (key.endsWith(".xml")) {
144+ String resKey = DEFAULT_CHARACTER_PREFIX + key;
145+ if (getResource(resKey) != null) {
146+ // 現存するテンプレートのみ登録
109147 results.put(key, val);
110148 }
111149 }
@@ -144,4 +182,123 @@
144182 }
145183 return cd;
146184 }
185+
186+ /**
187+ * リソースを取得する.<br>
188+ *
189+ * @param resKey
190+ * リソースキー
191+ * @return リソース、なければnull
192+ */
193+ protected URL getResource(String resKey) {
194+ ResourceLoader resourceLoader = new ResourceLoader();
195+ return resourceLoader.getResource(resKey);
196+ }
197+
198+ /**
199+ * カスタマイズ用のテンプレートディレクトリを取得する.<br>
200+ * まだ作成されていない場合で、prepareが指示されている場合はフォルダを準備し、 既定のファイルを作成する.<br>
201+ *
202+ * @param prepare
203+ * 実際にディレクトリを準備する場合はtrue
204+ * @return テンプレートディレクトリ
205+ */
206+ public File getTemplateDir(boolean prepare) throws IOException {
207+ File baseDir = ConfigurationDirUtilities.getUserDataDir();
208+ SetupLocalization setup = new SetupLocalization(baseDir);
209+ File resourceDir = setup.getResourceDir();
210+
211+ if (prepare) {
212+ // テンプレートリソースが未設定であれば設定する.
213+ setup.setupToLocal(
214+ EnumSet.of(SetupLocalization.Resources.Template), false);
215+
216+ // ディレクトリがなければ作成しておく
217+ if (resourceDir.exists()) {
218+ resourceDir.mkdirs();
219+ }
220+ }
221+ return new File(resourceDir, DEFAULT_CHARACTER_PREFIX);
222+ }
223+
224+ /**
225+ * "characterDataTemplates*.xml"のファイルは管理ファイルのため、 <br>
226+ * ユーザによる書き込みは禁止とする.<br>
227+ *
228+ * @param name
229+ * @return 書き込み可能であるか?
230+ */
231+ public boolean canFileSave(String name) {
232+ if (name.trim().startsWith("characterDataTemplates")) {
233+ return false;
234+ }
235+ return true;
236+ }
237+
238+ /**
239+ * 指定したキャラクターデータをテンプレートとして保存する.<br>
240+ *
241+ * @param name
242+ * 保存するテンプレートファイル名
243+ * @param cd
244+ * キャラクターデータ
245+ * @param localizedName
246+ * 表示名
247+ * @throws IOException
248+ */
249+ public void saveTemplate(String name, CharacterData cd, String localizedName)
250+ throws IOException {
251+ if (name == null || !canFileSave(name)) {
252+ throw new IllegalArgumentException();
253+ }
254+
255+ // テンプレートファイル位置の準備
256+ // (リソースが、まだファイルに展開されていなれば展開する)
257+ File templDir = getTemplateDir(true);
258+ File templFile = new File(templDir, name);
259+
260+ // キャラクターデータをXML形式でテンプレートファイルへ保存
261+ CharacterDataXMLWriter characterDataXmlWriter = new CharacterDataXMLWriter();
262+ BufferedOutputStream bos = new BufferedOutputStream(
263+ new FileOutputStream(templFile));
264+ try {
265+ // パーツセットなしの状態とし、名前をローカライズ名に設定する.
266+ CharacterData templCd = cd.duplicateBasicInfo(false);
267+ templCd.setName(localizedName);
268+
269+ characterDataXmlWriter.writeXMLCharacterData(templCd, bos);
270+
271+ } finally {
272+ bos.close();
273+ }
274+
275+ // 現在のテンプレート一覧のファイルリソースの読み込み
276+ // (言語中立のリソースのみ)
277+ Properties neutralProps = new Properties();
278+ File neutralPropsFile = new File(templDir, TEMPLATE_LIST_XML + ".xml");
279+ if (neutralPropsFile.exists()) {
280+ BufferedInputStream bis = new BufferedInputStream(
281+ new FileInputStream(neutralPropsFile));
282+ try {
283+ neutralProps.loadFromXML(bis);
284+
285+ } finally {
286+ bis.close();
287+ }
288+ }
289+
290+ // テンプレート一覧の更新
291+ neutralProps.put(name, localizedName);
292+
293+ // テンプレート一覧の保存
294+ BufferedOutputStream fos = new BufferedOutputStream(
295+ new FileOutputStream(neutralPropsFile));
296+ try {
297+ neutralProps.storeToXML(fos,
298+ new Timestamp(System.currentTimeMillis()).toString());
299+
300+ } finally {
301+ bos.close();
302+ }
303+ }
147304 }
--- trunk/src/charactermanaj/ui/SearchPartsDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/SearchPartsDialog.java (revision 85)
@@ -110,7 +110,7 @@
110110 });
111111
112112
113- Properties strings = LocalizedResourcePropertyLoader.getInstance()
113+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
114114 .getLocalizedProperties(STRINGS_RESOURCE);
115115
116116 setTitle(strings.getProperty("title"));
@@ -446,7 +446,7 @@
446446 private static final int[] COLUMN_WIDTHS;
447447
448448 static {
449- Properties strings = LocalizedResourcePropertyLoader.getInstance()
449+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
450450 .getLocalizedProperties(SearchPartsDialog.STRINGS_RESOURCE);
451451
452452 COLUMN_NAMES = new String[] {
--- trunk/src/charactermanaj/ui/MainFrame.java (revision 84)
+++ trunk/src/charactermanaj/ui/MainFrame.java (revision 85)
@@ -609,7 +609,7 @@
609609
610610 // 設定まわり準備
611611 AppConfig appConfig = AppConfig.getInstance();
612- Properties strings = LocalizedResourcePropertyLoader.getInstance()
612+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
613613 .getLocalizedProperties(STRINGS_RESOURCE);
614614
615615 // タイトル表示
@@ -1266,7 +1266,7 @@
12661266 protected void onChangeBgColor() {
12671267 getJMenuBar().setEnabled(false);
12681268 try {
1269- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1269+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
12701270 .getLocalizedProperties(STRINGS_RESOURCE);
12711271
12721272 Color color = wallpaperInfo.getBackgroundColor();
@@ -1718,7 +1718,7 @@
17181718 return;
17191719 }
17201720
1721- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1721+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
17221722 .getLocalizedProperties(STRINGS_RESOURCE);
17231723
17241724 if (JOptionPane.showConfirmDialog(this, strings.get("confirm.resetcolors"), strings.getProperty("confirm"),
@@ -1961,7 +1961,7 @@
19611961 }
19621962
19631963 protected void onHelp() {
1964- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1964+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
19651965 .getLocalizedProperties(STRINGS_RESOURCE);
19661966 String helpURL = strings.getProperty("help.url");
19671967 String helpDescription = strings.getProperty("help.show");
@@ -2095,7 +2095,7 @@
20952095 return;
20962096 }
20972097
2098- Properties strings = LocalizedResourcePropertyLoader.getInstance()
2098+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
20992099 .getLocalizedProperties(STRINGS_RESOURCE);
21002100
21012101 // お気に入りに登録するパーツセットが最後に使用したお気に入りと同じ構成であれば、
@@ -2205,7 +2205,7 @@
22052205 */
22062206 protected JMenuBar createMenuBar() {
22072207 final Properties strings = LocalizedResourcePropertyLoader
2208- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
2208+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
22092209
22102210 MenuDataFactory[] menus = new MenuDataFactory[] {
22112211 new MenuDataFactory("menu.file", new MenuDataFactory[] {
--- trunk/src/charactermanaj/ui/PreviewPanel.java (revision 84)
+++ trunk/src/charactermanaj/ui/PreviewPanel.java (revision 85)
@@ -232,7 +232,7 @@
232232 setLayout(new BorderLayout());
233233
234234 final AppConfig appConfig = AppConfig.getInstance();
235- final Properties strings = LocalizedResourcePropertyLoader.getInstance()
235+ final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
236236 .getLocalizedProperties(STRINGS_RESOURCE);
237237
238238 // 画像をロード中であることを示すインジケータの確認サイクル.
@@ -1808,7 +1808,7 @@
18081808 * コンストラクタ
18091809 */
18101810 public PreviewControlPanel() {
1811- final Properties strings = LocalizedResourcePropertyLoader.getInstance()
1811+ final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
18121812 .getLocalizedProperties(STRINGS_RESOURCE);
18131813
18141814 UIHelper uiHelper = UIHelper.getInstance();
--- trunk/src/charactermanaj/ui/ImageSelectPanel.java (revision 84)
+++ trunk/src/charactermanaj/ui/ImageSelectPanel.java (revision 85)
@@ -255,7 +255,7 @@
255255
256256 AppConfig appConfig = AppConfig.getInstance();
257257
258- final Properties strings = LocalizedResourcePropertyLoader.getInstance()
258+ final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
259259 .getLocalizedProperties(STRINGS_RESOURCE);
260260
261261 final Color selectedItemColor = appConfig.getCheckedItemBgColor();
--- trunk/src/charactermanaj/ui/ArchiveFileChooser.java (revision 84)
+++ trunk/src/charactermanaj/ui/ArchiveFileChooser.java (revision 85)
@@ -95,7 +95,7 @@
9595 }
9696 }
9797
98- Properties strings = LocalizedResourcePropertyLoader.getInstance()
98+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
9999 .getLocalizedProperties(STRINGS_RESOURCE);
100100
101101 if (writeMode && file.exists()) {
--- trunk/src/charactermanaj/ui/InformationDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/InformationDialog.java (revision 85)
@@ -104,7 +104,7 @@
104104 });
105105
106106 final Properties strings = LocalizedResourcePropertyLoader
107- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
107+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
108108
109109 setTitle(strings.getProperty("title"));
110110
@@ -298,7 +298,7 @@
298298
299299 static {
300300 final Properties strings = LocalizedResourcePropertyLoader
301- .getInstance().getLocalizedProperties(InformationDialog.STRINGS_RESOURCE);
301+ .getCachedInstance().getLocalizedProperties(InformationDialog.STRINGS_RESOURCE);
302302
303303 columnNames = new String[] {
304304 strings.getProperty("column.partsName"),
--- trunk/src/charactermanaj/ui/ManageFavoriteDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/ManageFavoriteDialog.java (revision 85)
@@ -86,7 +86,7 @@
8686 });
8787
8888 Properties strings = LocalizedResourcePropertyLoader
89- .getInstance()
89+ .getCachedInstance()
9090 .getLocalizedProperties(STRINGS_RESOURCE);
9191
9292 setTitle(strings.getProperty("manageFavorites"));
@@ -235,7 +235,7 @@
235235 */
236236 protected void onDelete() {
237237 // 削除の確認ダイアログ
238- Properties strings = LocalizedResourcePropertyLoader.getInstance()
238+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
239239 .getLocalizedProperties(STRINGS_RESOURCE);
240240
241241 String msg = strings.getProperty("favorite.remove.confirm");
@@ -288,7 +288,7 @@
288288 protected void onRename() {
289289 PartsSet partsSet = (PartsSet) list.getSelectedValue();
290290 if (partsSet != null) {
291- Properties strings = LocalizedResourcePropertyLoader.getInstance()
291+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
292292 .getLocalizedProperties(STRINGS_RESOURCE);
293293
294294 String localizedName = JOptionPane.showInputDialog(this, strings
--- trunk/src/charactermanaj/ui/ImportWizardDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/ImportWizardDialog.java (revision 85)
@@ -213,7 +213,7 @@
213213 }
214214 });
215215
216- Properties strings = LocalizedResourcePropertyLoader.getInstance()
216+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
217217 .getLocalizedProperties(STRINGS_RESOURCE);
218218
219219 // タイトル
@@ -429,7 +429,7 @@
429429 }
430430
431431 protected void onClose() {
432- Properties strings = LocalizedResourcePropertyLoader.getInstance()
432+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
433433 .getLocalizedProperties(STRINGS_RESOURCE);
434434
435435 if (JOptionPane.showConfirmDialog(this,
@@ -455,7 +455,7 @@
455455 * インポートの実行.<br>
456456 */
457457 protected void onFinish() {
458- Properties strings = LocalizedResourcePropertyLoader.getInstance()
458+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
459459 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
460460
461461 try {
@@ -776,7 +776,7 @@
776776 public ImportFileSelectPanel() {
777777 setLayout(new BorderLayout());
778778
779- Properties strings = LocalizedResourcePropertyLoader.getInstance()
779+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
780780 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
781781
782782 DocumentListener documentListener = new DocumentListener() {
@@ -1041,7 +1041,7 @@
10411041 return null;
10421042 }
10431043
1044- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1044+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
10451045 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
10461046
10471047 URI importArchive;
@@ -1260,7 +1260,7 @@
12601260 /* 以下、選択結果 */
12611261
12621262 public ImportTypeSelectPanel() {
1263- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1263+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
12641264 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
12651265
12661266 GridBagLayout basicPanelLayout = new GridBagLayout();
@@ -1467,7 +1467,7 @@
14671467 return;
14681468 }
14691469
1470- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1470+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
14711471 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
14721472
14731473 // 呼び出しもと情報
@@ -1707,7 +1707,7 @@
17071707
17081708
17091709 public ImportPartsSelectPanel() {
1710- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1710+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
17111711 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
17121712
17131713 setLayout(new BorderLayout());
@@ -2415,7 +2415,7 @@
24152415 private Set<PartsIdentifier> currentProfilePartsIdentifiers;
24162416
24172417 static {
2418- Properties strings = LocalizedResourcePropertyLoader.getInstance()
2418+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
24192419 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
24202420
24212421 COLUMN_NAMES = new String[] {
@@ -2850,7 +2850,7 @@
28502850 private Action actSelectUsedParts;
28512851
28522852 public ImportPresetSelectPanel() {
2853- Properties strings = LocalizedResourcePropertyLoader.getInstance()
2853+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
28542854 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
28552855
28562856 setBorder(BorderFactory.createTitledBorder(strings.getProperty("preset.title")));
@@ -3185,7 +3185,7 @@
31853185 private static final int[] COLUMN_WIDTHS; // = {50, 100, 200};
31863186
31873187 static {
3188- Properties strings = LocalizedResourcePropertyLoader.getInstance()
3188+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
31893189 .getLocalizedProperties(ImportWizardDialog.STRINGS_RESOURCE);
31903190
31913191 COLUMN_NAMES = new String[] {
--- trunk/src/charactermanaj/ui/model/PredefinedWallpaper.java (revision 84)
+++ trunk/src/charactermanaj/ui/model/PredefinedWallpaper.java (revision 85)
@@ -76,7 +76,7 @@
7676 * @return 定義済み壁紙リソースリスト
7777 */
7878 public static List<PredefinedWallpaper> getPredefinedWallpapers() {
79- Properties predefinedWallpapers = LocalizedResourcePropertyLoader.getInstance()
79+ Properties predefinedWallpapers = LocalizedResourcePropertyLoader.getCachedInstance()
8080 .getLocalizedProperties(PREDEFINED_WALLPAPER_RESOURCE);
8181
8282 ArrayList<PredefinedWallpaper> results = new ArrayList<PredefinedWallpaper>();
--- trunk/src/charactermanaj/ui/ProfileSelectorDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/ProfileSelectorDialog.java (revision 85)
@@ -48,6 +48,7 @@
4848 import javax.swing.JComboBox;
4949 import javax.swing.JComponent;
5050 import javax.swing.JDialog;
51+import javax.swing.JFileChooser;
5152 import javax.swing.JFrame;
5253 import javax.swing.JLabel;
5354 import javax.swing.JList;
@@ -58,6 +59,7 @@
5859 import javax.swing.JRadioButton;
5960 import javax.swing.JRootPane;
6061 import javax.swing.JScrollPane;
62+import javax.swing.JSeparator;
6163 import javax.swing.JSplitPane;
6264 import javax.swing.JTable;
6365 import javax.swing.JTextArea;
@@ -84,6 +86,7 @@
8486 import charactermanaj.model.io.PartsImageDirectoryWatchAgent;
8587 import charactermanaj.model.io.PartsImageDirectoryWatchAgentFactory;
8688 import charactermanaj.ui.util.FileDropTarget;
89+import charactermanaj.ui.util.SingleRootFileSystemView;
8790 import charactermanaj.util.DesktopUtilities;
8891 import charactermanaj.util.ErrorMessageHelper;
8992 import charactermanaj.util.LocalizedResourcePropertyLoader;
@@ -121,8 +124,9 @@
121124 */
122125 private SamplePicturePanel sampleImgPanel;
123126
127+ private Action actOK;
124128
125- private JButton btnOK;
129+ private Action actCancel;
126130
127131 private Action actProfileNew;
128132
@@ -138,6 +142,8 @@
138142
139143 private Action actProfileExport;
140144
145+ private Action actProfileTemplate;
146+
141147 /**
142148 * プロファイル一覧を表示するリストコンポーネント
143149 */
@@ -185,7 +191,7 @@
185191 });
186192
187193 final Properties strings = LocalizedResourcePropertyLoader
188- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
194+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
189195
190196 setTitle(strings.getProperty("title"));
191197
@@ -248,6 +254,20 @@
248254 .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
249255 pnlProfiles.add(characterListSP, BorderLayout.CENTER);
250256
257+ actOK = new AbstractAction(strings.getProperty("btn.select")) {
258+ private static final long serialVersionUID = 1L;
259+ public void actionPerformed(ActionEvent e) {
260+ onOK();
261+ }
262+ };
263+
264+ actCancel = new AbstractAction(strings.getProperty("btn.cancel")) {
265+ private static final long serialVersionUID = 1L;
266+ public void actionPerformed(ActionEvent e) {
267+ onCancel();
268+ }
269+ };
270+
251271 actProfileNew = new AbstractAction(strings.getProperty("profile.new")) {
252272 private static final long serialVersionUID = 1L;
253273 public void actionPerformed(ActionEvent e) {
@@ -301,6 +321,43 @@
301321 }
302322 };
303323
324+ actProfileTemplate = new AbstractAction(
325+ strings.getProperty("profile.template")) {
326+ private static final long serialVersionUID = 1L;
327+ public void actionPerformed(ActionEvent e) {
328+ onProfileTemplate();
329+ }
330+ };
331+
332+ final JPopupMenu popupTblMenu = new JPopupMenu();
333+ popupTblMenu.add(new JMenuItem(actOK));
334+ popupTblMenu.add(new JSeparator());
335+ popupTblMenu.add(new JMenuItem(actProfileCopy));
336+ popupTblMenu.add(new JMenuItem(actProfileEdit));
337+ popupTblMenu.add(new JMenuItem(actProfileRemove));
338+ popupTblMenu.add(new JSeparator());
339+ popupTblMenu.add(new JMenuItem(actProfileBrowse));
340+ popupTblMenu.add(new JMenuItem(actProfileImport));
341+ popupTblMenu.add(new JMenuItem(actProfileExport));
342+ popupTblMenu.add(new JSeparator());
343+ popupTblMenu.add(new JMenuItem(actProfileTemplate));
344+
345+ characterList.addMouseListener(new MouseAdapter() {
346+ @Override
347+ public void mousePressed(MouseEvent e) {
348+ evaluatePopup(e);
349+ }
350+ @Override
351+ public void mouseReleased(MouseEvent e) {
352+ evaluatePopup(e);
353+ }
354+ private void evaluatePopup(MouseEvent e) {
355+ if (e.isPopupTrigger()) {
356+ popupTblMenu.show(characterList, e.getX(), e.getY());
357+ }
358+ }
359+ });
360+
304361 JButton btnProfileNew = new JButton(actProfileNew);
305362 JButton btnProfileCopy = new JButton(actProfileCopy);
306363 JButton btnProfileEdit = new JButton(actProfileEdit);
@@ -308,6 +365,7 @@
308365 JButton btnProfileBrowse = new JButton(actProfileBrowse);
309366 JButton btnProfileImport = new JButton(actProfileImport);
310367 JButton btnProfileExport = new JButton(actProfileExport);
368+ JButton btnProfileTemplate = new JButton(actProfileTemplate);
311369
312370 JPanel pnlProfileEditButtons = new JPanel();
313371 pnlProfileEditButtons.setLayout(new GridBagLayout());
@@ -357,6 +415,10 @@
357415 gbc.gridy = 7;
358416 pnlProfileEditButtons.add(btnProfileExport, gbc);
359417
418+ gbc.gridx = 0;
419+ gbc.gridy = 8;
420+ pnlProfileEditButtons.add(btnProfileTemplate, gbc);
421+
360422 JPanel pnlProfilesGroup = new JPanel(new BorderLayout());
361423 pnlProfilesGroup.setBorder(BorderFactory.createCompoundBorder(BorderFactory
362424 .createEmptyBorder(3, 3, 3, 3), BorderFactory
@@ -461,20 +523,7 @@
461523 btnPanel.setLayout(boxLayout);
462524 btnPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 42));
463525
464- AbstractAction actOK = new AbstractAction(strings.getProperty("btn.select")) {
465- private static final long serialVersionUID = 1L;
466- public void actionPerformed(ActionEvent e) {
467- onOK();
468- }
469- };
470- AbstractAction actCancel = new AbstractAction(strings.getProperty("btn.cancel")) {
471- private static final long serialVersionUID = 1L;
472- public void actionPerformed(ActionEvent e) {
473- onCancel();
474- }
475- };
476-
477- btnOK = new JButton(actOK);
526+ JButton btnOK = new JButton(actOK);
478527 JButton btnCancel = new JButton(actCancel);
479528 if (Main.isLinuxOrMacOSX()) {
480529 btnPanel.add(btnCancel);
@@ -523,13 +572,13 @@
523572 }
524573
525574 final Properties strings = LocalizedResourcePropertyLoader
526- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
575+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
527576
528577 boolean selected = (characterData != null);
529578 boolean enableEdit = (characterData != null)
530579 && characterData.canWrite();
531580
532- btnOK.setEnabled(selected);
581+ actOK.setEnabled(selected);
533582
534583 actProfileNew.setEnabled(true);
535584 actProfileCopy.setEnabled(selected);
@@ -538,6 +587,7 @@
538587 actProfileImport.setEnabled(true);
539588 actProfileExport.setEnabled(selected);
540589 actProfileBrowse.setEnabled(selected);
590+ actProfileTemplate.setEnabled(selected);
541591
542592 if (enableEdit) {
543593 actProfileEdit.putValue(Action.NAME,
@@ -782,7 +832,7 @@
782832 if (makeDefault || cd == null) {
783833 try {
784834 final Properties strings = LocalizedResourcePropertyLoader
785- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
835+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
786836
787837 // キャラクターデータ選択用のコンボボックスの準備
788838 JComboBox comboTemplates = new JComboBox();
@@ -795,7 +845,9 @@
795845 boolean cellHasFocus) {
796846 @SuppressWarnings("unchecked")
797847 Map.Entry<String, String> entry = (Map.Entry<String, String>) value;
798- lbl.setText(entry.getValue());
848+ if (entry != null) {
849+ lbl.setText(entry.getValue());
850+ }
799851 return lbl;
800852 }
801853 });
@@ -915,7 +967,7 @@
915967 }
916968
917969 final Properties strings = LocalizedResourcePropertyLoader
918- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
970+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
919971
920972 String msgTempl = strings.getProperty("profile.remove.confirm");
921973 MessageFormat fmt = new MessageFormat(msgTempl);
@@ -1006,7 +1058,7 @@
10061058 // 選択したプロファイルを更新するか、新規にプロファイルを作成するか選択できるようにする
10071059 if (selCd != null) {
10081060 final Properties strings = LocalizedResourcePropertyLoader
1009- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
1061+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
10101062
10111063 JPanel radioPanel = new JPanel(new BorderLayout());
10121064 JRadioButton btnUpdate = new JRadioButton(strings.getProperty("importToUpdateProfile"));
@@ -1113,6 +1165,96 @@
11131165 return;
11141166 }
11151167 }
1168+
1169+ /**
1170+ * 選択したプロファイルをテンプレートとして登録する.
1171+ */
1172+ protected void onProfileTemplate() {
1173+ try {
1174+ CharacterData cd = null;
1175+ int selRow = characterList.getSelectedRow();
1176+ if (selRow >= 0) {
1177+ cd = characterListModel.getRow(selRow);
1178+ }
1179+ if (cd == null || !cd.isValid()) {
1180+ Toolkit tk = Toolkit.getDefaultToolkit();
1181+ tk.beep();
1182+ return;
1183+ }
1184+
1185+ String defualtName = cd.getId() + "_" + cd.getRev() + ".xml";
1186+ // Windowsでのファイル名として使用禁止の文字を置換する.
1187+ for (char c : "<>|:;*?/\\\"".toCharArray()) {
1188+ defualtName = defualtName.replace(c, '_');
1189+ }
1190+
1191+ // カスタマイズ用テンプレートファイルの格納場所を取得する.
1192+ final CharacterDataDefaultProvider defProv = new CharacterDataDefaultProvider();
1193+ final File templDir = defProv.getTemplateDir(true);
1194+
1195+ // 指定されたディレクトリ以外に表示・移動できないファイルシステムビューを使用したファイルチューザ
1196+ JFileChooser fileChooser = new JFileChooser(
1197+ new SingleRootFileSystemView(templDir)) {
1198+ private static final long serialVersionUID = 1L;
1199+
1200+ @Override
1201+ public void approveSelection() {
1202+ File outFile = getSelectedFile();
1203+ if (outFile == null) {
1204+ return;
1205+ }
1206+ String name = outFile.getName();
1207+ if (!defProv.canFileSave(name) || !name.endsWith(".xml")) {
1208+ // 書き込み不可ファイル、もしくはxml以外なので許可しない.
1209+ Toolkit tk = Toolkit.getDefaultToolkit();
1210+ tk.beep();
1211+ return;
1212+ }
1213+
1214+ // ファイルが存在すれば上書き確認する.
1215+ if (outFile.exists()) {
1216+ Properties strings = LocalizedResourcePropertyLoader
1217+ .getCachedInstance().getLocalizedProperties(
1218+ STRINGS_RESOURCE);
1219+
1220+ if (JOptionPane.showConfirmDialog(this,
1221+ strings.getProperty("confirmOverwrite"),
1222+ strings.getProperty("confirm"),
1223+ JOptionPane.YES_NO_OPTION,
1224+ JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) {
1225+ return;
1226+ }
1227+ }
1228+
1229+ super.approveSelection();
1230+ }
1231+ };
1232+
1233+ // 保存先ファイル名
1234+ fileChooser.setSelectedFile(new File(templDir, defualtName));
1235+ int ret = fileChooser.showSaveDialog(this);
1236+ if (ret != JFileChooser.APPROVE_OPTION) {
1237+ return;
1238+ }
1239+
1240+ // テンプレート名
1241+ String localizedName = cd.getName();
1242+ final Properties strings = LocalizedResourcePropertyLoader
1243+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
1244+ localizedName = JOptionPane.showInputDialog(this,
1245+ strings.getProperty("inputTemplateName"), localizedName);
1246+ if (localizedName == null) {
1247+ return;
1248+ }
1249+
1250+ File outFile = fileChooser.getSelectedFile();
1251+ defProv.saveTemplate(outFile.getName(), cd, localizedName);
1252+
1253+ } catch (Exception ex) {
1254+ ErrorMessageHelper.showErrorDialog(this, ex);
1255+ return;
1256+ }
1257+ }
11161258 }
11171259
11181260 /**
@@ -1185,7 +1327,7 @@
11851327 return;
11861328 }
11871329 final Properties strings = LocalizedResourcePropertyLoader
1188- .getInstance().getLocalizedProperties(
1330+ .getCachedInstance().getLocalizedProperties(
11891331 ProfileSelectorDialog.STRINGS_RESOURCE);
11901332 displayName = strings.getProperty(columnName);
11911333 width = Integer
--- trunk/src/charactermanaj/ui/UkagakaConvertDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/UkagakaConvertDialog.java (revision 85)
@@ -178,7 +178,7 @@
178178 */
179179 private void initComponent() {
180180
181- Properties strings = LocalizedResourcePropertyLoader.getInstance()
181+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
182182 .getLocalizedProperties(STRINGS_RESOURCE);
183183
184184 setTitle(strings.getProperty("title"));
--- trunk/src/charactermanaj/ui/ProfileEditDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/ProfileEditDialog.java (revision 85)
@@ -260,7 +260,7 @@
260260 // 設定
261261 AppConfig appConfig = AppConfig.getInstance();
262262 final Properties strings = LocalizedResourcePropertyLoader
263- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
263+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
264264
265265 // タイトル
266266 String title;
@@ -1214,7 +1214,7 @@
12141214 boolean writable = !original.isValid() || original.canWrite(); // 新規または更新可能
12151215 if (writable) {
12161216 final Properties strings = LocalizedResourcePropertyLoader
1217- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
1217+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
12181218 if (JOptionPane.showConfirmDialog(this, strings.get("confirm.close"), strings.getProperty("confirm"),
12191219 JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) {
12201220 // YESでなければ継続しない.
@@ -1302,7 +1302,7 @@
13021302 // 編集可能であり、且つ、保存可能な状態であれば
13031303 CharacterData newCd = createCharacterData();
13041304 final Properties strings = LocalizedResourcePropertyLoader
1305- .getInstance().getLocalizedProperties(STRINGS_RESOURCE);
1305+ .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
13061306 if (original.isValid() && !original.isSameStructure(newCd)) {
13071307 if (original.getRev().equals(newCd.getRev())) {
13081308 // 構造が変更されているがREVが変らない場合
@@ -1566,7 +1566,7 @@
15661566
15671567 static {
15681568 final Properties strings = LocalizedResourcePropertyLoader
1569- .getInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
1569+ .getCachedInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
15701570 colorGroupColumnNames = new String[] {
15711571 strings.getProperty("colorgroup.column.colorgroupname"),
15721572 };
@@ -2032,7 +2032,7 @@
20322032
20332033 static {
20342034 final Properties strings = LocalizedResourcePropertyLoader
2035- .getInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
2035+ .getCachedInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
20362036 categoriesColumnName = new String[] {
20372037 strings.getProperty("categories.column.categoryname"),
20382038 strings.getProperty("categories.column.multipleselectable"),
@@ -2322,7 +2322,7 @@
23222322
23232323 static {
23242324 final Properties strings = LocalizedResourcePropertyLoader
2325- .getInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
2325+ .getCachedInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
23262326 int columnsLen = Columns.values().length;
23272327 layerColumnNames = new String[columnsLen];
23282328 layersColumnWidths = new int[columnsLen];
@@ -2638,7 +2638,7 @@
26382638
26392639 static {
26402640 final Properties strings = LocalizedResourcePropertyLoader
2641- .getInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
2641+ .getCachedInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
26422642 partssetsColumnNames = new String[] {
26432643 strings.getProperty("partssets.column.default"),
26442644 strings.getProperty("partssets.column.preset"),
@@ -2857,7 +2857,7 @@
28572857
28582858 static {
28592859 final Properties strings = LocalizedResourcePropertyLoader
2860- .getInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
2860+ .getCachedInstance().getLocalizedProperties(ProfileEditDialog.STRINGS_RESOURCE);
28612861 partssetsColumnNames = new String[] {
28622862 strings.getProperty("recommendations.column.displayName"),
28632863 strings.getProperty("recommendations.column.url"),
--- trunk/src/charactermanaj/ui/SamplePicturePanel.java (revision 84)
+++ trunk/src/charactermanaj/ui/SamplePicturePanel.java (revision 85)
@@ -192,7 +192,7 @@
192192 Container parent = getParent();
193193 if (parent != null && parent instanceof JViewport) {
194194 Properties strings = LocalizedResourcePropertyLoader
195- .getInstance().getLocalizedProperties("languages/samplepicturepanel");
195+ .getCachedInstance().getLocalizedProperties("languages/samplepicturepanel");
196196 if (!fullsize) {
197197 tooltip = strings.getProperty("dblclick.fullsize");
198198 } else {
--- trunk/src/charactermanaj/ui/WallpaperDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/WallpaperDialog.java (revision 85)
@@ -152,7 +152,7 @@
152152 * このダイアログのコンポーネントを初期化します.<br>
153153 */
154154 private void initComponent() {
155- Properties strings = LocalizedResourcePropertyLoader.getInstance()
155+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
156156 .getLocalizedProperties(WallpaperDialog.STRINGS_RESOURCE);
157157
158158 setTitle(strings.getProperty("title"));
@@ -532,7 +532,7 @@
532532 }
533533
534534 if (messageid != null) {
535- Properties strings = LocalizedResourcePropertyLoader.getInstance()
535+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
536536 .getLocalizedProperties(WallpaperDialog.STRINGS_RESOURCE);
537537
538538 String message = strings.getProperty(messageid);
--- trunk/src/charactermanaj/ui/MenuBuilder.java (revision 84)
+++ trunk/src/charactermanaj/ui/MenuBuilder.java (revision 85)
@@ -87,7 +87,7 @@
8787 public JMenuBar createMenuBar(MenuDataFactory[] menus) {
8888
8989 // メニューリソース
90- Properties menuProps = LocalizedResourcePropertyLoader.getInstance()
90+ Properties menuProps = LocalizedResourcePropertyLoader.getCachedInstance()
9191 .getLocalizedProperties(MENU_STRINGS_RESOURCE);
9292
9393 // メニューバー
--- trunk/src/charactermanaj/ui/ExportWizardDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/ExportWizardDialog.java (revision 85)
@@ -144,7 +144,7 @@
144144 }
145145 });
146146
147- Properties strings = LocalizedResourcePropertyLoader.getInstance()
147+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
148148 .getLocalizedProperties(STRINGS_RESOURCE);
149149
150150 // タイトル
@@ -343,7 +343,7 @@
343343 }
344344
345345 protected void onClose() {
346- Properties strings = LocalizedResourcePropertyLoader.getInstance()
346+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
347347 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
348348
349349 if (JOptionPane.showConfirmDialog(this,
@@ -389,7 +389,7 @@
389389 }
390390
391391 // 完了メッセージ
392- Properties strings = LocalizedResourcePropertyLoader.getInstance()
392+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
393393 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
394394 JOptionPane.showMessageDialog(this, strings.getProperty("complete"));
395395
@@ -576,7 +576,7 @@
576576 setName("basicPanel");
577577 this.samplePicture = samplePicture;
578578
579- Properties strings = LocalizedResourcePropertyLoader.getInstance()
579+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
580580 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
581581
582582 GridBagLayout basicPanelLayout = new GridBagLayout();
@@ -795,7 +795,7 @@
795795 throw new IllegalArgumentException();
796796 }
797797
798- Properties strings = LocalizedResourcePropertyLoader.getInstance()
798+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
799799 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
800800
801801 setName("choosePartsPanel");
@@ -1027,7 +1027,7 @@
10271027
10281028 setName("presetSelectPanel");
10291029
1030- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1030+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
10311031 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
10321032
10331033 setName("choosePartsPanel");
@@ -1264,7 +1264,7 @@
12641264 private boolean enabled = true;
12651265
12661266 static {
1267- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1267+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
12681268 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
12691269
12701270 columnNames = new String[] {
@@ -1616,7 +1616,7 @@
16161616 private boolean enabled = true;
16171617
16181618 static {
1619- Properties strings = LocalizedResourcePropertyLoader.getInstance()
1619+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
16201620 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
16211621
16221622 columnNames = new String[] {
--- trunk/src/charactermanaj/ui/PartsManageDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/PartsManageDialog.java (revision 85)
@@ -110,7 +110,7 @@
110110 }
111111 });
112112
113- Properties strings = LocalizedResourcePropertyLoader.getInstance()
113+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
114114 .getLocalizedProperties(STRINGS_RESOURCE);
115115
116116 setTitle(strings.getProperty("title"));
@@ -509,7 +509,7 @@
509509 authors.add(row.getAuthor() == null ? "" : row.getAuthor());
510510 }
511511
512- Properties strings = LocalizedResourcePropertyLoader.getInstance()
512+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
513513 .getLocalizedProperties(STRINGS_RESOURCE);
514514
515515 if (authors.size() > 1) {
@@ -557,7 +557,7 @@
557557 authors.add(row.getAuthor() == null ? "" : row.getAuthor());
558558 }
559559
560- Properties strings = LocalizedResourcePropertyLoader.getInstance()
560+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
561561 .getLocalizedProperties(STRINGS_RESOURCE);
562562
563563 if (authors.size() > 1) {
@@ -656,7 +656,7 @@
656656 }
657657
658658 protected void onClose() {
659- Properties strings = LocalizedResourcePropertyLoader.getInstance()
659+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
660660 .getLocalizedProperties(STRINGS_RESOURCE);
661661 if (JOptionPane.showConfirmDialog(this,
662662 strings.getProperty("confirm.cancel"),
@@ -891,7 +891,7 @@
891891 .getLogger(PartsManageTableModel.class.getName());
892892
893893 private static Properties strings = LocalizedResourcePropertyLoader
894- .getInstance().getLocalizedProperties(
894+ .getCachedInstance().getLocalizedProperties(
895895 PartsManageDialog.STRINGS_RESOURCE);
896896
897897 /**
--- trunk/src/charactermanaj/ui/AppConfigDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/AppConfigDialog.java (revision 85)
@@ -15,6 +15,7 @@
1515 import java.awt.event.WindowEvent;
1616 import java.io.File;
1717 import java.util.Collections;
18+import java.util.EnumSet;
1819 import java.util.Properties;
1920 import java.util.Set;
2021 import java.util.logging.Level;
@@ -94,7 +95,7 @@
9495
9596 private void initComponent() {
9697
97- Properties strings = LocalizedResourcePropertyLoader.getInstance()
98+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
9899 .getLocalizedProperties("languages/appconfigdialog");
99100
100101 setTitle(strings.getProperty("title"));
@@ -274,7 +275,7 @@
274275 * ローカライズリソースをユーザディレクトリ上に展開する.
275276 */
276277 protected void onSetupLocalization() {
277- Properties strings = LocalizedResourcePropertyLoader.getInstance()
278+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
278279 .getLocalizedProperties("languages/appconfigdialog");
279280 if (JOptionPane.showConfirmDialog(this,
280281 strings.getProperty("setupLocalization"),
@@ -286,7 +287,8 @@
286287 try {
287288 File baseDir = ConfigurationDirUtilities.getUserDataDir();
288289 SetupLocalization setup = new SetupLocalization(baseDir);
289- setup.setupToLocal();
290+ setup.setupToLocal(
291+ EnumSet.allOf(SetupLocalization.Resources.class), true);
290292
291293 File resourceDir = setup.getResourceDir();
292294 DesktopUtilities.open(resourceDir);
@@ -298,7 +300,7 @@
298300
299301 protected void onClose() {
300302 if (appConfigTableModel.isModified()) {
301- Properties strings = LocalizedResourcePropertyLoader.getInstance()
303+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
302304 .getLocalizedProperties("languages/appconfigdialog");
303305 if (JOptionPane.showConfirmDialog(this, strings.getProperty("confirm.close"),
304306 strings.getProperty("confirm.close.caption"), JOptionPane.YES_NO_OPTION,
@@ -318,7 +320,7 @@
318320 return;
319321 }
320322
321- Properties strings = LocalizedResourcePropertyLoader.getInstance()
323+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
322324 .getLocalizedProperties("languages/appconfigdialog");
323325
324326 // 編集されたプロパティを取得する.
@@ -453,7 +455,7 @@
453455 private Properties original;
454456
455457 static {
456- Properties strings = LocalizedResourcePropertyLoader.getInstance()
458+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
457459 .getLocalizedProperties("languages/appconfigdialog");
458460
459461 COLUMN_NAMES = new String[] {
@@ -474,7 +476,7 @@
474476 if (original != null) {
475477 target.putAll(original);
476478
477- Properties strings = LocalizedResourcePropertyLoader.getInstance()
479+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
478480 .getLocalizedProperties("languages/appconfigdialog");
479481
480482 for (Object key : target.keySet()) {
--- trunk/src/charactermanaj/ui/ColorBox.java (revision 84)
+++ trunk/src/charactermanaj/ui/ColorBox.java (revision 85)
@@ -80,7 +80,7 @@
8080 }
8181 this.colorKey = colorKey;
8282
83- Properties strings = LocalizedResourcePropertyLoader.getInstance()
83+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
8484 .getLocalizedProperties(STRINGS_RESOURCE);
8585
8686 colorDisplayPanel = createColorDiaplyPanel();
@@ -222,7 +222,7 @@
222222 }
223223
224224 protected String getColorDialogTitle() {
225- Properties strings = LocalizedResourcePropertyLoader.getInstance()
225+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
226226 .getLocalizedProperties(STRINGS_RESOURCE);
227227 return strings.getProperty("caption.chooseColorKey");
228228 }
--- trunk/src/charactermanaj/ui/SelectCharatersDirDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/SelectCharatersDirDialog.java (revision 85)
@@ -137,7 +137,7 @@
137137 }
138138
139139 private void initComponent() {
140- Properties strings = LocalizedResourcePropertyLoader.getInstance()
140+ Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
141141 .getLocalizedProperties("languages/selectCharatersDirDialog");
142142
143143 Container contentPane = getContentPane();
--- trunk/src/charactermanaj/ui/util/SingleRootFileSystemView.java (nonexistent)
+++ trunk/src/charactermanaj/ui/util/SingleRootFileSystemView.java (revision 85)
@@ -0,0 +1,45 @@
1+package charactermanaj.ui.util;
2+
3+import java.io.File;
4+import java.io.IOException;
5+
6+import javax.swing.filechooser.FileSystemView;
7+
8+/**
9+ * ファイルチューザのコンストラクタに指定することで、特定のディレクトリ以外に移動できないようにする<br>
10+ * ためのファイルシステムビューを構築します.<br>
11+ * 親ディレクトリへの移動、別のルートディレクトリの選択はできず、新規ディレクトリの作成もできません.<br>
12+ *
13+ * @author seraphy
14+ */
15+public class SingleRootFileSystemView extends FileSystemView {
16+
17+ /**
18+ * 対象ディレクトリ
19+ */
20+ private File dir;
21+
22+ public SingleRootFileSystemView(File templDir) {
23+ if (templDir == null) {
24+ throw new IllegalArgumentException();
25+ }
26+ this.dir = templDir;
27+ }
28+
29+ @Override
30+ public File createNewFolder(File containingDir) throws IOException {
31+ return null;
32+ }
33+ @Override
34+ public File getDefaultDirectory() {
35+ return dir;
36+ }
37+ @Override
38+ public File getHomeDirectory() {
39+ return dir;
40+ }
41+ @Override
42+ public File[] getRoots() {
43+ return new File[]{dir};
44+ }
45+}
--- trunk/src/charactermanaj/ui/ColorDialog.java (revision 84)
+++ trunk/src/charactermanaj/ui/ColorDialog.java (revision 85)
@@ -138,7 +138,7 @@
138138 super(parent);
139139 this.partsCategory = partsCategory;
140140
141- final Properties strings = LocalizedResourcePropertyLoader.getInstance().getLocalizedProperties("languages/colordialog");
141+ final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance().getLocalizedProperties("languages/colordialog");
142142
143143 String caption = strings.getProperty("colordialog.caption");
144144 String name = partsCategory.getLocalizedCategoryName();
@@ -711,7 +711,7 @@
711711 }
712712 this.parent = parent;
713713
714- final Properties strings = LocalizedResourcePropertyLoader.getInstance().getLocalizedProperties("languages/colordialog");
714+ final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance().getLocalizedProperties("languages/colordialog");
715715
716716 setLayout(new BorderLayout());
717717 JPanel container = new JPanel();
--- trunk/src/charactermanaj/util/SetupLocalization.java (revision 84)
+++ trunk/src/charactermanaj/util/SetupLocalization.java (revision 85)
@@ -11,6 +11,7 @@
1111 import java.net.URLConnection;
1212 import java.util.ArrayList;
1313 import java.util.Collection;
14+import java.util.EnumSet;
1415 import java.util.Enumeration;
1516 import java.util.jar.JarEntry;
1617 import java.util.jar.JarFile;
@@ -28,6 +29,28 @@
2829
2930 public static final String DIRNAME_RESOURCES = "resources";
3031
32+ /**
33+ * リソースフォルダ下のサブディレクトリ一覧.<br>
34+ */
35+ public enum Resources {
36+ Languages("languages"), Menu("menu"), Template("template");
37+
38+ private final String dirName;
39+
40+ private Resources(String dirName) {
41+ this.dirName = dirName;
42+ }
43+
44+ public String getDirName() {
45+ return dirName;
46+ }
47+
48+ @Override
49+ public String toString() {
50+ return getDirName();
51+ }
52+ }
53+
3154 private File baseDir;
3255
3356 /**
@@ -46,19 +69,23 @@
4669 /**
4770 * コピー対象とするリソース一覧を取得する.<br>
4871 *
72+ * @param resourceSet
73+ * リソースディレクトリのサブディレクトリ名のリスト
4974 * @return リソース一覧(言語関連リソース、テンプレートなど)
5075 * @throws IOException
5176 * 失敗
5277 */
53- protected Collection<String> getResourceList() throws IOException {
78+ protected Collection<String> getResourceList(EnumSet<Resources> resourceSet)
79+ throws IOException {
80+ if (resourceSet == null) {
81+ resourceSet = EnumSet.noneOf(Resources.class);
82+ }
5483 ArrayList<String> resources = new ArrayList<String>();
5584
56- // リソースとしてコピー対象とするパッケージ名
57- String[] names = new String[]{"languages", "menu", "template"};
58-
5985 ClassLoader cl = getClass().getClassLoader();
6086
61- for (String name : names) {
87+ for (Resources resourceKey : resourceSet) {
88+ String name = resourceKey.getDirName();
6289 URL loc = cl.getResource(name);
6390 if (loc == null) {
6491 continue;
@@ -174,17 +201,25 @@
174201 /**
175202 * ローカルシステム上のアプリケーションデータディレクトリに言語リソースをコピーする.
176203 *
204+ * @param resourceSet
205+ * コピーするリソースセット.
206+ * @param overwrite
207+ * 上書きを許可する場合はtrue、スキップする場合はfalse
177208 * @throws IOException
178209 * 失敗
179210 */
180- public void setupToLocal() throws IOException {
211+ public void setupToLocal(EnumSet<Resources> resourceSet, boolean overwrite)
212+ throws IOException {
181213 File toDir = getResourceDir();
182214 ClassLoader cl = getDefaultClassLoader();
183- for (String resourceName : getResourceList()) {
215+ for (String resourceName : getResourceList(resourceSet)) {
184216 URL url = cl.getResource(resourceName);
185217 if (url != null) {
186218 File toFile = new File(toDir, resourceName).getCanonicalFile();
187- copyResource(url, toFile);
219+ if (overwrite || !toFile.exists()) {
220+ // 上書き許可か、まだファイルが存在しなければコピーする.
221+ copyResource(url, toFile);
222+ }
188223
189224 } else {
190225 logger.log(Level.WARNING, "missing resource: " + resourceName);
--- trunk/src/charactermanaj/util/LocalizedResourcePropertyLoader.java (revision 84)
+++ trunk/src/charactermanaj/util/LocalizedResourcePropertyLoader.java (revision 85)
@@ -4,6 +4,7 @@
44 import java.net.URL;
55 import java.util.HashMap;
66 import java.util.Locale;
7+import java.util.Map;
78 import java.util.Properties;
89
910 /**
@@ -10,7 +11,7 @@
1011 * xml形式のリソース上のプロパティファイルのローカライズされた読み込みを行うためのクラス.<br>
1112 * リソースは、単純名、言語名を末尾に付与したもの、言語名と国を末尾に付与したもの、言語名と国とバリアントを末尾に付与したもの、の順で読み取られる.<br>
1213 * 順番に読み込んで重ね合わせる.<br>
13- * 一度読み込んだものはキャッシュされ次回以降は読み取られない.<br>
14+ * 一度読み込んだものはキャッシュに保存され次回以降は、それが用いられる.<br>
1415 */
1516 public class LocalizedResourcePropertyLoader extends ResourceLoader {
1617
@@ -17,25 +18,31 @@
1718 /**
1819 * プロパティファイル群と、それに対するキャッシュ
1920 */
20- private HashMap<ResourceNames, Properties> propCache = new HashMap<ResourceNames, Properties>();
21+ private Map<ResourceNames, Properties> propCache;
2122
2223 /**
23- * シングルトンインスタンス
24+ * キャッシュを共有するシングルトンインスタンス.
2425 */
25- private static final LocalizedResourcePropertyLoader inst = new LocalizedResourcePropertyLoader();
26+ private static final LocalizedResourcePropertyLoader inst = new LocalizedResourcePropertyLoader(
27+ new HashMap<ResourceNames, Properties>());
2628
2729 /**
28- * プライベートコンストラクタ
30+ * 独立したキャッシュを指定することのできるコンストラクタ.<br>
31+ *
32+ * @param propCache
33+ * キャッシュ、不要であればnull可
2934 */
30- private LocalizedResourcePropertyLoader() {
31- super();
35+ public LocalizedResourcePropertyLoader(
36+ Map<ResourceNames, Properties> propCache) {
37+ this.propCache = propCache;
3238 }
3339
3440 /**
3541 * インスタンスを取得する
42+ *
3643 * @return インスタンス
3744 */
38- public static LocalizedResourcePropertyLoader getInstance() {
45+ public static LocalizedResourcePropertyLoader getCachedInstance() {
3946 return inst;
4047 }
4148
@@ -42,7 +49,9 @@
4249 /**
4350 * リソース名を指定してデフォルトのロケールでローカライズされたリソースプロパティを読み込む.<br>
4451 * リソースはxml形式である。リソース名には.xmlを付与しない.(自動的に内部で付与される.)
45- * @param name リソース名
52+ *
53+ * @param name
54+ * リソース名
4655 * @return プロパティ
4756 */
4857 public Properties getLocalizedProperties(String name) {
@@ -52,11 +61,30 @@
5261 /**
5362 * リソース名を指定して指定したロケールでローカライズされたリソースプロパティを読み込む.<br>
5463 * リソースはxml形式である。リソース名には.xmlを付与しない.(自動的に内部で付与される.)
55- * @param name リソース名
56- * @param locale ロケール、nullの場合はデフォルトのロケール
64+ *
65+ * @param name
66+ * リソース名
67+ * @param locale
68+ * ロケール、nullの場合はデフォルトのロケール
5769 * @return プロパティ
5870 */
5971 public Properties getLocalizedProperties(String name, Locale locale) {
72+ return getProperties(getResourceNames(name, locale));
73+ }
74+
75+ /**
76+ * リソース名を指定して指定したロケールでローカライズされたリソースプロパティの一覧を取得する.<br>
77+ * リソースはxml形式である。リソース名には.xmlを付与しない.(自動的に内部で付与される.)<br>
78+ * 返される順序は、読み込み順となる。(順番に読み込んで上書きしてゆくことを想定する).<br>
79+ * ロケール中立のものが先頭となり、指定したロケールにもっとも一致するものが最後となる.<br>
80+ *
81+ * @param name
82+ * リソース名
83+ * @param locale
84+ * ロケール、nullの場合はデフォルトのロケール
85+ * @return プロパティリソースの一覧(読み込み順)
86+ */
87+ public static ResourceNames getResourceNames(String name, Locale locale) {
6088 if (name == null || name.length() == 0) {
6189 throw new IllegalArgumentException();
6290 }
@@ -74,28 +102,34 @@
74102 name + "_" + language + "_" + country + ".xml",
75103 name + "_" + language + "_" + country + "_" + variant + ".xml",
76104 };
77-
78- return getProperties(new ResourceNames(resourceNames));
105+ return new ResourceNames(resourceNames);
79106 }
80107
81108 /**
82109 * リソース名群をもとにキャッシュもしくはプロパティをロードして返す.<br>
83110 * キャッシュされていない場合はプロパティをロードして、それをキャッシュに格納する.<br>
111+ * (共有キャッシュ時、もしくは独自のキャッシュが指定されている場合).<br>
84112 * リソースが一つも存在しない場合は実行時例外を発生させる.<br>
85- * @param resourceNames リソース名群
113+ *
114+ * @param resourceNames
115+ * リソース名群
86116 * @return プロパティ
87117 */
88- protected Properties getProperties(ResourceNames resourceNames) {
118+ public Properties getProperties(ResourceNames resourceNames) {
89119 if (resourceNames == null) {
90120 throw new IllegalArgumentException();
91121 }
92122 Properties prop;
93- synchronized (propCache) {
94- prop = propCache.get(resourceNames);
95- if (prop == null) {
96- prop = loadProperties(resourceNames);
97- propCache.put(resourceNames, prop);
123+ if (propCache != null) {
124+ synchronized (propCache) {
125+ prop = propCache.get(resourceNames);
126+ if (prop == null) {
127+ prop = loadProperties(resourceNames);
128+ propCache.put(resourceNames, prop);
129+ }
98130 }
131+ } else {
132+ prop = loadProperties(resourceNames);
99133 }
100134 if (prop == null) {
101135 throw new RuntimeException("missing resource: " + resourceNames);
@@ -106,7 +140,9 @@
106140 /**
107141 * リソース名群からリソースプロパティをロードして返す.<br>
108142 * 一つも存在しない場合はnullを返す.<br>
109- * @param resourceNames リソース群名
143+ *
144+ * @param resourceNames
145+ * リソース群名
110146 * @return プロパティ
111147 */
112148 protected Properties loadProperties(ResourceNames resourceNames) {
--- trunk/src/charactermanaj/util/ResourceNames.java (revision 84)
+++ trunk/src/charactermanaj/util/ResourceNames.java (revision 85)
@@ -5,9 +5,10 @@
55
66 /**
77 * 関連もしくは類似するリソースをまとめて取り扱うためにグループ化するためのクラス.<br>
8+ *
89 * @author seraphy
910 */
10-final class ResourceNames extends AbstractList<String> {
11+public class ResourceNames extends AbstractList<String> {
1112
1213 private final String[] resourceNames;
1314
--- trunk/src/charactermanaj/util/ResourceLoader.java (revision 84)
+++ trunk/src/charactermanaj/util/ResourceLoader.java (revision 85)
@@ -11,17 +11,19 @@
1111
1212 /**
1313 * リソースをロードするための抽象基底クラス.
14+ *
1415 * @author seraphy
1516 */
16-public abstract class ResourceLoader {
17+public class ResourceLoader {
1718
1819 /**
1920 * クラスローダを取得する.<br>
2021 * まずローカルファイル上のリソースディレクトリがあれば、それを検索する.<br>
2122 * つぎにスレッドに関連づけられているコンテキストクラスローダか、もしなければ、このクラスをロードしたクラスローダを用いて検索する.<br>
23+ *
2224 * @return クラスローダ
2325 */
24- protected ClassLoader getClassLoader() {
26+ public ClassLoader getClassLoader() {
2527 return getLocalizedClassLoader(getDefaultClassLoader());
2628 }
2729
@@ -28,9 +30,10 @@
2830 /**
2931 * クラスローダを取得する.<br>
3032 * スレッドに関連づけられているコンテキストクラスローダか、もしなければ、このクラスをロードしたクラスローダを返す.<br>
33+ *
3134 * @return クラスローダ
3235 */
33- protected ClassLoader getDefaultClassLoader() {
36+ public ClassLoader getDefaultClassLoader() {
3437 return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
3538 public ClassLoader run() {
3639 ClassLoader cl = Thread.currentThread().getContextClassLoader();
@@ -46,10 +49,12 @@
4649 * ローカルファイル上のリソースディレクトリにアクセスするクラスローダ取得する.<br>
4750 * 作成されていなければparentをそのまま返す.<br>
4851 * リソースはローカルファイル上のパスで検索されたのちにparentで検索されます.(標準のURLClassLoaderとは違う探索方法)<br>
49- * @param parent 親クラスローダ、nullの場合は親の探索をしない.
52+ *
53+ * @param parent
54+ * 親クラスローダ、nullの場合は親の探索をしない.
5055 * @return ローカルシステム上のリソースディレクトリにアクセスするクラスローダ、なければparentのまま
5156 */
52- protected ClassLoader getLocalizedClassLoader(final ClassLoader parent) {
57+ public ClassLoader getLocalizedClassLoader(final ClassLoader parent) {
5358 try {
5459 File baseDir = ConfigurationDirUtilities.getUserDataDir();
5560 SetupLocalization localize = new SetupLocalization(baseDir);
@@ -63,7 +68,7 @@
6368 return new URLClassLoader(urls, parent) {
6469 @Override
6570 public URL getResource(String name) {
66- URL url = findResource(name); // 子が優先 (標準と逆)
71+ URL url = findResource(name); // 子が優先 (標準と逆)
6772 if (url == null) {
6873 ClassLoader parent = getParent();
6974 if (parent != null) {
@@ -87,10 +92,12 @@
8792 * クラスローダによりリソースをロードする.<br>
8893 * 該当するリソースが存在しない場合はnullを返す.<br>
8994 * リソース名がnullの場合もnullを返す.<br>
90- * @param name リソース名またはnull
95+ *
96+ * @param name
97+ * リソース名またはnull
9198 * @return リソースがあれば、そのURL。なければnull
9299 */
93- protected URL getResource(String name) {
100+ public URL getResource(String name) {
94101 if (name == null) {
95102 return null;
96103 }
--- trunk/resources/languages/profileselectordialog.xml (revision 84)
+++ trunk/resources/languages/profileselectordialog.xml (revision 85)
@@ -4,7 +4,7 @@
44 <entry key="windowHeight">500</entry>
55 <entry key="title">Profile Selector</entry>
66 <entry key="profile.new">New</entry>
7- <entry key="profile.copy">Copy Struct.</entry>
7+ <entry key="profile.copy">Copy Structure</entry>
88 <entry key="profile.edit">Edit</entry>
99 <entry key="profile.edit.readonly">View</entry>
1010 <entry key="profile.remove">Remove</entry>
@@ -11,6 +11,7 @@
1111 <entry key="profile.browse">Browse</entry>
1212 <entry key="profile.import">Import</entry>
1313 <entry key="profile.export">Export</entry>
14+ <entry key="profile.template">Create Template</entry>
1415 <entry key="profileNew.chooseTemplate.title">Choose a Character Data Template</entry>
1516 <entry key="description">Description</entry>
1617 <entry key="profiles">Profiles</entry>
@@ -44,4 +45,9 @@
4445 <entry key="profile.column.description.width">300</entry>
4546 <entry key="profile.column.author.width">150</entry>
4647 <entry key="profile.column.location.width">300</entry>
48+
49+ <entry key="inputTemplateName">Template Name</entry>
50+ <entry key="confirm">Confirm</entry>
51+ <entry key="confirmOverwrite"><![CDATA[file already exists.
52+Do you want to replace it?]]></entry>
4753 </properties>
--- trunk/resources/languages/profileselectordialog_ja.xml (revision 84)
+++ trunk/resources/languages/profileselectordialog_ja.xml (revision 85)
@@ -11,6 +11,7 @@
1111 <entry key="profile.browse">場所を開く</entry>
1212 <entry key="profile.import">インポート</entry>
1313 <entry key="profile.export">エクスポート</entry>
14+ <entry key="profile.template">テンプレートの作成</entry>
1415 <entry key="profileNew.chooseTemplate.title">キャラクターデータのテンプレートの選択</entry>
1516 <entry key="description">プロファイルの説明</entry>
1617 <entry key="profiles">プロファイル一覧</entry>
@@ -44,4 +45,9 @@
4445 <entry key="profile.column.description.width">300</entry>
4546 <entry key="profile.column.author.width">150</entry>
4647 <entry key="profile.column.location.width">300</entry>
48+
49+ <entry key="inputTemplateName">テンプレートの名前</entry>
50+ <entry key="confirm">確認</entry>
51+ <entry key="confirmOverwrite"><![CDATA[ファイルは既に存在します。
52+上書きしてもよろしいですか?]]></entry>
4753 </properties>
旧リポジトリブラウザで表示