OSDN Git Service

設定で指定された優先フォントだけを使用するようにUIManagerを調整する。
authorseraphy <seraphy@users.sourceforge.jp>
Mon, 23 Jun 2014 11:17:03 +0000 (20:17 +0900)
committerseraphy <seraphy@users.sourceforge.jp>
Mon, 23 Jun 2014 11:17:03 +0000 (20:17 +0900)
dist/CharacterManaJ.jar
resources/languages/appconfigdialog.xml
resources/languages/appconfigdialog_ja.xml
src/charactermanaj/Main.java
src/charactermanaj/model/AppConfig.java

index aac4512..91c277e 100755 (executable)
Binary files a/dist/CharacterManaJ.jar and b/dist/CharacterManaJ.jar differ
index 034d482..f321cd3 100644 (file)
@@ -1,77 +1,78 @@
-<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">\r
-<properties>\r
-<comment>appConfig.xml</comment>\r
-<!--  だれか翻訳助けて Could someone please translate this.-->\r
-\r
-<entry key="title">Application Configurations</entry>\r
-<entry key="btn.apply">Apply</entry>\r
-<entry key="btn.cancel">Cancel</entry>\r
-<entry key="chk.askForCharactersDir">Ask the data directory during startup.</entry>\r
-<entry key="column.key">Key</entry>\r
-<entry key="column.value">Value</entry>\r
-<entry key="column.key.width">200</entry>\r
-<entry key="column.value.width">100</entry>\r
-<entry key="confirm.close.caption">Confirm</entry>\r
-<entry key="confirm.close">Are you sure want to close?</entry>\r
-<entry key="error.caption">Error</entry>\r
-<entry key="error.message">Please correct incompleteness.</entry>\r
-<entry key="caution">Change to property needs an application restart.</entry>\r
-<entry key="table.caption">Settings</entry>\r
-\r
-<entry key="btn.setupLocalization">Custom Localization</entry>\r
-<entry key="setupLocalization"><![CDATA[Deploying the language resources.\r
-If the file already exists, the file is overwritten.]]></entry>\r
-<entry key="confirm.setupLocalization.caption">Confirm</entry>\r
-\r
-<entry key="compressionQuality">01;Compression Quality</entry>\r
-<entry key="enablePNGSupportForWindows">02;Use the transparency image in Clipboard.(Windows/OSX)</entry>\r
-<entry key="zipNameEncoding">03;ZIP File Encoding</entry>\r
-<entry key="partsColorGroupPattern">04;The judgment pattern of a color group.('@' is color group name)</entry>\r
-<entry key="enableAutoShrinkPanel">05;Auto shrink category panels</entry>\r
-\r
-<entry key="mainFrameMaxWidth">10;Preview Max-Width</entry>\r
-<entry key="mainFrameMaxHeight">11;Preview Max-Height</entry>\r
-<entry key="enableRenderingHints">12;Use rendering hints</entry>\r
-<entry key="enableInterpolationBicubic">13;Use Bicubic</entry>\r
-<entry key="renderingOptimizeThresholdForNormal">14;Threshold of zoom factor of the rendering optimization.(normal)</entry>\r
-<entry key="renderingOptimizeThresholdForCheck">15;Threshold of zoom factor of the rendering optimization.(check)</entry>\r
-<entry key="predefinedZoomRanges">16;Predefined zoom factors</entry>\r
-<entry key="enableZoomPanel">17;Enable zoom panel</entry>\r
-<entry key="zoomPanelActivationArea">18;Area where zoom is activated.</entry>\r
-<entry key="wheelScrollUnit">19;The unit of scrolling by a wheel</entry>\r
-<entry key="enableOffscreenWallpaper">1A;Draw Wallpaper by offscreen.</entry>\r
-<entry key="offscreenWallpaperSize">1B;Offscreen default size.</entry>\r
-\r
-<entry key="enableAutoColorChange">20;Auto Color Refresh</entry>\r
-<entry key="notDisableLayerTab">21;The layer not existing is not disabled in the color dialog.</entry>\r
-\r
-<entry key="enableDirWatch">31;Enable Watch Directory</entry>\r
-<entry key="disableWatchDirIfNotWritable">32;Disable Watch Directory If Not Writable</entry>\r
-<entry key="dirWatchInterval">33;Directory Watch Interval (mSec)</entry>\r
-<entry key="noRemoveLog">34;No Remove Log</entry>\r
-<entry key="purgeLogDays">35;a number in days until purge log</entry>\r
-<entry key="informationDialogOpenMethod">36;Information Dialog Open Mode</entry>\r
-\r
-<entry key="selectedItemBgColor">50;Selected Item's Background Color</entry>\r
-<entry key="exportPresetWarningsForegroundColor">51;Export Preset's Warnings Foreground Color</entry>\r
-<entry key="checkedItemBgColor">52;Checked Item Background Color</entry>\r
-<entry key="sampleImageBgColor">53;Sample Picture Background Color</entry>\r
-<entry key="defaultImageBgColor">54;Preview Background Color</entry>\r
-<entry key="invalidBgColor">55;Invalid Cell's Background Color</entry>\r
-<entry key="gridColor">56;Grid Color</entry>\r
-<entry key="authorEditConflictBgColor">57;Author Conflict Background Color</entry>\r
-<entry key="selectPanelTitleColor">58;Parts Select Panel Hovering Color</entry>\r
-<entry key="defaultFontSize">59;Default Font Size</entry>\r
-\r
-<entry key="jarTransferBufferSize">90;Jar File Buffer</entry>\r
-<entry key="fileTransferBufferSize">91;File Buffer</entry>\r
-\r
-<entry key="drawGridMask">A0;Draw grid on preview</entry>\r
-<entry key="previewGridColor">A1;Grid color (ARGB)</entry>\r
-<entry key="previewGridSize">A2;Grid size</entry>\r
-<entry key="previewUnfilledSpaceForCheckMode">A3;Unfilled space (check-mode only)</entry>\r
-<entry key="enableCheckInfoTooltip">A4;Enable CheckInfo tooltip (check-mode only)</entry>\r
-\r
-<entry key="randomChooserMaxHistory">B0;Limit Of The Random Parts History</entry>\r
-\r
-</properties>\r
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+<comment>appConfig.xml</comment>
+<!--  だれか翻訳助けて Could someone please translate this.-->
+
+<entry key="title">Application Configurations</entry>
+<entry key="btn.apply">Apply</entry>
+<entry key="btn.cancel">Cancel</entry>
+<entry key="chk.askForCharactersDir">Ask the data directory during startup.</entry>
+<entry key="column.key">Key</entry>
+<entry key="column.value">Value</entry>
+<entry key="column.key.width">200</entry>
+<entry key="column.value.width">100</entry>
+<entry key="confirm.close.caption">Confirm</entry>
+<entry key="confirm.close">Are you sure want to close?</entry>
+<entry key="error.caption">Error</entry>
+<entry key="error.message">Please correct incompleteness.</entry>
+<entry key="caution">Change to property needs an application restart.</entry>
+<entry key="table.caption">Settings</entry>
+
+<entry key="btn.setupLocalization">Custom Localization</entry>
+<entry key="setupLocalization"><![CDATA[Deploying the language resources.
+If the file already exists, the file is overwritten.]]></entry>
+<entry key="confirm.setupLocalization.caption">Confirm</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 key="partsColorGroupPattern">04;The judgment pattern of a color group.('@' is color group name)</entry>
+<entry key="enableAutoShrinkPanel">05;Auto shrink category panels</entry>
+
+<entry key="mainFrameMaxWidth">10;Preview Max-Width</entry>
+<entry key="mainFrameMaxHeight">11;Preview Max-Height</entry>
+<entry key="enableRenderingHints">12;Use rendering hints</entry>
+<entry key="enableInterpolationBicubic">13;Use Bicubic</entry>
+<entry key="renderingOptimizeThresholdForNormal">14;Threshold of zoom factor of the rendering optimization.(normal)</entry>
+<entry key="renderingOptimizeThresholdForCheck">15;Threshold of zoom factor of the rendering optimization.(check)</entry>
+<entry key="predefinedZoomRanges">16;Predefined zoom factors</entry>
+<entry key="enableZoomPanel">17;Enable zoom panel</entry>
+<entry key="zoomPanelActivationArea">18;Area where zoom is activated.</entry>
+<entry key="wheelScrollUnit">19;The unit of scrolling by a wheel</entry>
+<entry key="enableOffscreenWallpaper">1A;Draw Wallpaper by offscreen.</entry>
+<entry key="offscreenWallpaperSize">1B;Offscreen default size.</entry>
+
+<entry key="enableAutoColorChange">20;Auto Color Refresh</entry>
+<entry key="notDisableLayerTab">21;The layer not existing is not disabled in the color dialog.</entry>
+
+<entry key="enableDirWatch">31;Enable Watch Directory</entry>
+<entry key="disableWatchDirIfNotWritable">32;Disable Watch Directory If Not Writable</entry>
+<entry key="dirWatchInterval">33;Directory Watch Interval (mSec)</entry>
+<entry key="noRemoveLog">34;No Remove Log</entry>
+<entry key="purgeLogDays">35;a number in days until purge log</entry>
+<entry key="informationDialogOpenMethod">36;Information Dialog Open Mode</entry>
+
+<entry key="selectedItemBgColor">50;Selected Item's Background Color</entry>
+<entry key="exportPresetWarningsForegroundColor">51;Export Preset's Warnings Foreground Color</entry>
+<entry key="checkedItemBgColor">52;Checked Item Background Color</entry>
+<entry key="sampleImageBgColor">53;Sample Picture Background Color</entry>
+<entry key="defaultImageBgColor">54;Preview Background Color</entry>
+<entry key="invalidBgColor">55;Invalid Cell's Background Color</entry>
+<entry key="gridColor">56;Grid Color</entry>
+<entry key="authorEditConflictBgColor">57;Author Conflict Background Color</entry>
+<entry key="selectPanelTitleColor">58;Parts Select Panel Hovering Color</entry>
+<entry key="defaultFontSize">59;Default Font Size</entry>
+<entry key="fontPriority">5a;Default Font Family Name</entry>
+
+<entry key="jarTransferBufferSize">90;Jar File Buffer</entry>
+<entry key="fileTransferBufferSize">91;File Buffer</entry>
+
+<entry key="drawGridMask">A0;Draw grid on preview</entry>
+<entry key="previewGridColor">A1;Grid color (ARGB)</entry>
+<entry key="previewGridSize">A2;Grid size</entry>
+<entry key="previewUnfilledSpaceForCheckMode">A3;Unfilled space (check-mode only)</entry>
+<entry key="enableCheckInfoTooltip">A4;Enable CheckInfo tooltip (check-mode only)</entry>
+
+<entry key="randomChooserMaxHistory">B0;Limit Of The Random Parts History</entry>
+
+</properties>
index b0d52f2..ff01ef2 100644 (file)
@@ -1,77 +1,78 @@
-<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">\r
-<properties>\r
-<comment>appConfig.xml</comment>\r
-<!--  だれか翻訳助けて Could someone please translate this.-->\r
-\r
-<entry key="title">アプリケーションの設定</entry>\r
-<entry key="btn.apply">更新</entry>\r
-<entry key="btn.cancel">キャンセル</entry>\r
-<entry key="chk.askForCharactersDir">起動時にデータフォルダを選択する.</entry>\r
-<entry key="column.key">プロパティ名</entry>\r
-<entry key="column.value">設定値</entry>\r
-<entry key="column.key.width">200</entry>\r
-<entry key="column.value.width">100</entry>\r
-<entry key="confirm.close.caption">確認</entry>\r
-<entry key="confirm.close">編集を破棄しますか?</entry>\r
-<entry key="error.caption">エラー</entry>\r
-<entry key="error.message">不備があります。修正してください。</entry>\r
-<entry key="caution">設定を変更した場合、アプリケーションの再起動が必要です。</entry>\r
-<entry key="table.caption">設定</entry>\r
-\r
-<entry key="btn.setupLocalization">言語のカスタマイズ</entry>\r
-<entry key="setupLocalization"><![CDATA[言語リソースを展開します。\r
-既にファイルが存在する場合は上書きされます。]]></entry>\r
-<entry key="confirm.setupLocalization.caption">確認</entry>\r
-\r
-<entry key="compressionQuality">01;JPEG圧縮時のクオリティ(1が最大、0.1が最小)</entry>\r
-<entry key="enablePNGSupportForWindows">02;クリップボードの透過サポートを有効にする.(Windows/OSX)</entry>\r
-<entry key="zipNameEncoding">03;ZIPファイルに格納されているファイル名のエンコーディング(csWindows31Jが標準)</entry>\r
-<entry key="partsColorGroupPattern">04;パーツ名からカラーグループを判定するパターン(正規表現)(@がカラーグループ名の場所になります.)</entry>\r
-<entry key="enableAutoShrinkPanel">05;自動的にパーツ選択パネルを縮小する.</entry>\r
-\r
-<entry key="mainFrameMaxWidth">10;プレビューの初期表示の最大幅</entry>\r
-<entry key="mainFrameMaxHeight">11;プレビューの初期表示の最大高さ</entry>\r
-<entry key="enableRenderingHints">12;レンダリングヒントを使用する</entry>\r
-<entry key="enableInterpolationBicubic">13;拡大時にバイキュービック方式による最適化を使用する.</entry>\r
-<entry key="renderingOptimizeThresholdForNormal">14;表示最適化を適用するズームの閾値(通常モード)(0は常に無効)</entry>\r
-<entry key="renderingOptimizeThresholdForCheck">15;表示最適化を適用するズームの閾値(チェックモード)(0は常に無効)</entry>\r
-<entry key="predefinedZoomRanges">16;ズーム倍率の選択候補(カンマ区切り)</entry>\r
-<entry key="enableZoomPanel">17;ズームパネルを表示する.</entry>\r
-<entry key="zoomPanelActivationArea">18;ズームパネルをアクティブにする範囲(0で常に無効)</entry>\r
-<entry key="wheelScrollUnit">19;ホイールによるスクロールの単位</entry>\r
-<entry key="enableOffscreenWallpaper">1A;壁紙をオフスクリーンで描画する.</entry>\r
-<entry key="offscreenWallpaperSize">1B;オフスクリーンの既定サイズ</entry>\r
-\r
-<entry key="enableAutoColorChange">20;カラー変更時、自動的にプレビューに適用する.</entry>\r
-<entry key="notDisableLayerTab">21;カラーダイアログで存在しないレイヤーをディセーブルにしない.</entry>\r
-\r
-<entry key="enableDirWatch">31;フォルダ監視の有効・無効</entry>\r
-<entry key="disableWatchDirIfNotWritable">32;フォルダに書き込み権限がない場合は監視しない</entry>\r
-<entry key="dirWatchInterval">33;フォルダの監視間隔(mSec)</entry>\r
-<entry key="noRemoveLog">34;正常時でもログを終了時に消去しない。</entry>\r
-<entry key="purgeLogDays">35;起動時に古いログを消去するまでの日数。(0の場合は削除しない)</entry>\r
-<entry key="informationDialogOpenMethod">36;情報ダイアログのアクションを「開く」にする。(false時は「編集」)</entry>\r
-\r
-<entry key="selectedItemBgColor">50;アイテム選択行(フォーカス行)の背景色</entry>\r
-<entry key="exportPresetWarningsForegroundColor">51;パーツセットのエクスポート時の警告色</entry>\r
-<entry key="checkedItemBgColor">52;アイテム選択(チェック行)の背景色</entry>\r
-<entry key="sampleImageBgColor">53;サンプルピクチャの背景色</entry>\r
-<entry key="defaultImageBgColor">54;プレビューの背景色(デフォルト)</entry>\r
-<entry key="invalidBgColor">55;不正行の背景色</entry>\r
-<entry key="gridColor">56;グリッド(罫線)の色</entry>\r
-<entry key="authorEditConflictBgColor">57;パーツ作者入力で複数作者選択時の入力ボックスの背景色</entry>\r
-<entry key="selectPanelTitleColor">58;パーツ選択パネルのホバー色</entry>\r
-<entry key="defaultFontSize">59;デフォルトのフォントサイズ</entry>\r
-\r
-<entry key="jarTransferBufferSize">90;JARファイル用バッファサイズ</entry>\r
-<entry key="fileTransferBufferSize">91;ファイル転送用バッファサイズ</entry>\r
-\r
-<entry key="drawGridMask">A0;グリッドを描画する確認モードのビットマスク(0-3, 0は無効にする場合)</entry>\r
-<entry key="previewGridColor">A1;プレビュー画面のグリッドカラー(ARGB)</entry>\r
-<entry key="previewGridSize">A2;プレビュー画面のグリッドサイズ</entry>\r
-<entry key="previewUnfilledSpaceForCheckMode">A3;チェックモード時の余白</entry>\r
-<entry key="enableCheckInfoTooltip">A4;チェックモードの情報ツールチップの表示有無</entry>\r
-\r
-<entry key="randomChooserMaxHistory">B0;パーツのランダム選択の最大履歴数</entry>\r
-\r
-</properties>\r
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+<comment>appConfig.xml</comment>
+<!--  だれか翻訳助けて Could someone please translate this.-->
+
+<entry key="title">アプリケーションの設定</entry>
+<entry key="btn.apply">更新</entry>
+<entry key="btn.cancel">キャンセル</entry>
+<entry key="chk.askForCharactersDir">起動時にデータフォルダを選択する.</entry>
+<entry key="column.key">プロパティ名</entry>
+<entry key="column.value">設定値</entry>
+<entry key="column.key.width">200</entry>
+<entry key="column.value.width">100</entry>
+<entry key="confirm.close.caption">確認</entry>
+<entry key="confirm.close">編集を破棄しますか?</entry>
+<entry key="error.caption">エラー</entry>
+<entry key="error.message">不備があります。修正してください。</entry>
+<entry key="caution">設定を変更した場合、アプリケーションの再起動が必要です。</entry>
+<entry key="table.caption">設定</entry>
+
+<entry key="btn.setupLocalization">言語のカスタマイズ</entry>
+<entry key="setupLocalization"><![CDATA[言語リソースを展開します。
+既にファイルが存在する場合は上書きされます。]]></entry>
+<entry key="confirm.setupLocalization.caption">確認</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 key="partsColorGroupPattern">04;パーツ名からカラーグループを判定するパターン(正規表現)(@がカラーグループ名の場所になります.)</entry>
+<entry key="enableAutoShrinkPanel">05;自動的にパーツ選択パネルを縮小する.</entry>
+
+<entry key="mainFrameMaxWidth">10;プレビューの初期表示の最大幅</entry>
+<entry key="mainFrameMaxHeight">11;プレビューの初期表示の最大高さ</entry>
+<entry key="enableRenderingHints">12;レンダリングヒントを使用する</entry>
+<entry key="enableInterpolationBicubic">13;拡大時にバイキュービック方式による最適化を使用する.</entry>
+<entry key="renderingOptimizeThresholdForNormal">14;表示最適化を適用するズームの閾値(通常モード)(0は常に無効)</entry>
+<entry key="renderingOptimizeThresholdForCheck">15;表示最適化を適用するズームの閾値(チェックモード)(0は常に無効)</entry>
+<entry key="predefinedZoomRanges">16;ズーム倍率の選択候補(カンマ区切り)</entry>
+<entry key="enableZoomPanel">17;ズームパネルを表示する.</entry>
+<entry key="zoomPanelActivationArea">18;ズームパネルをアクティブにする範囲(0で常に無効)</entry>
+<entry key="wheelScrollUnit">19;ホイールによるスクロールの単位</entry>
+<entry key="enableOffscreenWallpaper">1A;壁紙をオフスクリーンで描画する.</entry>
+<entry key="offscreenWallpaperSize">1B;オフスクリーンの既定サイズ</entry>
+
+<entry key="enableAutoColorChange">20;カラー変更時、自動的にプレビューに適用する.</entry>
+<entry key="notDisableLayerTab">21;カラーダイアログで存在しないレイヤーをディセーブルにしない.</entry>
+
+<entry key="enableDirWatch">31;フォルダ監視の有効・無効</entry>
+<entry key="disableWatchDirIfNotWritable">32;フォルダに書き込み権限がない場合は監視しない</entry>
+<entry key="dirWatchInterval">33;フォルダの監視間隔(mSec)</entry>
+<entry key="noRemoveLog">34;正常時でもログを終了時に消去しない。</entry>
+<entry key="purgeLogDays">35;起動時に古いログを消去するまでの日数。(0の場合は削除しない)</entry>
+<entry key="informationDialogOpenMethod">36;情報ダイアログのアクションを「開く」にする。(false時は「編集」)</entry>
+
+<entry key="selectedItemBgColor">50;アイテム選択行(フォーカス行)の背景色</entry>
+<entry key="exportPresetWarningsForegroundColor">51;パーツセットのエクスポート時の警告色</entry>
+<entry key="checkedItemBgColor">52;アイテム選択(チェック行)の背景色</entry>
+<entry key="sampleImageBgColor">53;サンプルピクチャの背景色</entry>
+<entry key="defaultImageBgColor">54;プレビューの背景色(デフォルト)</entry>
+<entry key="invalidBgColor">55;不正行の背景色</entry>
+<entry key="gridColor">56;グリッド(罫線)の色</entry>
+<entry key="authorEditConflictBgColor">57;パーツ作者入力で複数作者選択時の入力ボックスの背景色</entry>
+<entry key="selectPanelTitleColor">58;パーツ選択パネルのホバー色</entry>
+<entry key="defaultFontSize">59;デフォルトのフォントサイズ</entry>
+<entry key="fontPriority">5a;優先するフォントファミリー名(カンマ区切り)</entry>
+
+<entry key="jarTransferBufferSize">90;JARファイル用バッファサイズ</entry>
+<entry key="fileTransferBufferSize">91;ファイル転送用バッファサイズ</entry>
+
+<entry key="drawGridMask">A0;グリッドを描画する確認モードのビットマスク(0-3, 0は無効にする場合)</entry>
+<entry key="previewGridColor">A1;プレビュー画面のグリッドカラー(ARGB)</entry>
+<entry key="previewGridSize">A2;プレビュー画面のグリッドサイズ</entry>
+<entry key="previewUnfilledSpaceForCheckMode">A3;チェックモード時の余白</entry>
+<entry key="enableCheckInfoTooltip">A4;チェックモードの情報ツールチップの表示有無</entry>
+
+<entry key="randomChooserMaxHistory">B0;パーツのランダム選択の最大履歴数</entry>
+
+</properties>
index babd4d2..457371f 100644 (file)
-package charactermanaj;\r
-\r
-import java.awt.Font;\r
-import java.io.File;\r
-import java.lang.Thread.UncaughtExceptionHandler;\r
-import java.lang.reflect.Method;\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-\r
-import javax.management.JMException;\r
-import javax.swing.JOptionPane;\r
-import javax.swing.SwingUtilities;\r
-import javax.swing.UIDefaults;\r
-import javax.swing.UIManager;\r
-import javax.swing.plaf.FontUIResource;\r
-\r
-import charactermanaj.clipboardSupport.ImageSelection;\r
-import charactermanaj.graphics.io.ImageCacheMBeanImpl;\r
-import charactermanaj.model.AppConfig;\r
-import charactermanaj.model.util.StartupSupport;\r
-import charactermanaj.ui.MainFrame;\r
-import charactermanaj.ui.ProfileListManager;\r
-import charactermanaj.ui.SelectCharatersDirDialog;\r
-import charactermanaj.util.AWTExceptionLoggingHandler;\r
-import charactermanaj.util.ApplicationLoggerConfigurator;\r
-import charactermanaj.util.ConfigurationDirUtilities;\r
-import charactermanaj.util.DirectoryConfig;\r
-import charactermanaj.util.ErrorMessageHelper;\r
-import charactermanaj.util.JavaVersionUtils;\r
-\r
-/**\r
- * エントリポイント用クラス\r
- * \r
- * @author seraphy\r
- */\r
-public final class Main implements Runnable {\r
-\r
-       /**\r
-        * ロガー.<br>\r
-        */\r
-       private static final Logger logger = Logger.getLogger(Main.class.getName());\r
-\r
-       /**\r
-        * Mac OS Xであるか?\r
-        */\r
-       private static final boolean isMacOSX;\r
-\r
-       /**\r
-        * Linuxであるか?\r
-        */\r
-       private static final boolean isLinux;\r
-\r
-       /**\r
-        * クラスイニシャライザ.<br>\r
-        * 実行環境に関する定数を取得・設定する.<br>\r
-        */\r
-       static {\r
-               // Mac OS Xでの実行判定\r
-               // システムプロパティos.nameは、すべてのJVM実装に存在する.\r
-               // 基本ディレクトリの位置の決定に使うため、\r
-               // なによりも、まず、これを判定しないとダメ.(順序が重要)\r
-               String lcOS = System.getProperty("os.name").toLowerCase();\r
-               isMacOSX = lcOS.startsWith("mac os x");\r
-               isLinux = lcOS.indexOf("linux") >= 0;\r
-       }\r
-\r
-       /**\r
-        * ロガーの初期化.<br>\r
-        * 失敗しても継続する.<br>\r
-        */\r
-       private static void initLogger() {\r
-               try {\r
-                       // ロガーの準備\r
-\r
-                       // ローカルファイルシステム上のユーザ定義ディレクトリから\r
-                       // ログの設定を読み取る.(OSにより、設定ファイルの位置が異なることに注意)\r
-                       ApplicationLoggerConfigurator.configure();\r
-\r
-                       if (JavaVersionUtils.getJavaVersion() >= 1.7) {\r
-                               // java7以降は、sun.awt.exception.handlerが使えないので、\r
-                               // EDTスレッドで未処理例外ハンドラを明示的に設定する.\r
-                               final AWTExceptionLoggingHandler logHandler = new AWTExceptionLoggingHandler();\r
-                               SwingUtilities.invokeLater(new Runnable() {\r
-                                       public void run() {\r
-                                               final UncaughtExceptionHandler handler = Thread\r
-                                                               .getDefaultUncaughtExceptionHandler();\r
-                                               Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {\r
-                                                       public void uncaughtException(Thread t, Throwable ex) {\r
-                                                               logHandler.handle(ex);\r
-                                                               if (handler != null) {\r
-                                                                       handler.uncaughtException(t, ex);\r
-                                                               }\r
-                                                       }\r
-                                               });\r
-                                       }\r
-                               });\r
-\r
-                       } else {\r
-                               // SwingのEDT内の例外ハンドラの設定 (ロギングするだけ)\r
-                               // (ただし、unofficial trickである.)\r
-                               System.setProperty("sun.awt.exception.handler",\r
-                                               AWTExceptionLoggingHandler.class.getName());\r
-                       }\r
-\r
-               } catch (Throwable ex) {\r
-                       // ロガーの準備に失敗した場合はロガーがないかもなので\r
-                       // コンソールに出力する.\r
-                       ex.printStackTrace();\r
-                       logger.log(Level.SEVERE, "logger initiation failed. " + ex, ex);\r
-               }\r
-       }\r
-\r
-\r
-       /**\r
-        * UIをセットアップする.\r
-        * \r
-        * @throws Exception\r
-        *             いろいろな失敗\r
-        */\r
-       private static void setupUIManager(AppConfig appConfig) throws Exception {\r
-               // System.setProperty("swing.aatext", "true");\r
-               // System.setProperty("awt.useSystemAAFontSettings", "on");\r
-\r
-               if (isMacOSX()) {\r
-                       // MacOSXであれば、スクリーンメニューを有効化\r
-                       System.setProperty("apple.laf.useScreenMenuBar", "true");\r
-                       System.setProperty(\r
-                                       "com.apple.mrj.application.apple.menu.about.name",\r
-                                       "CharacterManaJ");\r
-\r
-                       // Java7以降であればノーマライズをセットアップする.\r
-                       if (JavaVersionUtils.getJavaVersion() >= 1.7) {\r
-                               charactermanaj.util.FileNameNormalizer.setupNFCNormalizer();\r
-                       }\r
-               }\r
-\r
-               // 実行プラットフォームのネイティブな外観にする.\r
-               UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());\r
-\r
-               // JSpliderのvalueを非表示 (GTKではデフォルトで有効のため)\r
-               UIManager.put("Slider.paintValue", Boolean.FALSE);\r
-\r
-               // フォントサイズの変更\r
-               int fontSize = appConfig.getDefaultFontSize();\r
-               for (java.util.Map.Entry<?, ?> entry : UIManager.getDefaults()\r
-                               .entrySet()) {\r
-                       Object key = entry.getKey();\r
-                       if (key.toString().toLowerCase().endsWith("font")) {\r
-                               Object val = UIManager.get(key);\r
-                               if (val instanceof FontUIResource) {\r
-                                       FontUIResource fontUIResource = (FontUIResource) val;\r
-                                       fontUIResource = new FontUIResource(\r
-                                                       fontUIResource.getName(),\r
-                                                       fontUIResource.getStyle(), fontSize);\r
-                                       UIManager.put(entry.getKey(), fontUIResource);\r
-                               }\r
-                       }\r
-               }\r
-\r
-               // JTextAreaの既定フォントを固定幅から、標準テキストと同じフォントに変更.\r
-               // (Linuxなどで固定幅フォントでは日本語フォントを持っていないため。)\r
-               Object textFieldFontUI = UIManager.get("TextField.font");\r
-               if (textFieldFontUI == null) {\r
-                       // もし無ければダイアログUIフォントを使う.(これは日本語をサポートするであろう。)\r
-                       textFieldFontUI = new UIDefaults.ProxyLazyValue(\r
-                                       "javax.swing.plaf.FontUIResource", null, new Object[] {\r
-                                                       "dialog", Integer.valueOf(Font.PLAIN),\r
-                                                       Integer.valueOf(fontSize) });\r
-               }\r
-               UIManager.put("TextArea.font", textFieldFontUI);\r
-       }\r
-\r
-       /**\r
-        * 初期処理およびメインフレームを構築する.<br>\r
-        * SwingのUIスレッドで実行される.<br>\r
-        */\r
-       public void run() {\r
-               try {\r
-                       // アプリケーション設定の読み込み\r
-                       AppConfig appConfig = AppConfig.getInstance();\r
-                       appConfig.loadConfig();\r
-\r
-                       // UIManagerのセットアップ.\r
-                       try {\r
-                               setupUIManager(appConfig);\r
-\r
-                       } catch (Exception ex) {\r
-                               // UIManagerの設定に失敗した場合はログに書いて継続する.\r
-                               ex.printStackTrace();\r
-                               logger.log(Level.WARNING, "UIManager setup failed.", ex);\r
-                       }\r
-\r
-                       // クリップボードサポートの設定\r
-                       if (!ImageSelection.setupSystemFlavorMap()) {\r
-                               logger.log(Level.WARNING,\r
-                                               "failed to set the clipboard-support.");\r
-                       }\r
-\r
-                       // LANG, またはLC_CTYPEが設定されていない場合はエラーを表示する\r
-                       // OSXのJava7(Oracle)を実行する場合、環境変数LANGまたはLC_CTYPEに正しくファイル名の文字コードが設定されていないと\r
-                       // ファイル名を正しく取り扱えず文字化けするため、実行前に確認し警告を表示する。\r
-                       // ただし、この挙動はJava7u60では修正されているので、それ以降であれば除外する.\r
-                       int[] versions = JavaVersionUtils.getJavaVersions();\r
-                       if (isMacOSX()\r
-                                       && (versions[0] == 1 && versions[1] == 7 && versions[3] < 60)) {\r
-                               String lang = System.getenv("LANG");\r
-                               String lcctype = System.getenv("LC_CTYPE");\r
-                               if ((lang == null || lang.trim().length() == 0)\r
-                                               && (lcctype == null || lcctype.trim().length() == 0)) {\r
-                                       JOptionPane\r
-                                                       .showMessageDialog(\r
-                                                                       null,\r
-                                                                       "\"LANG\" or \"LC_CTYPE\" environment variable must be set.",\r
-                                                                       "Configuration Error",\r
-                                                                       JOptionPane.ERROR_MESSAGE);\r
-                               }\r
-                       }\r
-\r
-                       // 起動時のシステムプロパティでキャラクターディレクトリが指定されていて実在すれば、それを優先する.\r
-                       File currentCharacterDir = null;\r
-                       String charactersDir = System.getProperty("charactersDir");\r
-                       if (charactersDir != null && charactersDir.length() > 0) {\r
-                               File charsDir = new File(charactersDir);\r
-                               if (charsDir.exists() && charsDir.isDirectory()) {\r
-                                       currentCharacterDir = charsDir;\r
-                               }\r
-                       }\r
-\r
-                       if (currentCharacterDir == null) {\r
-                               // キャラクターセットディレクトリの選択\r
-                               File defaultCharacterDir = ConfigurationDirUtilities\r
-                                               .getDefaultCharactersDir();\r
-                               currentCharacterDir = SelectCharatersDirDialog\r
-                                               .getCharacterDir(defaultCharacterDir);\r
-                               if (currentCharacterDir == null) {\r
-                                       // キャンセルされたので終了する.\r
-                                       logger.info("luncher canceled.");\r
-                                       return;\r
-                               }\r
-                       }\r
-\r
-                       // キャラクターデータフォルダの設定\r
-                       DirectoryConfig.getInstance().setCharactersDir(currentCharacterDir);\r
-\r
-                       // スタートアップ時の初期化\r
-                       StartupSupport.getInstance().doStartup();\r
-\r
-                       // デフォルトのプロファイルを開く.\r
-                       // (最後に使ったプロファイルがあれば、それが開かれる.)\r
-                       MainFrame mainFrame = ProfileListManager.openDefaultProfile();\r
-                       if (isMacOSX()) {\r
-                               try {\r
-                                       // MacOSXであればスクリーンメニューからのイベントをハンドルできるようにする.\r
-                                       // OSXにしか存在しないクラスを利用するためリフレクションとしている.\r
-                                       // ただしJDKによっては、Apple Java Extensionsがないことも予想されるので、\r
-                                       // その場合はエラーにしない。\r
-                                       Class<?> clz = Class\r
-                                                       .forName("charactermanaj.ui.MainFramePartialForMacOSX");\r
-                                       Method mtd = clz.getMethod("setupScreenMenu",\r
-                                                       MainFrame.class);\r
-                                       mtd.invoke(null, mainFrame);\r
-\r
-                               } catch (Throwable ex) {\r
-                                       logger.log(Level.CONFIG,\r
-                                                       "The Apple Java Extensions is not found.", ex);\r
-                               }\r
-                       }\r
-\r
-                       // 表示(および位置あわせ)\r
-                       mainFrame.showMainFrame();\r
-\r
-               } catch (Throwable ex) {\r
-                       // なんらかの致命的な初期化エラーがあった場合、ログとコンソールに表示\r
-                       // ダイアログが表示されるかどうかは状況次第.\r
-                       ex.printStackTrace();\r
-                       logger.log(Level.SEVERE, "Application initiation failed.", ex);\r
-                       ErrorMessageHelper.showErrorDialog(null, ex);\r
-\r
-                       // メインフレームを破棄します.\r
-                       MainFrame.closeAllProfiles();\r
-               }\r
-       }\r
-\r
-       /**\r
-        * エントリポイント.<br>\r
-        * 最初のメインフレームを開いたときにMac OS Xであればスクリーンメニューの登録も行う.<br>\r
-        * \r
-        * @param args\r
-        *            引数(未使用)\r
-        */\r
-       public static void main(String[] args) {\r
-               // ロガー等の初期化\r
-               initLogger();\r
-\r
-               // MBeanのセットアップ\r
-               try {\r
-                       ImageCacheMBeanImpl.setupMBean();\r
-\r
-               } catch (JMException ex) {\r
-                       // 失敗しても無視して継続する.\r
-                       logger.log(Level.SEVERE, ex.getMessage(), ex);\r
-               }\r
-\r
-               // フレームの生成等は、SwingのEDTで実行する.\r
-               SwingUtilities.invokeLater(new Main());\r
-       }\r
-\r
-       /**\r
-        * Mac OS Xで動作しているか?\r
-        * \r
-        * @return Max OS X上であればtrue\r
-        */\r
-       public static boolean isMacOSX() {\r
-               return isMacOSX;\r
-       }\r
-\r
-       /**\r
-        * Mac OS X、もしくはlinuxで動作しているか?\r
-        * \r
-        * @return Mac OS X、もしくはlinuxで動作していればtrue\r
-        */\r
-       public static boolean isLinuxOrMacOSX() {\r
-               return isLinux || isMacOSX;\r
-       }\r
-}\r
+package charactermanaj;
+
+import java.awt.GraphicsEnvironment;
+import java.io.File;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.lang.reflect.Method;
+import java.util.Locale;
+import java.util.TreeSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.management.JMException;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.plaf.FontUIResource;
+
+import charactermanaj.clipboardSupport.ImageSelection;
+import charactermanaj.graphics.io.ImageCacheMBeanImpl;
+import charactermanaj.model.AppConfig;
+import charactermanaj.model.util.StartupSupport;
+import charactermanaj.ui.MainFrame;
+import charactermanaj.ui.ProfileListManager;
+import charactermanaj.ui.SelectCharatersDirDialog;
+import charactermanaj.util.AWTExceptionLoggingHandler;
+import charactermanaj.util.ApplicationLoggerConfigurator;
+import charactermanaj.util.ConfigurationDirUtilities;
+import charactermanaj.util.DirectoryConfig;
+import charactermanaj.util.ErrorMessageHelper;
+import charactermanaj.util.JavaVersionUtils;
+
+/**
+ * エントリポイント用クラス
+ * 
+ * @author seraphy
+ */
+public final class Main implements Runnable {
+
+       /**
+        * ロガー.<br>
+        */
+       private static final Logger logger = Logger.getLogger(Main.class.getName());
+
+       /**
+        * Mac OS Xであるか?
+        */
+       private static final boolean isMacOSX;
+
+       /**
+        * Linuxであるか?
+        */
+       private static final boolean isLinux;
+
+       /**
+        * クラスイニシャライザ.<br>
+        * 実行環境に関する定数を取得・設定する.<br>
+        */
+       static {
+               // Mac OS Xでの実行判定
+               // システムプロパティos.nameは、すべてのJVM実装に存在する.
+               // 基本ディレクトリの位置の決定に使うため、
+               // なによりも、まず、これを判定しないとダメ.(順序が重要)
+               String lcOS = System.getProperty("os.name").toLowerCase();
+               isMacOSX = lcOS.startsWith("mac os x");
+               isLinux = lcOS.indexOf("linux") >= 0;
+       }
+
+       /**
+        * ロガーの初期化.<br>
+        * 失敗しても継続する.<br>
+        */
+       private static void initLogger() {
+               try {
+                       // ロガーの準備
+
+                       // ローカルファイルシステム上のユーザ定義ディレクトリから
+                       // ログの設定を読み取る.(OSにより、設定ファイルの位置が異なることに注意)
+                       ApplicationLoggerConfigurator.configure();
+
+                       if (JavaVersionUtils.getJavaVersion() >= 1.7) {
+                               // java7以降は、sun.awt.exception.handlerが使えないので、
+                               // EDTスレッドで未処理例外ハンドラを明示的に設定する.
+                               final AWTExceptionLoggingHandler logHandler = new AWTExceptionLoggingHandler();
+                               SwingUtilities.invokeLater(new Runnable() {
+                                       public void run() {
+                                               final UncaughtExceptionHandler handler = Thread
+                                                               .getDefaultUncaughtExceptionHandler();
+                                               Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
+                                                       public void uncaughtException(Thread t, Throwable ex) {
+                                                               logHandler.handle(ex);
+                                                               if (handler != null) {
+                                                                       handler.uncaughtException(t, ex);
+                                                               }
+                                                       }
+                                               });
+                                       }
+                               });
+
+                       } else {
+                               // SwingのEDT内の例外ハンドラの設定 (ロギングするだけ)
+                               // (ただし、unofficial trickである.)
+                               System.setProperty("sun.awt.exception.handler",
+                                               AWTExceptionLoggingHandler.class.getName());
+                       }
+
+               } catch (Throwable ex) {
+                       // ロガーの準備に失敗した場合はロガーがないかもなので
+                       // コンソールに出力する.
+                       ex.printStackTrace();
+                       logger.log(Level.SEVERE, "logger initiation failed. " + ex, ex);
+               }
+       }
+
+
+       /**
+        * UIをセットアップする.
+        * 
+        * @throws Exception
+        *             いろいろな失敗
+        */
+       private static void setupUIManager(AppConfig appConfig) throws Exception {
+               // System.setProperty("swing.aatext", "true");
+               // System.setProperty("awt.useSystemAAFontSettings", "on");
+
+               if (isMacOSX()) {
+                       // MacOSXであれば、スクリーンメニューを有効化
+                       System.setProperty("apple.laf.useScreenMenuBar", "true");
+                       System.setProperty(
+                                       "com.apple.mrj.application.apple.menu.about.name",
+                                       "CharacterManaJ");
+
+                       // Java7以降であればノーマライズをセットアップする.
+                       if (JavaVersionUtils.getJavaVersion() >= 1.7) {
+                               charactermanaj.util.FileNameNormalizer.setupNFCNormalizer();
+                       }
+               }
+
+               // 実行プラットフォームのネイティブな外観にする.
+               UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+
+               // JSpliderのvalueを非表示 (GTKではデフォルトで有効のため)
+               UIManager.put("Slider.paintValue", Boolean.FALSE);
+
+
+               // 優先するフォントファミリ中の実在するフォントファミリのセット(大文字小文字の区別なし)
+               TreeSet<String> availablePriorityFontSets = new TreeSet<String>(
+                               String.CASE_INSENSITIVE_ORDER);
+               
+               // 優先するフォントファミリの実在チェックと、もっとも優先されるフォントファミリの確定
+               String selectedFontFamily = null;
+               String fontPriorityStr = appConfig.getFontPriority();
+               if (fontPriorityStr.trim().length() > 0) {
+                       String[] fontPriority = fontPriorityStr.split(",");
+                       for (String availableFontFamily : GraphicsEnvironment
+                                       .getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.ENGLISH)) {
+                               for (String fontFamily : fontPriority) {
+                                       fontFamily = fontFamily.trim();
+                                       if (fontFamily.length() > 0) {
+                                               if (availableFontFamily.equalsIgnoreCase(fontFamily)) {
+                                                       if (selectedFontFamily == null) {
+                                                               // 最初に見つかった優先フォント
+                                                               selectedFontFamily = availableFontFamily;
+                                                       }
+                                                       availablePriorityFontSets.add(fontFamily);
+                                               }
+                                       }
+                               }
+                       }
+                       if (selectedFontFamily == null) {
+                               // フォールバック用フォントとして「Dialog」を用いる.
+                               // 仮想フォントファミリである「Dialog」は日本語も表示可能である.
+                               selectedFontFamily = "Dialog";
+                       }
+               }
+               
+               // デフォルトのフォントサイズ、0以下の場合はシステム標準のまま
+               int defFontSize = appConfig.getDefaultFontSize();
+
+               // UIデフォルトのフォント設定で、優先フォント以外のフォントファミリが指定されているものを
+               // すべて最優先フォントファミリに設定する.
+               // また、設定されたフォントサイズが0よりも大きければ、そのサイズに設定する.
+               for (java.util.Map.Entry<?, ?> entry : UIManager.getDefaults()
+                               .entrySet()) {
+                       Object key = entry.getKey();
+                       Object val = UIManager.get(key);
+                       if (val instanceof FontUIResource) {
+                               FontUIResource fontUIResource = (FontUIResource) val;
+                               int fontSize = fontUIResource.getSize();
+                               String fontFamily = fontUIResource.getFamily();
+                               
+                               if (defFontSize > 0) {
+                                       fontSize = defFontSize;
+                               }
+
+                               if (selectedFontFamily != null
+                                               && !availablePriorityFontSets.contains(fontFamily)) {
+                                       // 現在のデフォルトUIに指定された優先フォント以外が設定されており、
+                                       // 且つ、優先フォントの指定があれば、優先フォントに差し替える.
+                                       if (logger.isLoggable(Level.FINE)) {
+                                               logger.log(Level.FINE, "UIDefaultFont: " + key +
+                                                               "= " + fontFamily + " -> " + selectedFontFamily);
+                                       }
+                                       fontFamily = selectedFontFamily;
+                               }
+                               
+                               fontUIResource = new FontUIResource(fontFamily,
+                                               fontUIResource.getStyle(), fontSize);
+                               UIManager.put(entry.getKey(), fontUIResource);
+                       }
+               }
+       }
+
+       /**
+        * 初期処理およびメインフレームを構築する.<br>
+        * SwingのUIスレッドで実行される.<br>
+        */
+       public void run() {
+               try {
+                       // アプリケーション設定の読み込み
+                       AppConfig appConfig = AppConfig.getInstance();
+                       appConfig.loadConfig();
+
+                       // UIManagerのセットアップ.
+                       try {
+                               setupUIManager(appConfig);
+
+                       } catch (Exception ex) {
+                               // UIManagerの設定に失敗した場合はログに書いて継続する.
+                               ex.printStackTrace();
+                               logger.log(Level.WARNING, "UIManager setup failed.", ex);
+                       }
+
+                       // クリップボードサポートの設定
+                       if (!ImageSelection.setupSystemFlavorMap()) {
+                               logger.log(Level.WARNING,
+                                               "failed to set the clipboard-support.");
+                       }
+
+                       // LANG, またはLC_CTYPEが設定されていない場合はエラーを表示する
+                       // OSXのJava7(Oracle)を実行する場合、環境変数LANGまたはLC_CTYPEに正しくファイル名の文字コードが設定されていないと
+                       // ファイル名を正しく取り扱えず文字化けするため、実行前に確認し警告を表示する。
+                       // ただし、この挙動はJava7u60では修正されているので、それ以降であれば除外する.
+                       int[] versions = JavaVersionUtils.getJavaVersions();
+                       if (isMacOSX()
+                                       && (versions[0] == 1 && versions[1] == 7 && versions[3] < 60)) {
+                               String lang = System.getenv("LANG");
+                               String lcctype = System.getenv("LC_CTYPE");
+                               if ((lang == null || lang.trim().length() == 0)
+                                               && (lcctype == null || lcctype.trim().length() == 0)) {
+                                       JOptionPane
+                                                       .showMessageDialog(
+                                                                       null,
+                                                                       "\"LANG\" or \"LC_CTYPE\" environment variable must be set.",
+                                                                       "Configuration Error",
+                                                                       JOptionPane.ERROR_MESSAGE);
+                               }
+                       }
+
+                       // 起動時のシステムプロパティでキャラクターディレクトリが指定されていて実在すれば、それを優先する.
+                       File currentCharacterDir = null;
+                       String charactersDir = System.getProperty("charactersDir");
+                       if (charactersDir != null && charactersDir.length() > 0) {
+                               File charsDir = new File(charactersDir);
+                               if (charsDir.exists() && charsDir.isDirectory()) {
+                                       currentCharacterDir = charsDir;
+                               }
+                       }
+
+                       if (currentCharacterDir == null) {
+                               // キャラクターセットディレクトリの選択
+                               File defaultCharacterDir = ConfigurationDirUtilities
+                                               .getDefaultCharactersDir();
+                               currentCharacterDir = SelectCharatersDirDialog
+                                               .getCharacterDir(defaultCharacterDir);
+                               if (currentCharacterDir == null) {
+                                       // キャンセルされたので終了する.
+                                       logger.info("luncher canceled.");
+                                       return;
+                               }
+                       }
+
+                       // キャラクターデータフォルダの設定
+                       DirectoryConfig.getInstance().setCharactersDir(currentCharacterDir);
+
+                       // スタートアップ時の初期化
+                       StartupSupport.getInstance().doStartup();
+
+                       // デフォルトのプロファイルを開く.
+                       // (最後に使ったプロファイルがあれば、それが開かれる.)
+                       MainFrame mainFrame = ProfileListManager.openDefaultProfile();
+                       if (isMacOSX()) {
+                               try {
+                                       // MacOSXであればスクリーンメニューからのイベントをハンドルできるようにする.
+                                       // OSXにしか存在しないクラスを利用するためリフレクションとしている.
+                                       // ただしJDKによっては、Apple Java Extensionsがないことも予想されるので、
+                                       // その場合はエラーにしない。
+                                       Class<?> clz = Class
+                                                       .forName("charactermanaj.ui.MainFramePartialForMacOSX");
+                                       Method mtd = clz.getMethod("setupScreenMenu",
+                                                       MainFrame.class);
+                                       mtd.invoke(null, mainFrame);
+
+                               } catch (Throwable ex) {
+                                       logger.log(Level.CONFIG,
+                                                       "The Apple Java Extensions is not found.", ex);
+                               }
+                       }
+
+                       // 表示(および位置あわせ)
+                       mainFrame.showMainFrame();
+
+               } catch (Throwable ex) {
+                       // なんらかの致命的な初期化エラーがあった場合、ログとコンソールに表示
+                       // ダイアログが表示されるかどうかは状況次第.
+                       ex.printStackTrace();
+                       logger.log(Level.SEVERE, "Application initiation failed.", ex);
+                       ErrorMessageHelper.showErrorDialog(null, ex);
+
+                       // メインフレームを破棄します.
+                       MainFrame.closeAllProfiles();
+               }
+       }
+
+       /**
+        * エントリポイント.<br>
+        * 最初のメインフレームを開いたときにMac OS Xであればスクリーンメニューの登録も行う.<br>
+        * 
+        * @param args
+        *            引数(未使用)
+        */
+       public static void main(String[] args) {
+               // ロガー等の初期化
+               initLogger();
+
+               // MBeanのセットアップ
+               try {
+                       ImageCacheMBeanImpl.setupMBean();
+
+               } catch (JMException ex) {
+                       // 失敗しても無視して継続する.
+                       logger.log(Level.SEVERE, ex.getMessage(), ex);
+               }
+
+               // フレームの生成等は、SwingのEDTで実行する.
+               SwingUtilities.invokeLater(new Main());
+       }
+
+       /**
+        * Mac OS Xで動作しているか?
+        * 
+        * @return Max OS X上であればtrue
+        */
+       public static boolean isMacOSX() {
+               return isMacOSX;
+       }
+
+       /**
+        * Mac OS X、もしくはlinuxで動作しているか?
+        * 
+        * @return Mac OS X、もしくはlinuxで動作していればtrue
+        */
+       public static boolean isLinuxOrMacOSX() {
+               return isLinux || isMacOSX;
+       }
+}
index 368f9ec..d8a1300 100644 (file)
-package charactermanaj.model;\r
-\r
-import java.awt.Color;\r
-import java.io.BufferedOutputStream;\r
-import java.io.File;\r
-import java.io.FileNotFoundException;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.net.URI;\r
-import java.net.URL;\r
-import java.nio.charset.Charset;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Properties;\r
-import java.util.Set;\r
-import java.util.logging.Level;\r
-import java.util.logging.Logger;\r
-import java.util.regex.Pattern;\r
-\r
-import charactermanaj.util.ApplicationLogHandler;\r
-import charactermanaj.util.BeanPropertiesUtilities;\r
-import charactermanaj.util.ConfigurationDirUtilities;\r
-\r
-/**\r
- * アプリケーションの全域にわたる設定.<br>\r
- * アプリケーション設定は、クラスパス上のリソース、コートベース直下のappConfig.xml、ユーザーごとのappConfig.xmlの順に読み込まれます\r
- * .<br>\r
- *\r
- * @author seraphy\r
- */\r
-public final class AppConfig {\r
-\r
-       /**\r
-        * アプリケーション設定ファイルの名前\r
-        */\r
-       private static final String CONFIG_NAME = "appConfig.xml";\r
-\r
-       /**\r
-        * 全ユーザー用キャラクターディレクトリのシステムプロパティのキー名.<br>\r
-        */\r
-       public static final String COMMON_CHARACTER_DIR_PROPERTY_NAME = "character.dir";\r
-\r
-       /**\r
-        * 開発用仕様バージョン番号\r
-        */\r
-       private static final String DEFAULT_SPECIFICATION_VERSION = "1.0";\r
-\r
-\r
-       /**\r
-        * ロガー\r
-        */\r
-       private static final Logger logger = Logger.getLogger(AppConfig.class.getName());\r
-\r
-\r
-       /**\r
-        * シングルトンインスタンス\r
-        */\r
-       private static final AppConfig singleton = new AppConfig();\r
-\r
-\r
-       /**\r
-        * インスタンスを取得する.\r
-        *\r
-        * @return インスタンス\r
-        */\r
-       public static AppConfig getInstance() {\r
-               return singleton;\r
-       }\r
-\r
-       /**\r
-        * プライベートコンストラクタ\r
-        */\r
-       private AppConfig() {\r
-               loadAppVersions();\r
-       }\r
-\r
-       private String implementationVersion;\r
-\r
-       private String specificationVersion;\r
-\r
-       /**\r
-        * 実装バージョンを取得する.<br>\r
-        * ビルドされたjarパッケージからバージョン情報を取得する.<br>\r
-        * クラスパスの実行からのバージョンは常に「develop」となる.<br>\r
-        *\r
-        * @return 実装バージョン\r
-        */\r
-       public String getImplementationVersion() {\r
-               return implementationVersion;\r
-       }\r
-\r
-       /**\r
-        * 仕様バージョンを取得する.<br>\r
-        * ビルドされたjarパッケージからバージョン情報を取得する.<br>\r
-        * クラスパスの実行からのバージョンは常に「develop」となる.<br>\r
-        *\r
-        * @return 仕様バージョン\r
-        */\r
-       public String getSpecificationVersion() {\r
-               return specificationVersion;\r
-       }\r
-\r
-       /**\r
-        * ビルドされたjarパッケージからバージョン情報を取得する.<br>\r
-        * クラスパスの実行からのバージョンは常に「develop」となる.<br>\r
-        */\r
-       private void loadAppVersions() {\r
-               Package pak = this.getClass().getPackage();\r
-               String implementationVersion = "develop";\r
-               String specificationVersion = DEFAULT_SPECIFICATION_VERSION;\r
-               if (pak != null) {\r
-                       String vInfo = pak.getImplementationVersion();\r
-                       if (vInfo != null && implementationVersion.trim().length() > 0) {\r
-                               implementationVersion = vInfo.trim();\r
-                       }\r
-                       String specVInfo = pak.getSpecificationVersion();\r
-                       if (specVInfo != null && specVInfo.trim().length() > 0) {\r
-                               specificationVersion = specVInfo.trim();\r
-                       }\r
-               }\r
-\r
-               this.implementationVersion = implementationVersion;\r
-               this.specificationVersion = specificationVersion;\r
-       }\r
-\r
-       /**\r
-        * 設定ファイルの読み込み順序で、読み込むべきURIのリストを返す.<br>\r
-        * <ul>\r
-        * <li>(1) リソース上の/appConfig.xml</li>\r
-        * <li>(2) appConfigFileシステムプロパティで指定されたファイル</li>\r
-        * <li>(3) コードベース下のappConfig.xml</li>\r
-        * <li>(4) アプリケーションデータ保存先のappConfig.xml</li>\r
-        * </ul>\r
-        * appConfigFileシステムプロパティがある場合は、(1)(2)の順。 <br>\r
-        * 指定がない場合は、(1)(3)(4)の順に読み取る.<br>\r
-        *\r
-        * @return 優先順位での設定ファイルの読み込み先URIのリスト\r
-        * @throws IOException\r
-        */\r
-       public List<URI> getCandidateURIs() throws IOException {\r
-               List<URI> uris = new ArrayList<URI>();\r
-               // リソース中の既定\r
-               uris.add(new File(getClass().getResource("/" + CONFIG_NAME).getPath())\r
-                               .toURI());\r
-\r
-               String specifiedAppConfig = System.getProperty("appConfigFile");\r
-               if (specifiedAppConfig != null) {\r
-                       // システムプロパティでappConfig.xmlを明示している場合は、それを読み込む。\r
-                       // (appConfigFileシステムプロパティが空の場合は、リソース埋め込みの既定の設定だけをよみこむ)\r
-                       if (specifiedAppConfig.trim().length() > 0) {\r
-                               File specifiedAppConfigFile = new File(specifiedAppConfig);\r
-                               uris.add(specifiedAppConfigFile.toURI());\r
-                       }\r
-\r
-               } else {\r
-                       // システムプロパティが指定されていない場合は、\r
-                       // コードベース、つぎにユーザーディレクトリの順で読み込む\r
-                       File codeBase = ConfigurationDirUtilities.getApplicationBaseDir();\r
-                       File userDataDir = ConfigurationDirUtilities.getUserDataDir();\r
-\r
-                       // システムプロパティて明示していない場合は、コードベースおよびユーザディレクトリを使用する.\r
-                       uris.add(new File(codeBase, CONFIG_NAME).getCanonicalFile().toURI());\r
-                       uris.add(new File(userDataDir, CONFIG_NAME).toURI());\r
-               }\r
-               return uris;\r
-       }\r
-\r
-       /**\r
-        * 保存先の試行順序ごとのファイルのリスト。\r
-        *\r
-        * @return 保存先(優先順)\r
-        */\r
-       public List<File> getPrioritySaveFileList() {\r
-               ArrayList<File> saveFiles = new ArrayList<File>();\r
-\r
-               String specifiedAppConfig = System.getProperty("appConfigFile");\r
-               if (specifiedAppConfig != null) {\r
-                       // システムプロパティでappConfig.xmlを明示している場合\r
-                       if (specifiedAppConfig.trim().length() > 0) {\r
-                               File specifiedAppConfigFile = new File(specifiedAppConfig);\r
-                               if (!specifiedAppConfigFile.exists()\r
-                                               || specifiedAppConfigFile.canWrite()) {\r
-                                       // まだ存在しないか、書き込み可能である場合のみ候補とする.\r
-                                       saveFiles.add(specifiedAppConfigFile);\r
-                               }\r
-                       }\r
-               } else {\r
-                       // システムプロパティappConfigFileがなければユーザディレクトリへ書き込む\r
-                       // ユーザディレクトリは常に候補とする.\r
-                       File userDataDir = ConfigurationDirUtilities.getUserDataDir();\r
-                       saveFiles.add(new File(userDataDir, CONFIG_NAME));\r
-               }\r
-\r
-               return saveFiles;\r
-       }\r
-\r
-       /**\r
-        * プロパティをロードする.<br>\r
-        * 存在しないか、読み取りに失敗した場合は、該当ファイルはスキップされる.<br>\r
-        */\r
-       public void loadConfig() {\r
-               Properties config = new Properties();\r
-               try {\r
-                       for (URI uri : getCandidateURIs()) {\r
-                               if (uri == null) {\r
-                                       continue; // リソースがない場合はnullになる\r
-                               }\r
-                               // ファイルの実在チェック (チェックできる場合のみ)\r
-                               if ("file".equals(uri.getScheme())) {\r
-                                       File file = new File(uri);\r
-                                       if (!file.exists()) {\r
-                                               logger.log(Level.CONFIG, "appConfig.xml is not found.:" + file);\r
-                                               continue;\r
-                                       }\r
-                               }\r
-                               // appConfig.xmlの読み込みを行う.\r
-                               // Properties#loadFromXML() はXMLからキーを読み取り、既存のキーに対して上書きする.\r
-                               // XMLに存在しないキーは読み込み前のままなので、繰り返し呼び出すことで「重ね合わせ」することができる.\r
-                               try {\r
-                                       URL resourceURL = uri.toURL();\r
-                                       InputStream is = resourceURL.openStream();\r
-                                       try {\r
-                                               config.loadFromXML(is);\r
-                                               logger.log(Level.CONFIG, "appConfig.xml is loaded.:" + uri);\r
-                                       } finally {\r
-                                               is.close();\r
-                                       }\r
-\r
-                               } catch (FileNotFoundException ex) {\r
-                                       logger.log(Level.CONFIG, "appConfig.xml is not found.: " + uri, ex);\r
-                                       // 無視する (無い場合は十分にありえるので「情報」レベルでログ。)\r
-                               } catch (Exception ex) {\r
-                                       logger.log(Level.WARNING, "appConfig.xml loading failed.: " + uri, ex);\r
-                                       // 無視する\r
-                               }\r
-                       }\r
-\r
-               } catch (IOException ex) {\r
-                       throw new RuntimeException("appConfig.xml loading failed.", ex);\r
-               } catch (RuntimeException ex) {\r
-                       throw new RuntimeException("appConfig.xml loading failed.", ex);\r
-               }\r
-               BeanPropertiesUtilities.loadFromProperties(this, config);\r
-       }\r
-\r
-       /**\r
-        * プロパティをアプリケーションデータの指定した保存先に保存する.\r
-        *\r
-        * @throws IOException\r
-        *             保存に失敗した場合\r
-        */\r
-       public void saveConfig(List<File> prioritySaveFiles) throws IOException {\r
-               Properties config = getProperties();\r
-               IOException oex = null;\r
-               for (File configStore : prioritySaveFiles) {\r
-                       try {\r
-                               OutputStream os = new BufferedOutputStream(\r
-                                               new FileOutputStream(configStore));\r
-                               try {\r
-                                       config.storeToXML(os, CONFIG_NAME, "UTF-8");\r
-                                       return; // 成功した時点で終了\r
-\r
-                               } finally {\r
-                                       os.close();\r
-                               }\r
-\r
-                       } catch (IOException ex) {\r
-                               logger.log(Level.WARNING, "アプリケーション設定の保存に失敗しました" + ex, ex);\r
-                               oex = ex;\r
-                       }\r
-               }\r
-\r
-               // 例外が発生していれば、最後の例外を返す.\r
-               if (oex != null) {\r
-                       throw oex;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * プロパティをアプリケーションデータの保存先に保存する.\r
-        *\r
-        * @throws IOException\r
-        *             保存に失敗した場合\r
-        */\r
-       public void saveConfig() throws IOException {\r
-               saveConfig(getPrioritySaveFileList());\r
-       }\r
-\r
-       /**\r
-        * Propertiesの値を設定した場合に設定できない項目があるかチェックする.<br>\r
-        * このメソッドを呼び出しても、アプリケーション設定自身は何も影響されない.<br>\r
-        *\r
-        * @param props\r
-        *            適用するプロパティ\r
-        * @return 設定できなかったプロパティキーのコレクション、問題なければ空が返される.\r
-        */\r
-       public static Set<String> checkProperties(Properties props) {\r
-               if (props == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               AppConfig dummy = new AppConfig(); // アプリケーションから参照されないダミーのインスタンスを作成する.\r
-               return BeanPropertiesUtilities.loadFromProperties(dummy, props);\r
-       }\r
-\r
-       /**\r
-        * Propertiesの値で設定を更新する.<br>\r
-        *\r
-        * @param props\r
-        *            適用するプロパティ\r
-        * @return 設定できなかったプロパティキーのコレクション、問題なければ空が返される.\r
-        */\r
-       public Set<String> update(Properties props) {\r
-               if (props == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               return BeanPropertiesUtilities.loadFromProperties(this, props);\r
-       }\r
-\r
-       /**\r
-        * このアプリケーション設定をプロパティに書き出して返します.<br>\r
-        *\r
-        * @return プロパティ\r
-        */\r
-       public Properties getProperties() {\r
-               Properties config = new Properties();\r
-               BeanPropertiesUtilities.saveToProperties(this, config);\r
-               return config;\r
-       }\r
-\r
-\r
-       /**\r
-        * プロファイル選択ダイアログのプロファイルのサンプルイメージの背景色\r
-        *\r
-        * @return サンプルイメージの背景色\r
-        */\r
-       public Color getSampleImageBgColor() {\r
-               return sampleImageBgColor;\r
-       }\r
-\r
-       public void setSampleImageBgColor(Color sampleImageBgColor) {\r
-               if (sampleImageBgColor == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.sampleImageBgColor = sampleImageBgColor;\r
-       }\r
-\r
-       private Color sampleImageBgColor = Color.white;\r
-\r
-\r
-       /**\r
-        * デフォルトのイメージ背景色を取得する.\r
-        *\r
-        * @return デフォルトのイメージ背景色\r
-        */\r
-       public Color getDefaultImageBgColor() {\r
-               return defaultImageBgColor;\r
-       }\r
-\r
-       public void setDefaultImageBgColor(Color defaultImageBgColor) {\r
-               if (defaultImageBgColor == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.defaultImageBgColor = defaultImageBgColor;\r
-       }\r
-\r
-       private Color defaultImageBgColor = Color.white;\r
-\r
-       /**\r
-        * 使用中アイテムの背景色を取得する.\r
-        *\r
-        * @return 使用中アイテムの背景色\r
-        */\r
-       public Color getCheckedItemBgColor() {\r
-               return checkedItemBgColor;\r
-       }\r
-\r
-       public void setCheckedItemBgColor(Color checkedItemBgColor) {\r
-               if (checkedItemBgColor == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.checkedItemBgColor = checkedItemBgColor;\r
-       }\r
-\r
-       private Color checkedItemBgColor = Color.cyan.brighter();\r
-\r
-\r
-       /**\r
-        *  選択アイテムの背景色を取得する\r
-        *\r
-        * @return 選択アイテムの背景色\r
-        */\r
-       public Color getSelectedItemBgColor() {\r
-               return selectedItemBgColor;\r
-       }\r
-\r
-       public void setSelectedItemBgColor(Color selectedItemBgColor) {\r
-               this.selectedItemBgColor = selectedItemBgColor;\r
-       }\r
-\r
-       private Color selectedItemBgColor = Color.orange;\r
-\r
-       /**\r
-        * 不備のあるデータ行の背景色を取得する.\r
-        *\r
-        * @return 不備のあるデータ行の背景色\r
-        */\r
-       public Color getInvalidBgColor() {\r
-               return invalidBgColor;\r
-       }\r
-\r
-       public void setInvalidBgColor(Color invalidBgColor) {\r
-               if (invalidBgColor == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.invalidBgColor = invalidBgColor;\r
-       }\r
-\r
-       private Color invalidBgColor = Color.red.brighter().brighter();\r
-\r
-       /**\r
-        * JPEG画像変換時の圧縮率を取得する.\r
-        *\r
-        * @return 圧縮率\r
-        */\r
-       public float getCompressionQuality() {\r
-               return compressionQuality;\r
-       }\r
-\r
-       public void setCompressionQuality(float compressionQuality) {\r
-               if (compressionQuality < .1f || compressionQuality > 1f) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.compressionQuality = compressionQuality;\r
-       }\r
-\r
-       private float compressionQuality = .8f;\r
-\r
-       /**\r
-        * エクスポートウィザードのプリセットにパーツ不足時の警告色(前景色)を取得する.\r
-        *\r
-        * @return エクスポートウィザードのプリセットにパーツ不足時の警告色(前景色)\r
-        */\r
-       public Color getExportPresetWarningsForegroundColor() {\r
-               return exportPresetWarningsForegroundColor;\r
-       }\r
-\r
-       public void setExportPresetWarningsForegroundColor(\r
-                       Color exportPresetWarningsForegroundColor) {\r
-               this.exportPresetWarningsForegroundColor = exportPresetWarningsForegroundColor;\r
-       }\r
-\r
-       private Color exportPresetWarningsForegroundColor = Color.red;\r
-\r
-       /**\r
-        * JARファイル転送用バッファサイズ.<br>\r
-        *\r
-        * @return JARファイル転送用バッファサイズ.\r
-        */\r
-       public int getJarTransferBufferSize() {\r
-               return jarTransferBufferSize;\r
-       }\r
-\r
-       public void setJarTransferBufferSize(int jarTransferBufferSize) {\r
-               if (jarTransferBufferSize <= 0) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.jarTransferBufferSize = jarTransferBufferSize;\r
-       }\r
-\r
-       private int jarTransferBufferSize = 4096;\r
-\r
-       /**\r
-        * ZIPファイル名のエンコーディング.<br>\r
-        *\r
-        * @return ZIPファイル名のエンコーディング.<br>\r
-        */\r
-       public String getZipNameEncoding() {\r
-               return zipNameEncoding;\r
-       }\r
-\r
-       public void setZipNameEncoding(String zipNameEncoding) {\r
-               if (zipNameEncoding == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               try {\r
-                       Charset.forName(zipNameEncoding);\r
-               } catch (Exception ex) {\r
-                       throw new RuntimeException("unsupported charset: " + zipNameEncoding);\r
-               }\r
-               this.zipNameEncoding = zipNameEncoding;\r
-       }\r
-\r
-       private String zipNameEncoding = "csWindows31J";\r
-\r
-       /**\r
-        * ディセーブルなテーブルのセルのフォアグラウンドカラーを取得する.\r
-        *\r
-        * @return ディセーブルなテーブルのセルのフォアグラウンドカラー\r
-        */\r
-       public Color getDisabledCellForgroundColor() {\r
-               return disabledCellForegroundColor;\r
-       }\r
-\r
-       public void setDisabledCellForegroundColor(Color disabledCellForegroundColor) {\r
-               if (disabledCellForegroundColor == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.disabledCellForegroundColor = disabledCellForegroundColor;\r
-       }\r
-\r
-       private Color disabledCellForegroundColor = Color.gray;\r
-\r
-\r
-       /**\r
-        * ディレクトリを監視する間隔(mSec)を取得する.\r
-        *\r
-        * @return ディレクトリを監視する間隔(mSec)\r
-        */\r
-       public int getDirWatchInterval() {\r
-               return dirWatchInterval;\r
-       }\r
-\r
-       public void setDirWatchInterval(int dirWatchInterval) {\r
-               if (dirWatchInterval <= 0) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.dirWatchInterval = dirWatchInterval;\r
-       }\r
-\r
-       private int dirWatchInterval = 7 * 1000;\r
-\r
-       /**\r
-        * ディレクトリの監視を有効にするか?\r
-        *\r
-        * @return ディレクトリの監視を有効にする場合はtrue\r
-        */\r
-       public boolean isEnableDirWatch() {\r
-               return enableDirWatch;\r
-       }\r
-\r
-       public void setEnableDirWatch(boolean enableDirWatch) {\r
-               this.enableDirWatch = enableDirWatch;\r
-       }\r
-\r
-       private boolean enableDirWatch = true;\r
-\r
-       /**\r
-        * ファイル転送に使うバッファサイズ.<br>\r
-        *\r
-        * @return バッファサイズ\r
-        */\r
-       public int getFileTransferBufferSize() {\r
-               return fileTransferBufferSize;\r
-       }\r
-\r
-       public void setFileTransferBufferSize(int fileTransferBufferSize) {\r
-               if (fileTransferBufferSize <= 0) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.fileTransferBufferSize = fileTransferBufferSize;\r
-       }\r
-\r
-       private int fileTransferBufferSize = 4096;\r
-\r
-       /**\r
-        * プレビューのインジケータを表示するまでのディレイ(mSec)を取得する.\r
-        *\r
-        * @return プレビューのインジケータを表示するまでのディレイ(mSec)\r
-        */\r
-       public long getPreviewIndicatorDelay() {\r
-               return previewIndeicatorDelay;\r
-       }\r
-\r
-       public void setPreviewIndeicatorDelay(long previewIndeicatorDelay) {\r
-               if (previewIndeicatorDelay < 0) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.previewIndeicatorDelay = previewIndeicatorDelay;\r
-       }\r
-\r
-       private long previewIndeicatorDelay = 300;\r
-\r
-       /**\r
-        * 情報ダイアログの編集ボタンを「開く」アクションにする場合はtrue、「編集」アクションにする場合はfalse\r
-        *\r
-        * @return trueならばOpen、falseならばEdit\r
-        */\r
-       public boolean isInformationDialogOpenMethod() {\r
-               return informationDialogOpenMethod;\r
-       }\r
-\r
-       public void setInformationDialogOpenMethod(\r
-                       boolean informationDialogOpenMethod) {\r
-               this.informationDialogOpenMethod = informationDialogOpenMethod;\r
-       }\r
-\r
-       private boolean informationDialogOpenMethod = true;\r
-\r
-       /**\r
-        * ログを常に残すか?<br>\r
-        * falseの場合は{@link ApplicationLogHandler}の実装に従って終了時に 必要なければログは削除される.<br>\r
-        *\r
-        * @return 常に残す場合はtrue、そうでなければfalse\r
-        */\r
-       public boolean isNoRemoveLog() {\r
-               return noRemoveLog;\r
-       }\r
-\r
-       public void setNoRemoveLog(boolean noRemoveLog) {\r
-               this.noRemoveLog = noRemoveLog;\r
-       }\r
-\r
-       private boolean noRemoveLog = false;\r
-\r
-\r
-       /**\r
-        * テーブルのグリッド色.<br>\r
-        *\r
-        * @return テーブルのグリッド色\r
-        */\r
-       public Color getGridColor() {\r
-               return gridColor;\r
-       }\r
-\r
-       public void setGridColor(Color gridColor) {\r
-               if (gridColor == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.gridColor = gridColor;\r
-       }\r
-\r
-       private Color gridColor = Color.gray;\r
-\r
-       /**\r
-        * カラーダイアログの値が変更されたら、自動的にプレビューを更新するか?\r
-        *\r
-        * @return カラーダイアログの値が変更されたら、自動的にプレビューを更新する場合はtrue (デフォルトはtrue)\r
-        */\r
-       public boolean isEnableAutoColorChange() {\r
-               return enableAutoColorChange;\r
-       }\r
-\r
-       public void setEnableAutoColorChange(boolean enableAutoColorChange) {\r
-               this.enableAutoColorChange = enableAutoColorChange;\r
-       }\r
-\r
-       private boolean enableAutoColorChange = true;\r
-\r
-       public void setAuthorEditConflictBgColor(Color authorEditConflictBgColor) {\r
-               if (authorEditConflictBgColor == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               this.authorEditConflictBgColor = authorEditConflictBgColor;\r
-       }\r
-\r
-       /**\r
-        * パーツの作者編集時に複数作者を選択した場合のに入力ボックスの背景色\r
-        *\r
-        * @return 背景色\r
-        */\r
-       public Color getAuthorEditConflictBgColor() {\r
-               return authorEditConflictBgColor;\r
-       }\r
-\r
-       Color authorEditConflictBgColor = Color.yellow;\r
-\r
-\r
-       public void setMainFrameMaxWidth(int width) {\r
-               this.mainFrameMaxWidth = width;\r
-       }\r
-\r
-       /**\r
-        * メインフレームの初期表示時の最大幅\r
-        *\r
-        * @return メインフレームの初期表示時の最大幅\r
-        */\r
-       public int getMainFrameMaxWidth() {\r
-               return mainFrameMaxWidth;\r
-       }\r
-\r
-       private int mainFrameMaxWidth = 800;\r
-\r
-       public void setMainFrameMaxHeight(int height) {\r
-               this.mainFrameMaxHeight = height;\r
-       }\r
-\r
-       /**\r
-        * メインフレームの初期表示時の最大高さ\r
-        *\r
-        * @return メインフレームの初期表示時の最大高さ\r
-        */\r
-       public int getMainFrameMaxHeight() {\r
-               return mainFrameMaxHeight;\r
-       }\r
-\r
-       private int mainFrameMaxHeight = 600;\r
-\r
-\r
-       /**\r
-        * カラーダイアログで存在しないレイヤーをディセーブルにしない.\r
-        *\r
-        * @return ディセーブルにしない場合はtrue\r
-        */\r
-       public boolean isNotDisableLayerTab() {\r
-               return notDisableLayerTab;\r
-       }\r
-\r
-       public void setNotDisableLayerTab(boolean notDisableLayerTab) {\r
-               this.notDisableLayerTab = notDisableLayerTab;\r
-       }\r
-\r
-       private boolean notDisableLayerTab;\r
-\r
-\r
-       /**\r
-        * ログを消去する日数.<br>\r
-        * この指定日を経過した古いログは削除される.<br>\r
-        * 0の場合は削除されない.\r
-        *\r
-        * @return\r
-        */\r
-       public long getPurgeLogDays() {\r
-               return purgeLogDays;\r
-       }\r
-\r
-       public void setPurgeLogDays(long purgeLogDays) {\r
-               this.purgeLogDays = purgeLogDays;\r
-       }\r
-\r
-       private long purgeLogDays = 10;\r
-\r
-       public String getPartsColorGroupPattern() {\r
-               return partsColorGroupPattern;\r
-       }\r
-\r
-       public void setPartsColorGroupPattern(String pattern) {\r
-               if (pattern != null && pattern.trim().length() > 0) {\r
-                       Pattern.compile(pattern);\r
-               }\r
-               partsColorGroupPattern = pattern;\r
-       }\r
-\r
-       private String partsColorGroupPattern = "^.*\\(@\\).*$";\r
-\r
-       private Color selectPanelTitleColor = Color.BLUE;\r
-\r
-       public Color getSelectPanelTitleColor() {\r
-               return selectPanelTitleColor;\r
-       }\r
-\r
-       public void setSelectPanelTitleColor(Color color) {\r
-               if (color == null) {\r
-                       throw new IllegalArgumentException();\r
-               }\r
-               selectPanelTitleColor = color;\r
-       }\r
-\r
-       private boolean enableAutoShrinkPanel;\r
-\r
-       public boolean isEnableAutoShrinkPanel() {\r
-               return enableAutoShrinkPanel;\r
-       }\r
-\r
-       public void setEnableAutoShrinkPanel(boolean enableAutoShrinkPanel) {\r
-               this.enableAutoShrinkPanel = enableAutoShrinkPanel;\r
-       }\r
-\r
-       public boolean isDisableWatchDirIfNotWritable() {\r
-               return disableWatchDirIfNotWritable;\r
-       }\r
-\r
-       public void setDisableWatchDirIfNotWritable(boolean disableWatchDirIfNotWritable) {\r
-               this.disableWatchDirIfNotWritable = disableWatchDirIfNotWritable;\r
-       }\r
-\r
-       private boolean disableWatchDirIfNotWritable = true;\r
-\r
-       public void setEnablePNGSupportForWindows(boolean enablePNGSupportForWindows) {\r
-               this.enablePNGSupportForWindows = enablePNGSupportForWindows;\r
-       }\r
-\r
-       public boolean isEnablePNGSupportForWindows() {\r
-               return enablePNGSupportForWindows;\r
-       }\r
-\r
-       private boolean enablePNGSupportForWindows = true;\r
-\r
-       /**\r
-        * 画像表示(通常モード)でオプティマイズを有効にする最大倍率.\r
-        */\r
-       private double renderingOptimizeThresholdForNormal = 2.;\r
-\r
-       public void setRenderingOptimizeThresholdForNormal(\r
-                       double renderingOptimizeThresholdForNormal) {\r
-               this.renderingOptimizeThresholdForNormal = renderingOptimizeThresholdForNormal;\r
-       }\r
-\r
-       public double getRenderingOptimizeThresholdForNormal() {\r
-               return renderingOptimizeThresholdForNormal;\r
-       }\r
-       /**\r
-        * 画像表示(チェックモード)でオプティマイズを有効にする最大倍率.\r
-        */\r
-       private double renderingOptimizeThresholdForCheck = 0.;\r
-\r
-       public void setRenderingOptimizeThresholdForCheck(\r
-                       double renderingOptimizeThresholdForCheck) {\r
-               this.renderingOptimizeThresholdForCheck = renderingOptimizeThresholdForCheck;\r
-       }\r
-\r
-       public double getRenderingOptimizeThresholdForCheck() {\r
-               return renderingOptimizeThresholdForCheck;\r
-       }\r
-\r
-       /**\r
-        * バイキュービックをサポートする場合\r
-        */\r
-       private boolean enableInterpolationBicubic = true;\r
-\r
-       public void setEnableInterpolationBicubic(boolean enableInterpolationBicubic) {\r
-               this.enableInterpolationBicubic = enableInterpolationBicubic;\r
-       }\r
-\r
-       public boolean isEnableInterpolationBicubic() {\r
-               return enableInterpolationBicubic;\r
-       }\r
-\r
-       /**\r
-        * 事前定義済みの倍率候補.<br>\r
-        */\r
-       private String predefinedZoomRanges = "20, 50, 80, 100, 120, 150, 200, 300, 400, 800";\r
-\r
-       public String getPredefinedZoomRanges() {\r
-               return predefinedZoomRanges;\r
-       }\r
-\r
-       public void setPredefinedZoomRanges(String predefinedZoomRanges) {\r
-               this.predefinedZoomRanges = predefinedZoomRanges;\r
-       }\r
-\r
-       /**\r
-        * ズームパネルを初期状態で表示するか?\r
-        */\r
-       private boolean enableZoomPanel = true;\r
-\r
-       public boolean isEnableZoomPanel() {\r
-               return enableZoomPanel;\r
-       }\r
-\r
-       public void setEnableZoomPanel(boolean enableZoomPanel) {\r
-               this.enableZoomPanel = enableZoomPanel;\r
-       }\r
-\r
-       /**\r
-        * ズームパネルをアクティブにする下部範囲\r
-        */\r
-       private int zoomPanelActivationArea = 30;\r
-\r
-       public int getZoomPanelActivationArea() {\r
-               return zoomPanelActivationArea;\r
-       }\r
-\r
-       public void setZoomPanelActivationArea(int zoomPanelActivationArea) {\r
-               this.zoomPanelActivationArea = zoomPanelActivationArea;\r
-       }\r
-\r
-       /**\r
-        * レンダリングヒントを使用するか?\r
-        */\r
-       private boolean enableRenderingHints = true;\r
-\r
-       public void setEnableRenderingHints(boolean enableRenderingHints) {\r
-               this.enableRenderingHints = enableRenderingHints;\r
-       }\r
-\r
-       public boolean isEnableRenderingHints() {\r
-               return enableRenderingHints;\r
-       }\r
-\r
-       /**\r
-        * グリッド描画とマスク\r
-        */\r
-       private int drawGridMask = 2;\r
-\r
-       public int getDrawGridMask() {\r
-               return drawGridMask;\r
-       }\r
-\r
-       public void setDrawGridMask(int drawGridMask) {\r
-               this.drawGridMask = drawGridMask & 0x03;\r
-       }\r
-\r
-       private int previewGridColor = 0x7f7f0000;\r
-\r
-       public int getPreviewGridColor() {\r
-               return previewGridColor;\r
-       }\r
-\r
-       public void setPreviewGridColor(int previewGridColor) {\r
-               this.previewGridColor = previewGridColor;\r
-       }\r
-\r
-       private int previewGridSize = 20;\r
-\r
-       public int getPreviewGridSize() {\r
-               return previewGridSize;\r
-       }\r
-\r
-       public void setPreviewGridSize(int previewGridSize) {\r
-               this.previewGridSize = previewGridSize;\r
-       }\r
-\r
-       /**\r
-        * チェックモード時の余白サイズ(片側)\r
-        */\r
-       private int previewUnfilledSpaceForCheckMode = 0;\r
-\r
-       public int getPreviewUnfilledSpaceForCheckMode() {\r
-               return previewUnfilledSpaceForCheckMode;\r
-       }\r
-\r
-       public void setPreviewUnfilledSpaceForCheckMode(\r
-                       int previewUnfilledSpaceForCheckMode) {\r
-               this.previewUnfilledSpaceForCheckMode = previewUnfilledSpaceForCheckMode;\r
-       }\r
-\r
-       /**\r
-        * チェックモードでツールチップを表示するか?\r
-        */\r
-       private boolean enableCheckInfoTooltip = true;\r
-\r
-       public boolean isEnableCheckInfoTooltip() {\r
-               return enableCheckInfoTooltip;\r
-       }\r
-\r
-       public void setEnableCheckInfoTooltip(boolean enableCheckInfoTooltip) {\r
-               this.enableCheckInfoTooltip = enableCheckInfoTooltip;\r
-       }\r
-\r
-       /**\r
-        * ホイールによるスクロールの単位.<br>\r
-        */\r
-       private int wheelScrollUnit = 10;\r
-\r
-       public int getWheelScrollUnit() {\r
-               return wheelScrollUnit;\r
-       }\r
-\r
-       public void setWheelScrollUnit(int wheelScrollUnit) {\r
-               this.wheelScrollUnit = wheelScrollUnit;\r
-       }\r
-\r
-       /**\r
-        * 壁紙にオフスクリーン描画を使用するか?.<br>\r
-        * (あまり劇的なパフォーマンス効果はない.)\r
-        */\r
-       private boolean enableOffscreenWallpaper = false;\r
-\r
-       public boolean isEnableOffscreenWallpaper() {\r
-               return enableOffscreenWallpaper;\r
-       }\r
-\r
-       public void setEnableOffscreenWallpaper(boolean enableOffscreenWallpaper) {\r
-               this.enableOffscreenWallpaper = enableOffscreenWallpaper;\r
-       }\r
-\r
-       /**\r
-        * 壁紙のオフスクリーンの既定サイズ.\r
-        */\r
-       private int offscreenWallpaperSize = 300;\r
-\r
-       public int getOffscreenWallpaperSize() {\r
-               return offscreenWallpaperSize;\r
-       }\r
-\r
-       public void setOffscreenWallpaperSize(int offscreenWallpaperSize) {\r
-               this.offscreenWallpaperSize = offscreenWallpaperSize;\r
-       }\r
-\r
-       private int randomChooserMaxHistory = 10;\r
-\r
-       public int getRandomChooserMaxHistory() {\r
-               return randomChooserMaxHistory;\r
-       }\r
-\r
-       public void setRandomChooserMaxHistory(int randomChooserMaxHistory) {\r
-               this.randomChooserMaxHistory = randomChooserMaxHistory;\r
-       }\r
-\r
-       private int defaultFontSize = 12;\r
-\r
-       public int getDefaultFontSize() {\r
-               return defaultFontSize;\r
-       }\r
-\r
-       public void setDefaultFontSize(int defaultFontSize) {\r
-               this.defaultFontSize = defaultFontSize;\r
-       }\r
-}\r
+package charactermanaj.model;
+
+import java.awt.Color;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import charactermanaj.util.ApplicationLogHandler;
+import charactermanaj.util.BeanPropertiesUtilities;
+import charactermanaj.util.ConfigurationDirUtilities;
+
+/**
+ * アプリケーションの全域にわたる設定.<br>
+ * アプリケーション設定は、クラスパス上のリソース、コートベース直下のappConfig.xml、ユーザーごとのappConfig.xmlの順に読み込まれます
+ * .<br>
+ *
+ * @author seraphy
+ */
+public final class AppConfig {
+
+       /**
+        * アプリケーション設定ファイルの名前
+        */
+       private static final String CONFIG_NAME = "appConfig.xml";
+
+       /**
+        * 全ユーザー用キャラクターディレクトリのシステムプロパティのキー名.<br>
+        */
+       public static final String COMMON_CHARACTER_DIR_PROPERTY_NAME = "character.dir";
+
+       /**
+        * 開発用仕様バージョン番号
+        */
+       private static final String DEFAULT_SPECIFICATION_VERSION = "1.0";
+
+
+       /**
+        * ロガー
+        */
+       private static final Logger logger = Logger.getLogger(AppConfig.class.getName());
+
+
+       /**
+        * シングルトンインスタンス
+        */
+       private static final AppConfig singleton = new AppConfig();
+
+
+       /**
+        * インスタンスを取得する.
+        *
+        * @return インスタンス
+        */
+       public static AppConfig getInstance() {
+               return singleton;
+       }
+
+       /**
+        * プライベートコンストラクタ
+        */
+       private AppConfig() {
+               loadAppVersions();
+       }
+
+       private String implementationVersion;
+
+       private String specificationVersion;
+
+       /**
+        * 実装バージョンを取得する.<br>
+        * ビルドされたjarパッケージからバージョン情報を取得する.<br>
+        * クラスパスの実行からのバージョンは常に「develop」となる.<br>
+        *
+        * @return 実装バージョン
+        */
+       public String getImplementationVersion() {
+               return implementationVersion;
+       }
+
+       /**
+        * 仕様バージョンを取得する.<br>
+        * ビルドされたjarパッケージからバージョン情報を取得する.<br>
+        * クラスパスの実行からのバージョンは常に「develop」となる.<br>
+        *
+        * @return 仕様バージョン
+        */
+       public String getSpecificationVersion() {
+               return specificationVersion;
+       }
+
+       /**
+        * ビルドされたjarパッケージからバージョン情報を取得する.<br>
+        * クラスパスの実行からのバージョンは常に「develop」となる.<br>
+        */
+       private void loadAppVersions() {
+               Package pak = this.getClass().getPackage();
+               String implementationVersion = "develop";
+               String specificationVersion = DEFAULT_SPECIFICATION_VERSION;
+               if (pak != null) {
+                       String vInfo = pak.getImplementationVersion();
+                       if (vInfo != null && implementationVersion.trim().length() > 0) {
+                               implementationVersion = vInfo.trim();
+                       }
+                       String specVInfo = pak.getSpecificationVersion();
+                       if (specVInfo != null && specVInfo.trim().length() > 0) {
+                               specificationVersion = specVInfo.trim();
+                       }
+               }
+
+               this.implementationVersion = implementationVersion;
+               this.specificationVersion = specificationVersion;
+       }
+
+       /**
+        * 設定ファイルの読み込み順序で、読み込むべきURIのリストを返す.<br>
+        * <ul>
+        * <li>(1) リソース上の/appConfig.xml</li>
+        * <li>(2) appConfigFileシステムプロパティで指定されたファイル</li>
+        * <li>(3) コードベース下のappConfig.xml</li>
+        * <li>(4) アプリケーションデータ保存先のappConfig.xml</li>
+        * </ul>
+        * appConfigFileシステムプロパティがある場合は、(1)(2)の順。 <br>
+        * 指定がない場合は、(1)(3)(4)の順に読み取る.<br>
+        *
+        * @return 優先順位での設定ファイルの読み込み先URIのリスト
+        * @throws IOException
+        */
+       public List<URI> getCandidateURIs() throws IOException {
+               List<URI> uris = new ArrayList<URI>();
+               // リソース中の既定
+               uris.add(new File(getClass().getResource("/" + CONFIG_NAME).getPath())
+                               .toURI());
+
+               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());
+                       }
+
+               } else {
+                       // システムプロパティが指定されていない場合は、
+                       // コードベース、つぎにユーザーディレクトリの順で読み込む
+                       File codeBase = ConfigurationDirUtilities.getApplicationBaseDir();
+                       File userDataDir = ConfigurationDirUtilities.getUserDataDir();
+
+                       // システムプロパティて明示していない場合は、コードベースおよびユーザディレクトリを使用する.
+                       uris.add(new File(codeBase, CONFIG_NAME).getCanonicalFile().toURI());
+                       uris.add(new File(userDataDir, CONFIG_NAME).toURI());
+               }
+               return uris;
+       }
+
+       /**
+        * 保存先の試行順序ごとのファイルのリスト。
+        *
+        * @return 保存先(優先順)
+        */
+       public List<File> getPrioritySaveFileList() {
+               ArrayList<File> saveFiles = new ArrayList<File>();
+
+               String specifiedAppConfig = System.getProperty("appConfigFile");
+               if (specifiedAppConfig != null) {
+                       // システムプロパティでappConfig.xmlを明示している場合
+                       if (specifiedAppConfig.trim().length() > 0) {
+                               File specifiedAppConfigFile = new File(specifiedAppConfig);
+                               if (!specifiedAppConfigFile.exists()
+                                               || specifiedAppConfigFile.canWrite()) {
+                                       // まだ存在しないか、書き込み可能である場合のみ候補とする.
+                                       saveFiles.add(specifiedAppConfigFile);
+                               }
+                       }
+               } else {
+                       // システムプロパティappConfigFileがなければユーザディレクトリへ書き込む
+                       // ユーザディレクトリは常に候補とする.
+                       File userDataDir = ConfigurationDirUtilities.getUserDataDir();
+                       saveFiles.add(new File(userDataDir, CONFIG_NAME));
+               }
+
+               return saveFiles;
+       }
+
+       /**
+        * プロパティをロードする.<br>
+        * 存在しないか、読み取りに失敗した場合は、該当ファイルはスキップされる.<br>
+        */
+       public void loadConfig() {
+               Properties config = new Properties();
+               try {
+                       for (URI uri : getCandidateURIs()) {
+                               if (uri == null) {
+                                       continue; // リソースがない場合はnullになる
+                               }
+                               // ファイルの実在チェック (チェックできる場合のみ)
+                               if ("file".equals(uri.getScheme())) {
+                                       File file = new File(uri);
+                                       if (!file.exists()) {
+                                               logger.log(Level.CONFIG, "appConfig.xml is not found.:" + file);
+                                               continue;
+                                       }
+                               }
+                               // appConfig.xmlの読み込みを行う.
+                               // Properties#loadFromXML() はXMLからキーを読み取り、既存のキーに対して上書きする.
+                               // XMLに存在しないキーは読み込み前のままなので、繰り返し呼び出すことで「重ね合わせ」することができる.
+                               try {
+                                       URL resourceURL = uri.toURL();
+                                       InputStream is = resourceURL.openStream();
+                                       try {
+                                               config.loadFromXML(is);
+                                               logger.log(Level.CONFIG, "appConfig.xml is loaded.:" + uri);
+                                       } finally {
+                                               is.close();
+                                       }
+
+                               } catch (FileNotFoundException ex) {
+                                       logger.log(Level.CONFIG, "appConfig.xml is not found.: " + uri, ex);
+                                       // 無視する (無い場合は十分にありえるので「情報」レベルでログ。)
+                               } catch (Exception ex) {
+                                       logger.log(Level.WARNING, "appConfig.xml loading failed.: " + uri, ex);
+                                       // 無視する
+                               }
+                       }
+
+               } catch (IOException ex) {
+                       throw new RuntimeException("appConfig.xml loading failed.", ex);
+               } catch (RuntimeException ex) {
+                       throw new RuntimeException("appConfig.xml loading failed.", ex);
+               }
+               BeanPropertiesUtilities.loadFromProperties(this, config);
+       }
+
+       /**
+        * プロパティをアプリケーションデータの指定した保存先に保存する.
+        *
+        * @throws IOException
+        *             保存に失敗した場合
+        */
+       public void saveConfig(List<File> prioritySaveFiles) throws IOException {
+               Properties config = getProperties();
+               IOException oex = null;
+               for (File configStore : prioritySaveFiles) {
+                       try {
+                               OutputStream os = new BufferedOutputStream(
+                                               new FileOutputStream(configStore));
+                               try {
+                                       config.storeToXML(os, CONFIG_NAME, "UTF-8");
+                                       return; // 成功した時点で終了
+
+                               } finally {
+                                       os.close();
+                               }
+
+                       } catch (IOException ex) {
+                               logger.log(Level.WARNING, "アプリケーション設定の保存に失敗しました" + ex, ex);
+                               oex = ex;
+                       }
+               }
+
+               // 例外が発生していれば、最後の例外を返す.
+               if (oex != null) {
+                       throw oex;
+               }
+       }
+
+       /**
+        * プロパティをアプリケーションデータの保存先に保存する.
+        *
+        * @throws IOException
+        *             保存に失敗した場合
+        */
+       public void saveConfig() throws IOException {
+               saveConfig(getPrioritySaveFileList());
+       }
+
+       /**
+        * Propertiesの値を設定した場合に設定できない項目があるかチェックする.<br>
+        * このメソッドを呼び出しても、アプリケーション設定自身は何も影響されない.<br>
+        *
+        * @param props
+        *            適用するプロパティ
+        * @return 設定できなかったプロパティキーのコレクション、問題なければ空が返される.
+        */
+       public static Set<String> checkProperties(Properties props) {
+               if (props == null) {
+                       throw new IllegalArgumentException();
+               }
+               AppConfig dummy = new AppConfig(); // アプリケーションから参照されないダミーのインスタンスを作成する.
+               return BeanPropertiesUtilities.loadFromProperties(dummy, props);
+       }
+
+       /**
+        * Propertiesの値で設定を更新する.<br>
+        *
+        * @param props
+        *            適用するプロパティ
+        * @return 設定できなかったプロパティキーのコレクション、問題なければ空が返される.
+        */
+       public Set<String> update(Properties props) {
+               if (props == null) {
+                       throw new IllegalArgumentException();
+               }
+               return BeanPropertiesUtilities.loadFromProperties(this, props);
+       }
+
+       /**
+        * このアプリケーション設定をプロパティに書き出して返します.<br>
+        *
+        * @return プロパティ
+        */
+       public Properties getProperties() {
+               Properties config = new Properties();
+               BeanPropertiesUtilities.saveToProperties(this, config);
+               return config;
+       }
+
+
+       /**
+        * プロファイル選択ダイアログのプロファイルのサンプルイメージの背景色
+        *
+        * @return サンプルイメージの背景色
+        */
+       public Color getSampleImageBgColor() {
+               return sampleImageBgColor;
+       }
+
+       public void setSampleImageBgColor(Color sampleImageBgColor) {
+               if (sampleImageBgColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               this.sampleImageBgColor = sampleImageBgColor;
+       }
+
+       private Color sampleImageBgColor = Color.white;
+
+
+       /**
+        * デフォルトのイメージ背景色を取得する.
+        *
+        * @return デフォルトのイメージ背景色
+        */
+       public Color getDefaultImageBgColor() {
+               return defaultImageBgColor;
+       }
+
+       public void setDefaultImageBgColor(Color defaultImageBgColor) {
+               if (defaultImageBgColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               this.defaultImageBgColor = defaultImageBgColor;
+       }
+
+       private Color defaultImageBgColor = Color.white;
+
+       /**
+        * 使用中アイテムの背景色を取得する.
+        *
+        * @return 使用中アイテムの背景色
+        */
+       public Color getCheckedItemBgColor() {
+               return checkedItemBgColor;
+       }
+
+       public void setCheckedItemBgColor(Color checkedItemBgColor) {
+               if (checkedItemBgColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               this.checkedItemBgColor = checkedItemBgColor;
+       }
+
+       private Color checkedItemBgColor = Color.cyan.brighter();
+
+
+       /**
+        *  選択アイテムの背景色を取得する
+        *
+        * @return 選択アイテムの背景色
+        */
+       public Color getSelectedItemBgColor() {
+               return selectedItemBgColor;
+       }
+
+       public void setSelectedItemBgColor(Color selectedItemBgColor) {
+               this.selectedItemBgColor = selectedItemBgColor;
+       }
+
+       private Color selectedItemBgColor = Color.orange;
+
+       /**
+        * 不備のあるデータ行の背景色を取得する.
+        *
+        * @return 不備のあるデータ行の背景色
+        */
+       public Color getInvalidBgColor() {
+               return invalidBgColor;
+       }
+
+       public void setInvalidBgColor(Color invalidBgColor) {
+               if (invalidBgColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               this.invalidBgColor = invalidBgColor;
+       }
+
+       private Color invalidBgColor = Color.red.brighter().brighter();
+
+       /**
+        * JPEG画像変換時の圧縮率を取得する.
+        *
+        * @return 圧縮率
+        */
+       public float getCompressionQuality() {
+               return compressionQuality;
+       }
+
+       public void setCompressionQuality(float compressionQuality) {
+               if (compressionQuality < .1f || compressionQuality > 1f) {
+                       throw new IllegalArgumentException();
+               }
+               this.compressionQuality = compressionQuality;
+       }
+
+       private float compressionQuality = .8f;
+
+       /**
+        * エクスポートウィザードのプリセットにパーツ不足時の警告色(前景色)を取得する.
+        *
+        * @return エクスポートウィザードのプリセットにパーツ不足時の警告色(前景色)
+        */
+       public Color getExportPresetWarningsForegroundColor() {
+               return exportPresetWarningsForegroundColor;
+       }
+
+       public void setExportPresetWarningsForegroundColor(
+                       Color exportPresetWarningsForegroundColor) {
+               this.exportPresetWarningsForegroundColor = exportPresetWarningsForegroundColor;
+       }
+
+       private Color exportPresetWarningsForegroundColor = Color.red;
+
+       /**
+        * JARファイル転送用バッファサイズ.<br>
+        *
+        * @return JARファイル転送用バッファサイズ.
+        */
+       public int getJarTransferBufferSize() {
+               return jarTransferBufferSize;
+       }
+
+       public void setJarTransferBufferSize(int jarTransferBufferSize) {
+               if (jarTransferBufferSize <= 0) {
+                       throw new IllegalArgumentException();
+               }
+               this.jarTransferBufferSize = jarTransferBufferSize;
+       }
+
+       private int jarTransferBufferSize = 4096;
+
+       /**
+        * ZIPファイル名のエンコーディング.<br>
+        *
+        * @return ZIPファイル名のエンコーディング.<br>
+        */
+       public String getZipNameEncoding() {
+               return zipNameEncoding;
+       }
+
+       public void setZipNameEncoding(String zipNameEncoding) {
+               if (zipNameEncoding == null) {
+                       throw new IllegalArgumentException();
+               }
+               try {
+                       Charset.forName(zipNameEncoding);
+               } catch (Exception ex) {
+                       throw new RuntimeException("unsupported charset: " + zipNameEncoding);
+               }
+               this.zipNameEncoding = zipNameEncoding;
+       }
+
+       private String zipNameEncoding = "csWindows31J";
+
+       /**
+        * ディセーブルなテーブルのセルのフォアグラウンドカラーを取得する.
+        *
+        * @return ディセーブルなテーブルのセルのフォアグラウンドカラー
+        */
+       public Color getDisabledCellForgroundColor() {
+               return disabledCellForegroundColor;
+       }
+
+       public void setDisabledCellForegroundColor(Color disabledCellForegroundColor) {
+               if (disabledCellForegroundColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               this.disabledCellForegroundColor = disabledCellForegroundColor;
+       }
+
+       private Color disabledCellForegroundColor = Color.gray;
+
+
+       /**
+        * ディレクトリを監視する間隔(mSec)を取得する.
+        *
+        * @return ディレクトリを監視する間隔(mSec)
+        */
+       public int getDirWatchInterval() {
+               return dirWatchInterval;
+       }
+
+       public void setDirWatchInterval(int dirWatchInterval) {
+               if (dirWatchInterval <= 0) {
+                       throw new IllegalArgumentException();
+               }
+               this.dirWatchInterval = dirWatchInterval;
+       }
+
+       private int dirWatchInterval = 7 * 1000;
+
+       /**
+        * ディレクトリの監視を有効にするか?
+        *
+        * @return ディレクトリの監視を有効にする場合はtrue
+        */
+       public boolean isEnableDirWatch() {
+               return enableDirWatch;
+       }
+
+       public void setEnableDirWatch(boolean enableDirWatch) {
+               this.enableDirWatch = enableDirWatch;
+       }
+
+       private boolean enableDirWatch = true;
+
+       /**
+        * ファイル転送に使うバッファサイズ.<br>
+        *
+        * @return バッファサイズ
+        */
+       public int getFileTransferBufferSize() {
+               return fileTransferBufferSize;
+       }
+
+       public void setFileTransferBufferSize(int fileTransferBufferSize) {
+               if (fileTransferBufferSize <= 0) {
+                       throw new IllegalArgumentException();
+               }
+               this.fileTransferBufferSize = fileTransferBufferSize;
+       }
+
+       private int fileTransferBufferSize = 4096;
+
+       /**
+        * プレビューのインジケータを表示するまでのディレイ(mSec)を取得する.
+        *
+        * @return プレビューのインジケータを表示するまでのディレイ(mSec)
+        */
+       public long getPreviewIndicatorDelay() {
+               return previewIndeicatorDelay;
+       }
+
+       public void setPreviewIndeicatorDelay(long previewIndeicatorDelay) {
+               if (previewIndeicatorDelay < 0) {
+                       throw new IllegalArgumentException();
+               }
+               this.previewIndeicatorDelay = previewIndeicatorDelay;
+       }
+
+       private long previewIndeicatorDelay = 300;
+
+       /**
+        * 情報ダイアログの編集ボタンを「開く」アクションにする場合はtrue、「編集」アクションにする場合はfalse
+        *
+        * @return trueならばOpen、falseならばEdit
+        */
+       public boolean isInformationDialogOpenMethod() {
+               return informationDialogOpenMethod;
+       }
+
+       public void setInformationDialogOpenMethod(
+                       boolean informationDialogOpenMethod) {
+               this.informationDialogOpenMethod = informationDialogOpenMethod;
+       }
+
+       private boolean informationDialogOpenMethod = true;
+
+       /**
+        * ログを常に残すか?<br>
+        * falseの場合は{@link ApplicationLogHandler}の実装に従って終了時に 必要なければログは削除される.<br>
+        *
+        * @return 常に残す場合はtrue、そうでなければfalse
+        */
+       public boolean isNoRemoveLog() {
+               return noRemoveLog;
+       }
+
+       public void setNoRemoveLog(boolean noRemoveLog) {
+               this.noRemoveLog = noRemoveLog;
+       }
+
+       private boolean noRemoveLog = false;
+
+
+       /**
+        * テーブルのグリッド色.<br>
+        *
+        * @return テーブルのグリッド色
+        */
+       public Color getGridColor() {
+               return gridColor;
+       }
+
+       public void setGridColor(Color gridColor) {
+               if (gridColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               this.gridColor = gridColor;
+       }
+
+       private Color gridColor = Color.gray;
+
+       /**
+        * カラーダイアログの値が変更されたら、自動的にプレビューを更新するか?
+        *
+        * @return カラーダイアログの値が変更されたら、自動的にプレビューを更新する場合はtrue (デフォルトはtrue)
+        */
+       public boolean isEnableAutoColorChange() {
+               return enableAutoColorChange;
+       }
+
+       public void setEnableAutoColorChange(boolean enableAutoColorChange) {
+               this.enableAutoColorChange = enableAutoColorChange;
+       }
+
+       private boolean enableAutoColorChange = true;
+
+       public void setAuthorEditConflictBgColor(Color authorEditConflictBgColor) {
+               if (authorEditConflictBgColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               this.authorEditConflictBgColor = authorEditConflictBgColor;
+       }
+
+       /**
+        * パーツの作者編集時に複数作者を選択した場合のに入力ボックスの背景色
+        *
+        * @return 背景色
+        */
+       public Color getAuthorEditConflictBgColor() {
+               return authorEditConflictBgColor;
+       }
+
+       Color authorEditConflictBgColor = Color.yellow;
+
+
+       public void setMainFrameMaxWidth(int width) {
+               this.mainFrameMaxWidth = width;
+       }
+
+       /**
+        * メインフレームの初期表示時の最大幅
+        *
+        * @return メインフレームの初期表示時の最大幅
+        */
+       public int getMainFrameMaxWidth() {
+               return mainFrameMaxWidth;
+       }
+
+       private int mainFrameMaxWidth = 800;
+
+       public void setMainFrameMaxHeight(int height) {
+               this.mainFrameMaxHeight = height;
+       }
+
+       /**
+        * メインフレームの初期表示時の最大高さ
+        *
+        * @return メインフレームの初期表示時の最大高さ
+        */
+       public int getMainFrameMaxHeight() {
+               return mainFrameMaxHeight;
+       }
+
+       private int mainFrameMaxHeight = 600;
+
+
+       /**
+        * カラーダイアログで存在しないレイヤーをディセーブルにしない.
+        *
+        * @return ディセーブルにしない場合はtrue
+        */
+       public boolean isNotDisableLayerTab() {
+               return notDisableLayerTab;
+       }
+
+       public void setNotDisableLayerTab(boolean notDisableLayerTab) {
+               this.notDisableLayerTab = notDisableLayerTab;
+       }
+
+       private boolean notDisableLayerTab;
+
+
+       /**
+        * ログを消去する日数.<br>
+        * この指定日を経過した古いログは削除される.<br>
+        * 0の場合は削除されない.
+        *
+        * @return
+        */
+       public long getPurgeLogDays() {
+               return purgeLogDays;
+       }
+
+       public void setPurgeLogDays(long purgeLogDays) {
+               this.purgeLogDays = purgeLogDays;
+       }
+
+       private long purgeLogDays = 10;
+
+       public String getPartsColorGroupPattern() {
+               return partsColorGroupPattern;
+       }
+
+       public void setPartsColorGroupPattern(String pattern) {
+               if (pattern != null && pattern.trim().length() > 0) {
+                       Pattern.compile(pattern);
+               }
+               partsColorGroupPattern = pattern;
+       }
+
+       private String partsColorGroupPattern = "^.*\\(@\\).*$";
+
+       private Color selectPanelTitleColor = Color.BLUE;
+
+       public Color getSelectPanelTitleColor() {
+               return selectPanelTitleColor;
+       }
+
+       public void setSelectPanelTitleColor(Color color) {
+               if (color == null) {
+                       throw new IllegalArgumentException();
+               }
+               selectPanelTitleColor = color;
+       }
+
+       private boolean enableAutoShrinkPanel;
+
+       public boolean isEnableAutoShrinkPanel() {
+               return enableAutoShrinkPanel;
+       }
+
+       public void setEnableAutoShrinkPanel(boolean enableAutoShrinkPanel) {
+               this.enableAutoShrinkPanel = enableAutoShrinkPanel;
+       }
+
+       public boolean isDisableWatchDirIfNotWritable() {
+               return disableWatchDirIfNotWritable;
+       }
+
+       public void setDisableWatchDirIfNotWritable(boolean disableWatchDirIfNotWritable) {
+               this.disableWatchDirIfNotWritable = disableWatchDirIfNotWritable;
+       }
+
+       private boolean disableWatchDirIfNotWritable = true;
+
+       public void setEnablePNGSupportForWindows(boolean enablePNGSupportForWindows) {
+               this.enablePNGSupportForWindows = enablePNGSupportForWindows;
+       }
+
+       public boolean isEnablePNGSupportForWindows() {
+               return enablePNGSupportForWindows;
+       }
+
+       private boolean enablePNGSupportForWindows = true;
+
+       /**
+        * 画像表示(通常モード)でオプティマイズを有効にする最大倍率.
+        */
+       private double renderingOptimizeThresholdForNormal = 2.;
+
+       public void setRenderingOptimizeThresholdForNormal(
+                       double renderingOptimizeThresholdForNormal) {
+               this.renderingOptimizeThresholdForNormal = renderingOptimizeThresholdForNormal;
+       }
+
+       public double getRenderingOptimizeThresholdForNormal() {
+               return renderingOptimizeThresholdForNormal;
+       }
+       /**
+        * 画像表示(チェックモード)でオプティマイズを有効にする最大倍率.
+        */
+       private double renderingOptimizeThresholdForCheck = 0.;
+
+       public void setRenderingOptimizeThresholdForCheck(
+                       double renderingOptimizeThresholdForCheck) {
+               this.renderingOptimizeThresholdForCheck = renderingOptimizeThresholdForCheck;
+       }
+
+       public double getRenderingOptimizeThresholdForCheck() {
+               return renderingOptimizeThresholdForCheck;
+       }
+
+       /**
+        * バイキュービックをサポートする場合
+        */
+       private boolean enableInterpolationBicubic = true;
+
+       public void setEnableInterpolationBicubic(boolean enableInterpolationBicubic) {
+               this.enableInterpolationBicubic = enableInterpolationBicubic;
+       }
+
+       public boolean isEnableInterpolationBicubic() {
+               return enableInterpolationBicubic;
+       }
+
+       /**
+        * 事前定義済みの倍率候補.<br>
+        */
+       private String predefinedZoomRanges = "20, 50, 80, 100, 120, 150, 200, 300, 400, 800";
+
+       public String getPredefinedZoomRanges() {
+               return predefinedZoomRanges;
+       }
+
+       public void setPredefinedZoomRanges(String predefinedZoomRanges) {
+               this.predefinedZoomRanges = predefinedZoomRanges;
+       }
+
+       /**
+        * ズームパネルを初期状態で表示するか?
+        */
+       private boolean enableZoomPanel = true;
+
+       public boolean isEnableZoomPanel() {
+               return enableZoomPanel;
+       }
+
+       public void setEnableZoomPanel(boolean enableZoomPanel) {
+               this.enableZoomPanel = enableZoomPanel;
+       }
+
+       /**
+        * ズームパネルをアクティブにする下部範囲
+        */
+       private int zoomPanelActivationArea = 30;
+
+       public int getZoomPanelActivationArea() {
+               return zoomPanelActivationArea;
+       }
+
+       public void setZoomPanelActivationArea(int zoomPanelActivationArea) {
+               this.zoomPanelActivationArea = zoomPanelActivationArea;
+       }
+
+       /**
+        * レンダリングヒントを使用するか?
+        */
+       private boolean enableRenderingHints = true;
+
+       public void setEnableRenderingHints(boolean enableRenderingHints) {
+               this.enableRenderingHints = enableRenderingHints;
+       }
+
+       public boolean isEnableRenderingHints() {
+               return enableRenderingHints;
+       }
+
+       /**
+        * グリッド描画とマスク
+        */
+       private int drawGridMask = 2;
+
+       public int getDrawGridMask() {
+               return drawGridMask;
+       }
+
+       public void setDrawGridMask(int drawGridMask) {
+               this.drawGridMask = drawGridMask & 0x03;
+       }
+
+       private int previewGridColor = 0x7f7f0000;
+
+       public int getPreviewGridColor() {
+               return previewGridColor;
+       }
+
+       public void setPreviewGridColor(int previewGridColor) {
+               this.previewGridColor = previewGridColor;
+       }
+
+       private int previewGridSize = 20;
+
+       public int getPreviewGridSize() {
+               return previewGridSize;
+       }
+
+       public void setPreviewGridSize(int previewGridSize) {
+               this.previewGridSize = previewGridSize;
+       }
+
+       /**
+        * チェックモード時の余白サイズ(片側)
+        */
+       private int previewUnfilledSpaceForCheckMode = 0;
+
+       public int getPreviewUnfilledSpaceForCheckMode() {
+               return previewUnfilledSpaceForCheckMode;
+       }
+
+       public void setPreviewUnfilledSpaceForCheckMode(
+                       int previewUnfilledSpaceForCheckMode) {
+               this.previewUnfilledSpaceForCheckMode = previewUnfilledSpaceForCheckMode;
+       }
+
+       /**
+        * チェックモードでツールチップを表示するか?
+        */
+       private boolean enableCheckInfoTooltip = true;
+
+       public boolean isEnableCheckInfoTooltip() {
+               return enableCheckInfoTooltip;
+       }
+
+       public void setEnableCheckInfoTooltip(boolean enableCheckInfoTooltip) {
+               this.enableCheckInfoTooltip = enableCheckInfoTooltip;
+       }
+
+       /**
+        * ホイールによるスクロールの単位.<br>
+        */
+       private int wheelScrollUnit = 10;
+
+       public int getWheelScrollUnit() {
+               return wheelScrollUnit;
+       }
+
+       public void setWheelScrollUnit(int wheelScrollUnit) {
+               this.wheelScrollUnit = wheelScrollUnit;
+       }
+
+       /**
+        * 壁紙にオフスクリーン描画を使用するか?.<br>
+        * (あまり劇的なパフォーマンス効果はない.)
+        */
+       private boolean enableOffscreenWallpaper = false;
+
+       public boolean isEnableOffscreenWallpaper() {
+               return enableOffscreenWallpaper;
+       }
+
+       public void setEnableOffscreenWallpaper(boolean enableOffscreenWallpaper) {
+               this.enableOffscreenWallpaper = enableOffscreenWallpaper;
+       }
+
+       /**
+        * 壁紙のオフスクリーンの既定サイズ.
+        */
+       private int offscreenWallpaperSize = 300;
+
+       public int getOffscreenWallpaperSize() {
+               return offscreenWallpaperSize;
+       }
+
+       public void setOffscreenWallpaperSize(int offscreenWallpaperSize) {
+               this.offscreenWallpaperSize = offscreenWallpaperSize;
+       }
+
+       /**
+        * ランダム選択パーツの履歴数
+        */
+       private int randomChooserMaxHistory = 10;
+
+       public int getRandomChooserMaxHistory() {
+               return randomChooserMaxHistory;
+       }
+
+       public void setRandomChooserMaxHistory(int randomChooserMaxHistory) {
+               this.randomChooserMaxHistory = randomChooserMaxHistory;
+       }
+
+       /**
+        * デフォルトのフォントサイズ、0以下の場合はシステム既定のまま
+        */
+       private int defaultFontSize = 12;
+
+       public int getDefaultFontSize() {
+               return defaultFontSize;
+       }
+
+       public void setDefaultFontSize(int defaultFontSize) {
+               this.defaultFontSize = defaultFontSize;
+       }
+
+       /**
+        * デフォルトのフォントファミリー、カンマ区切り
+        */
+       private String fontPriority = "Meiryo, MS UI Gothic, MS Gothic";
+       
+       public String getFontPriority() {
+               return fontPriority;
+       }
+       
+       public void setFontPriority(String fontPriority) {
+               this.fontPriority = fontPriority;
+       }
+}