-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;
+ }
+}
-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;
+ }
+}