OSDN Git Service

カラーダイアログのパラメータのコピーペースト機能の追加
authorseraphy <seraphy@users.osdn.me>
Mon, 10 Dec 2018 15:08:04 +0000 (00:08 +0900)
committerseraphy <seraphy@users.osdn.me>
Mon, 10 Dec 2018 15:24:33 +0000 (00:24 +0900)
および、アプリケーション設定の変更による動的反映を拡充と、
修正もれのあったURLの修正。

22 files changed:
src/main/attachment/README_ja.txt
src/main/attachment/README_ja_withJRE.txt
src/main/java/charactermanaj/Main.java
src/main/java/charactermanaj/model/AppConfig.java
src/main/java/charactermanaj/ui/ColorDialog.java
src/main/java/charactermanaj/ui/ImageSelectPanel.java
src/main/java/charactermanaj/ui/MainFrame.java
src/main/java/charactermanaj/util/BeanPropertiesUtilities.java
src/main/resources/_HOW_TO_LOCALIZE.txt
src/main/resources/appinfo/about.html
src/main/resources/appinfo/about_ja.html
src/main/resources/appinfo/about_zh.html
src/main/resources/icons/paste.png [new file with mode: 0644]
src/main/resources/languages/appconfigdialog.xml
src/main/resources/languages/appconfigdialog_ja.xml
src/main/resources/languages/appconfigdialog_zh.xml
src/main/resources/languages/colordialog.xml
src/main/resources/languages/colordialog_ja.xml
src/main/resources/languages/colordialog_zh.xml
src/main/resources/languages/mainframe.xml
src/main/resources/languages/mainframe_ja.xml
src/main/resources/languages/mainframe_zh.xml

index 3fcac55..148d755 100644 (file)
@@ -56,7 +56,7 @@ Java6でコンパイルしているため、Java6のデスクトップをサポ
 
 [使用・作成されるファイル等について]
 使用・作成されるフォルダ等についてはWikiをご参照ください。
-http://sourceforge.jp/projects/charactermanaj/wiki/FrontPage
+https://osdn.net/projects/charactermanaj/wiki/FrontPage
 
 [ソースコードについて]
 ver0.995からソースコードはGitで管理しています。
index b8cba0e..3ab7b9d 100644 (file)
@@ -64,7 +64,7 @@ Java11での利用も可能です。
 
 [使用・作成されるファイル等について]
 使用・作成されるフォルダ等についてはWikiをご参照ください。
-http://sourceforge.jp/projects/charactermanaj/wiki/FrontPage
+https://osdn.net/projects/charactermanaj/wiki/FrontPage
 
 [ソースコードについて]
 ver0.995からソースコードはGitで管理しています。
index ead0f30..932ab9b 100644 (file)
@@ -1,7 +1,10 @@
 package charactermanaj;
 
 import java.awt.Font;
+import java.awt.Frame;
 import java.awt.GraphicsEnvironment;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.lang.Thread.UncaughtExceptionHandler;
 import java.lang.reflect.Method;
@@ -124,7 +127,7 @@ public final class Main implements Runnable {
         * @throws Exception
         *             いろいろな失敗
         */
-       private static void setupUIManager(AppConfig appConfig) throws Exception {
+       private static void setupUIManager(final AppConfig appConfig) throws Exception {
                // System.setProperty("swing.aatext", "true");
                // System.setProperty("awt.useSystemAAFontSettings", "on");
 
@@ -147,6 +150,27 @@ public final class Main implements Runnable {
                // JSpliderのvalueを非表示 (GTKではデフォルトで有効のため)
                UIManager.put("Slider.paintValue", Boolean.FALSE);
 
+               // デフォルトフォントを設定する
+               setupDefaultFont(appConfig);
+
+               // アプリケーション設定でデフォルトフォントサイズが変更された場合は
+               // 現在表示されている、すべてのフレームに再適用を試行する。
+               appConfig.addPropertyChangeListener(AppConfig.DEFAULT_FONT_SIZE, new PropertyChangeListener() {
+                       @Override
+                       public void propertyChange(PropertyChangeEvent evt) {
+                               setupDefaultFont(appConfig);
+                               try {
+                                       for (Frame frame : Frame.getFrames()) {
+                                               SwingUtilities.updateComponentTreeUI(frame);
+                                       }
+                               } catch (Exception ex) {
+                                       logger.log(Level.WARNING, "failed revalidate frames", ex);
+                               }
+                       }
+               });
+       }
+
+       private static void setupDefaultFont(AppConfig appConfig) {
 
                // 優先するフォントファミリ中の実在するフォントファミリのセット(大文字小文字の区別なし)
                TreeSet<String> availablePriorityFontSets = new TreeSet<String>(
index 668ba36..2499b05 100644 (file)
@@ -1,6 +1,8 @@
 package charactermanaj.model;
 
 import java.awt.Color;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -22,14 +24,17 @@ import java.util.regex.Pattern;
 
 import charactermanaj.util.ApplicationLogHandler;
 import charactermanaj.util.BeanPropertiesUtilities;
+import charactermanaj.util.BeanPropertiesUtilities.StringConverterSpec;
+import charactermanaj.util.BeanPropertiesUtilities.UnsignedHexStringConverter;
 import charactermanaj.util.ConfigurationDirUtilities;
 
 /**
  * アプリケーションの全域にわたる設定.<br>
- * アプリケーション設定は、クラスパス上のリソース、コートベース直下のappConfig.xml、ユーザーごとのappConfig.xmlの順に読み込まれます
- * .<br>
+ * アプリケーション設定は、クラスパス上のリソース、コートベース直下のappConfig.xml、ユーザーごとのappConfig.xmlの順に読み込まれます.<br>
+ * 設定値は{@link BeanPropertiesUtilities}によってXMLプロパティファイルとして永続化されます。<br>
  *
  * @author seraphy
+ * @see BeanPropertiesUtilities
  */
 public final class AppConfig {
 
@@ -60,6 +65,27 @@ public final class AppConfig {
         */
        private static final AppConfig singleton = new AppConfig();
 
+       /**
+        * プロパティ変更リスナのサポート
+        */
+       private final PropertyChangeSupport propChangeSupport = new PropertyChangeSupport(this);
+
+
+       public void addPropertyChangeListener(PropertyChangeListener listener) {
+               propChangeSupport.addPropertyChangeListener(listener);
+       }
+
+       public void removePropertyChangeListener(PropertyChangeListener listener) {
+               propChangeSupport.removePropertyChangeListener(listener);
+       }
+
+       public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+               propChangeSupport.addPropertyChangeListener(propertyName, listener);
+       }
+
+       public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+               propChangeSupport.removePropertyChangeListener(propertyName, listener);
+       }
 
        /**
         * インスタンスを取得する.
@@ -395,11 +421,17 @@ public final class AppConfig {
                return sampleImageBgColor;
        }
 
+       public static final String SAMPLE_IMAGE_BG_COLOR = "sampleImageBgColor";
+
        public void setSampleImageBgColor(Color sampleImageBgColor) {
                if (sampleImageBgColor == null) {
                        throw new IllegalArgumentException();
                }
-               this.sampleImageBgColor = sampleImageBgColor;
+               Color old = this.sampleImageBgColor;
+               if (old == null ? sampleImageBgColor != null : !old.equals(sampleImageBgColor)) {
+                       this.sampleImageBgColor = sampleImageBgColor;
+                       propChangeSupport.firePropertyChange(SAMPLE_IMAGE_BG_COLOR, old, sampleImageBgColor);
+               }
        }
 
        private Color sampleImageBgColor = Color.white;
@@ -414,11 +446,17 @@ public final class AppConfig {
                return defaultImageBgColor;
        }
 
+       public static final String DEFAULT_IMAGE_BG_COLOR = "defaultImageBgColor";
+
        public void setDefaultImageBgColor(Color defaultImageBgColor) {
                if (defaultImageBgColor == null) {
                        throw new IllegalArgumentException();
                }
-               this.defaultImageBgColor = defaultImageBgColor;
+               Color old = this.defaultImageBgColor;
+               if (old == null ? defaultImageBgColor != null : !old.equals(defaultImageBgColor)) {
+                       this.defaultImageBgColor = defaultImageBgColor;
+                       propChangeSupport.firePropertyChange(DEFAULT_IMAGE_BG_COLOR, old, defaultImageBgColor);
+               }
        }
 
        private Color defaultImageBgColor = Color.white;
@@ -432,11 +470,17 @@ public final class AppConfig {
                return checkedItemBgColor;
        }
 
+       public static final String CHECKED_ITEM_BG_COLOR = "checkedItemBgColor";
+
        public void setCheckedItemBgColor(Color checkedItemBgColor) {
                if (checkedItemBgColor == null) {
                        throw new IllegalArgumentException();
                }
-               this.checkedItemBgColor = checkedItemBgColor;
+               Color old = this.checkedItemBgColor;
+               if (old == null ? checkedItemBgColor != null : !old.equals(checkedItemBgColor)) {
+                       this.checkedItemBgColor = checkedItemBgColor;
+                       propChangeSupport.firePropertyChange(CHECKED_ITEM_BG_COLOR, old, checkedItemBgColor);
+               }
        }
 
        private Color checkedItemBgColor = Color.cyan.brighter();
@@ -451,8 +495,17 @@ public final class AppConfig {
                return selectedItemBgColor;
        }
 
+       public static final String SELECTED_ITEM_BG_COLOR = "selectedItemBgColor";
+
        public void setSelectedItemBgColor(Color selectedItemBgColor) {
-               this.selectedItemBgColor = selectedItemBgColor;
+               if (selectedItemBgColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               Color old = this.selectedItemBgColor;
+               if (old == null ? selectedItemBgColor != null : !old.equals(selectedItemBgColor)) {
+                       this.selectedItemBgColor = selectedItemBgColor;
+                       propChangeSupport.firePropertyChange(SELECTED_ITEM_BG_COLOR, old, selectedItemBgColor);
+               }
        }
 
        private Color selectedItemBgColor = Color.orange;
@@ -466,11 +519,17 @@ public final class AppConfig {
                return invalidBgColor;
        }
 
+       public static final String INVALID_BG_COLOR = "invalidBgColor";
+
        public void setInvalidBgColor(Color invalidBgColor) {
                if (invalidBgColor == null) {
                        throw new IllegalArgumentException();
                }
-               this.invalidBgColor = invalidBgColor;
+               Color old = this.invalidBgColor;
+               if (old == null ? invalidBgColor != null : !old.equals(invalidBgColor)) {
+                       this.invalidBgColor = invalidBgColor;
+                       propChangeSupport.firePropertyChange(INVALID_BG_COLOR, old, invalidBgColor);
+               }
        }
 
        private Color invalidBgColor = Color.red.brighter().brighter();
@@ -484,11 +543,17 @@ public final class AppConfig {
                return compressionQuality;
        }
 
+       public static final String COMPRESSION_QUALITY = "compressionQuality";
+
        public void setCompressionQuality(float compressionQuality) {
                if (compressionQuality < .1f || compressionQuality > 1f) {
                        throw new IllegalArgumentException();
                }
-               this.compressionQuality = compressionQuality;
+               float old = this.compressionQuality;
+               if (old != compressionQuality) {
+                       this.compressionQuality = compressionQuality;
+                       propChangeSupport.firePropertyChange(COMPRESSION_QUALITY, old, compressionQuality);
+               }
        }
 
        private float compressionQuality = .8f;
@@ -502,9 +567,19 @@ public final class AppConfig {
                return exportPresetWarningsForegroundColor;
        }
 
-       public void setExportPresetWarningsForegroundColor(
-                       Color exportPresetWarningsForegroundColor) {
-               this.exportPresetWarningsForegroundColor = exportPresetWarningsForegroundColor;
+       public static final String EXPORT_PRESET_WARNINGS_FOREGROUND_COLOR = "exportPresetWarningsForegroundColor";
+
+       public void setExportPresetWarningsForegroundColor(Color exportPresetWarningsForegroundColor) {
+               if (exportPresetWarningsForegroundColor == null) {
+                       throw new IllegalArgumentException();
+               }
+               Color old = this.exportPresetWarningsForegroundColor;
+               if (old == null ? exportPresetWarningsForegroundColor != null
+                               : !old.equals(exportPresetWarningsForegroundColor)) {
+                       this.exportPresetWarningsForegroundColor = exportPresetWarningsForegroundColor;
+                       propChangeSupport.firePropertyChange(EXPORT_PRESET_WARNINGS_FOREGROUND_COLOR, old,
+                                       exportPresetWarningsForegroundColor);
+               }
        }
 
        private Color exportPresetWarningsForegroundColor = Color.red;
@@ -518,11 +593,17 @@ public final class AppConfig {
                return jarTransferBufferSize;
        }
 
+       public static final String JAR_TRANSFER_BUFFER_SIZE = "jarTransferBufferSize";
+
        public void setJarTransferBufferSize(int jarTransferBufferSize) {
                if (jarTransferBufferSize <= 0) {
                        throw new IllegalArgumentException();
                }
-               this.jarTransferBufferSize = jarTransferBufferSize;
+               int old = this.jarTransferBufferSize;
+               if (old != jarTransferBufferSize) {
+                       this.jarTransferBufferSize = jarTransferBufferSize;
+                       propChangeSupport.firePropertyChange(JAR_TRANSFER_BUFFER_SIZE, old, jarTransferBufferSize);
+               }
        }
 
        private int jarTransferBufferSize = 4096;
@@ -536,6 +617,8 @@ public final class AppConfig {
                return zipNameEncoding;
        }
 
+       public static final String ZIP_NAME_ENCODING = "zipNameEncoding";
+
        public void setZipNameEncoding(String zipNameEncoding) {
                if (zipNameEncoding == null) {
                        throw new IllegalArgumentException();
@@ -545,7 +628,11 @@ public final class AppConfig {
                } catch (Exception ex) {
                        throw new RuntimeException("unsupported charset: " + zipNameEncoding);
                }
-               this.zipNameEncoding = zipNameEncoding;
+               String old = this.zipNameEncoding;
+               if (old == null ? zipNameEncoding != null : !old.equals(zipNameEncoding)) {
+                       this.zipNameEncoding = zipNameEncoding;
+                       propChangeSupport.firePropertyChange(ZIP_NAME_ENCODING, old, zipNameEncoding);
+               }
        }
 
        private String zipNameEncoding = "csWindows31J";
@@ -559,11 +646,17 @@ public final class AppConfig {
                return disabledCellForegroundColor;
        }
 
+       public static final String DISABLED_CELL_FOREGROUND_COLOR = "disabledCellForegroundColor";
+
        public void setDisabledCellForegroundColor(Color disabledCellForegroundColor) {
                if (disabledCellForegroundColor == null) {
                        throw new IllegalArgumentException();
                }
-               this.disabledCellForegroundColor = disabledCellForegroundColor;
+               Color old = this.disabledCellForegroundColor;
+               if (old == null ? disabledCellForegroundColor != null : !old.equals(disabledCellForegroundColor)) {
+                       this.disabledCellForegroundColor = disabledCellForegroundColor;
+                       propChangeSupport.firePropertyChange(DISABLED_CELL_FOREGROUND_COLOR, old, disabledCellForegroundColor);
+               }
        }
 
        private Color disabledCellForegroundColor = Color.gray;
@@ -578,11 +671,17 @@ public final class AppConfig {
                return dirWatchInterval;
        }
 
+       public static final String DIR_WATCH_INTERVAL = "dirWatchInterval";
+
        public void setDirWatchInterval(int dirWatchInterval) {
                if (dirWatchInterval <= 0) {
                        throw new IllegalArgumentException();
                }
-               this.dirWatchInterval = dirWatchInterval;
+               int old = this.dirWatchInterval;
+               if (old != dirWatchInterval) {
+                       this.dirWatchInterval = dirWatchInterval;
+                       propChangeSupport.firePropertyChange(DIR_WATCH_INTERVAL, old, dirWatchInterval);
+               }
        }
 
        private int dirWatchInterval = 7 * 1000;
@@ -596,8 +695,14 @@ public final class AppConfig {
                return enableDirWatch;
        }
 
+       public static final String ENABLE_DIR_WATCH = "enableDirWatch";
+
        public void setEnableDirWatch(boolean enableDirWatch) {
-               this.enableDirWatch = enableDirWatch;
+               boolean old = this.enableDirWatch;
+               if (old != enableDirWatch) {
+                       this.enableDirWatch = enableDirWatch;
+                       propChangeSupport.firePropertyChange(ENABLE_DIR_WATCH, old, enableDirWatch);
+               }
        }
 
        private boolean enableDirWatch = true;
@@ -611,11 +716,17 @@ public final class AppConfig {
                return fileTransferBufferSize;
        }
 
+       public static final String FILE_TRANSFER_BUFFER_SIZE = "fileTransferBufferSize";
+
        public void setFileTransferBufferSize(int fileTransferBufferSize) {
                if (fileTransferBufferSize <= 0) {
                        throw new IllegalArgumentException();
                }
-               this.fileTransferBufferSize = fileTransferBufferSize;
+               int old = this.fileTransferBufferSize;
+               if (old != fileTransferBufferSize) {
+                       this.fileTransferBufferSize = fileTransferBufferSize;
+                       propChangeSupport.firePropertyChange(FILE_TRANSFER_BUFFER_SIZE, old, fileTransferBufferSize);
+               }
        }
 
        private int fileTransferBufferSize = 4096;
@@ -629,11 +740,17 @@ public final class AppConfig {
                return previewIndeicatorDelay;
        }
 
+       public static final String PREVIEW_INDEICATOR_DELAY = "previewIndeicatorDelay";
+
        public void setPreviewIndeicatorDelay(long previewIndeicatorDelay) {
                if (previewIndeicatorDelay < 0) {
                        throw new IllegalArgumentException();
                }
-               this.previewIndeicatorDelay = previewIndeicatorDelay;
+               long old = this.previewIndeicatorDelay;
+               if (old != previewIndeicatorDelay) {
+                       this.previewIndeicatorDelay = previewIndeicatorDelay;
+                       propChangeSupport.firePropertyChange(PREVIEW_INDEICATOR_DELAY, old, previewIndeicatorDelay);
+               }
        }
 
        private long previewIndeicatorDelay = 300;
@@ -647,9 +764,15 @@ public final class AppConfig {
                return informationDialogOpenMethod;
        }
 
+       public static final String INFORMATION_DIALOG_OPEN_METHOD = "informationDialogOpenMethod";
+
        public void setInformationDialogOpenMethod(
                        boolean informationDialogOpenMethod) {
-               this.informationDialogOpenMethod = informationDialogOpenMethod;
+               boolean old = this.informationDialogOpenMethod;
+               if (old != informationDialogOpenMethod) {
+                       this.informationDialogOpenMethod = informationDialogOpenMethod;
+                       propChangeSupport.firePropertyChange("informationDialogOpenMethod", old, informationDialogOpenMethod);
+               }
        }
 
        private boolean informationDialogOpenMethod = true;
@@ -664,8 +787,14 @@ public final class AppConfig {
                return noRemoveLog;
        }
 
+       public static final String NO_REMOVE_LOG = "noRemoveLog";
+
        public void setNoRemoveLog(boolean noRemoveLog) {
-               this.noRemoveLog = noRemoveLog;
+               boolean old = this.noRemoveLog;
+               if (old != noRemoveLog) {
+                       this.noRemoveLog = noRemoveLog;
+                       propChangeSupport.firePropertyChange(NO_REMOVE_LOG, old, noRemoveLog);
+               }
        }
 
        private boolean noRemoveLog = false;
@@ -680,11 +809,17 @@ public final class AppConfig {
                return gridColor;
        }
 
+       public static final String GRID_COLOR = "gridColor";
+
        public void setGridColor(Color gridColor) {
                if (gridColor == null) {
                        throw new IllegalArgumentException();
                }
-               this.gridColor = gridColor;
+               Color old = this.gridColor;
+               if (old == null ? gridColor != null : !old.equals(gridColor)) {
+                       this.gridColor = gridColor;
+                       propChangeSupport.firePropertyChange(GRID_COLOR, old, gridColor);
+               }
        }
 
        private Color gridColor = Color.gray;
@@ -698,17 +833,29 @@ public final class AppConfig {
                return enableAutoColorChange;
        }
 
+       public static final String ENABLE_AUTO_COLOR_CHANGE = "enableAutoColorChange";
+
        public void setEnableAutoColorChange(boolean enableAutoColorChange) {
-               this.enableAutoColorChange = enableAutoColorChange;
+               boolean old = this.enableAutoColorChange;
+               if (old != enableAutoColorChange) {
+                       this.enableAutoColorChange = enableAutoColorChange;
+                       propChangeSupport.firePropertyChange(ENABLE_AUTO_COLOR_CHANGE, old, enableAutoColorChange);
+               }
        }
 
        private boolean enableAutoColorChange = true;
 
+       public static final String AUTHOR_EDIT_CONFLICT_BG_COLOR = "authorEditConflictBgColor";
+
        public void setAuthorEditConflictBgColor(Color authorEditConflictBgColor) {
                if (authorEditConflictBgColor == null) {
                        throw new IllegalArgumentException();
                }
-               this.authorEditConflictBgColor = authorEditConflictBgColor;
+               Color old = this.authorEditConflictBgColor;
+               if (old == null ? authorEditConflictBgColor != null : !old.equals(authorEditConflictBgColor)) {
+                       this.authorEditConflictBgColor = authorEditConflictBgColor;
+                       propChangeSupport.firePropertyChange(AUTHOR_EDIT_CONFLICT_BG_COLOR, old, authorEditConflictBgColor);
+               }
        }
 
        /**
@@ -723,8 +870,14 @@ public final class AppConfig {
        Color authorEditConflictBgColor = Color.yellow;
 
 
-       public void setMainFrameMaxWidth(int width) {
-               this.mainFrameMaxWidth = width;
+       public static final String MAIN_FRAME_MAX_WIDTH = "mainFrameMaxWidth";
+
+       public void setMainFrameMaxWidth(int mainFrameMaxWidth) {
+               int old = mainFrameMaxWidth;
+               if (old != mainFrameMaxWidth) {
+                       this.mainFrameMaxWidth = mainFrameMaxWidth;
+                       propChangeSupport.firePropertyChange(MAIN_FRAME_MAX_WIDTH, old, mainFrameMaxWidth);
+               }
        }
 
        /**
@@ -738,8 +891,14 @@ public final class AppConfig {
 
        private int mainFrameMaxWidth = 800;
 
-       public void setMainFrameMaxHeight(int height) {
-               this.mainFrameMaxHeight = height;
+       public static final String MAIN_FRAME_MAX_HEIGHT = "mainFrameMaxHeight";
+
+       public void setMainFrameMaxHeight(int mainFrameMaxHeight) {
+               int old = this.mainFrameMaxHeight;
+               if (old != mainFrameMaxHeight) {
+                       this.mainFrameMaxHeight = mainFrameMaxHeight;
+                       propChangeSupport.firePropertyChange(MAIN_FRAME_MAX_HEIGHT, old, mainFrameMaxHeight);
+               }
        }
 
        /**
@@ -763,8 +922,14 @@ public final class AppConfig {
                return notDisableLayerTab;
        }
 
+       public static final String NOT_DISABLE_LAYER_TAB = "notDisableLayerTab";
+
        public void setNotDisableLayerTab(boolean notDisableLayerTab) {
-               this.notDisableLayerTab = notDisableLayerTab;
+               boolean old = this.notDisableLayerTab;
+               if (old != notDisableLayerTab) {
+                       this.notDisableLayerTab = notDisableLayerTab;
+                       propChangeSupport.firePropertyChange(NOT_DISABLE_LAYER_TAB, old, notDisableLayerTab);
+               }
        }
 
        private boolean notDisableLayerTab;
@@ -781,8 +946,14 @@ public final class AppConfig {
                return purgeLogDays;
        }
 
+       public static final String PURGE_LOG_DAYS = "purgeLogDays";
+
        public void setPurgeLogDays(long purgeLogDays) {
-               this.purgeLogDays = purgeLogDays;
+               long old = this.purgeLogDays;
+               if (old != purgeLogDays) {
+                       this.purgeLogDays = purgeLogDays;
+                       propChangeSupport.firePropertyChange(PURGE_LOG_DAYS, old, purgeLogDays);
+               }
        }
 
        private long purgeLogDays = 10;
@@ -791,11 +962,17 @@ public final class AppConfig {
                return partsColorGroupPattern;
        }
 
+       public static final String PARTS_COLOR_GROUP_PATTERN = "partsColorGroupPattern";
+
        public void setPartsColorGroupPattern(String pattern) {
                if (pattern != null && pattern.trim().length() > 0) {
                        Pattern.compile(pattern);
                }
-               partsColorGroupPattern = pattern;
+               String old = this.partsColorGroupPattern;
+               if (old == null ? pattern != null : !old.equals(pattern)) {
+                       this.partsColorGroupPattern = pattern;
+                       propChangeSupport.firePropertyChange(PARTS_COLOR_GROUP_PATTERN, old, pattern);
+               }
        }
 
        private String partsColorGroupPattern = "^.*\\(@\\).*$";
@@ -806,11 +983,17 @@ public final class AppConfig {
                return selectPanelTitleColor;
        }
 
-       public void setSelectPanelTitleColor(Color color) {
-               if (color == null) {
+       public static final String SELECT_PANEL_TITLE_COLOR = "selectPanelTitleColor";
+
+       public void setSelectPanelTitleColor(Color selectPanelTitleColor) {
+               if (selectPanelTitleColor == null) {
                        throw new IllegalArgumentException();
                }
-               selectPanelTitleColor = color;
+               Color old = this.selectPanelTitleColor;
+               if (old == null ? selectPanelTitleColor != null : !old.equals(selectPanelTitleColor)) {
+                       this.selectPanelTitleColor = selectPanelTitleColor;
+                       propChangeSupport.firePropertyChange(SELECT_PANEL_TITLE_COLOR, old, selectPanelTitleColor);
+               }
        }
 
        private boolean enableAutoShrinkPanel;
@@ -819,22 +1002,40 @@ public final class AppConfig {
                return enableAutoShrinkPanel;
        }
 
+       public static final String ENABLE_AUTO_SHRINK_PANEL = "enableAutoShrinkPanel";
+
        public void setEnableAutoShrinkPanel(boolean enableAutoShrinkPanel) {
-               this.enableAutoShrinkPanel = enableAutoShrinkPanel;
+               boolean old = this.enableAutoShrinkPanel;
+               if (old != enableAutoShrinkPanel) {
+                       this.enableAutoShrinkPanel = enableAutoShrinkPanel;
+                       propChangeSupport.firePropertyChange(ENABLE_AUTO_SHRINK_PANEL, old, enableAutoShrinkPanel);
+               }
        }
 
        public boolean isDisableWatchDirIfNotWritable() {
                return disableWatchDirIfNotWritable;
        }
 
+       public static final String DISABLE_WATCH_DIR_IF_NOT_WRITABLE = "disableWatchDirIfNotWritable";
+
        public void setDisableWatchDirIfNotWritable(boolean disableWatchDirIfNotWritable) {
-               this.disableWatchDirIfNotWritable = disableWatchDirIfNotWritable;
+               boolean old = this.disableWatchDirIfNotWritable;
+               if (old != disableWatchDirIfNotWritable) {
+                       this.disableWatchDirIfNotWritable = disableWatchDirIfNotWritable;
+                       propChangeSupport.firePropertyChange(DISABLE_WATCH_DIR_IF_NOT_WRITABLE, old, disableWatchDirIfNotWritable);
+               }
        }
 
        private boolean disableWatchDirIfNotWritable = true;
 
+       public static final String ENABLE_PNG_SUPPORT_FOR_WINDOWS = "enablePNGSupportForWindows";
+
        public void setEnablePNGSupportForWindows(boolean enablePNGSupportForWindows) {
-               this.enablePNGSupportForWindows = enablePNGSupportForWindows;
+               boolean old = this.enablePNGSupportForWindows;
+               if (old != enablePNGSupportForWindows) {
+                       this.enablePNGSupportForWindows = enablePNGSupportForWindows;
+                       propChangeSupport.firePropertyChange(ENABLE_PNG_SUPPORT_FOR_WINDOWS, old, enablePNGSupportForWindows);
+               }
        }
 
        public boolean isEnablePNGSupportForWindows() {
@@ -848,9 +1049,16 @@ public final class AppConfig {
         */
        private double renderingOptimizeThresholdForNormal = 2.;
 
+       public static final String RENDERING_OPTIMIZE_THRESHOLD_FOR_NORMAL = "renderingOptimizeThresholdForNormal";
+
        public void setRenderingOptimizeThresholdForNormal(
                        double renderingOptimizeThresholdForNormal) {
-               this.renderingOptimizeThresholdForNormal = renderingOptimizeThresholdForNormal;
+               double old = this.renderingOptimizeThresholdForNormal;
+               if (old != renderingOptimizeThresholdForNormal) {
+                       this.renderingOptimizeThresholdForNormal = renderingOptimizeThresholdForNormal;
+                       propChangeSupport.firePropertyChange(RENDERING_OPTIMIZE_THRESHOLD_FOR_NORMAL, old,
+                                       renderingOptimizeThresholdForNormal);
+               }
        }
 
        public double getRenderingOptimizeThresholdForNormal() {
@@ -861,9 +1069,16 @@ public final class AppConfig {
         */
        private double renderingOptimizeThresholdForCheck = 0.;
 
+       public static final String RENDERING_OPTIMIZE_THRESHOLD_FOR_CHECK = "renderingOptimizeThresholdForCheck";
+
        public void setRenderingOptimizeThresholdForCheck(
                        double renderingOptimizeThresholdForCheck) {
-               this.renderingOptimizeThresholdForCheck = renderingOptimizeThresholdForCheck;
+               double old = this.renderingOptimizeThresholdForCheck;
+               if (old != renderingOptimizeThresholdForCheck) {
+                       this.renderingOptimizeThresholdForCheck = renderingOptimizeThresholdForCheck;
+                       propChangeSupport.firePropertyChange(RENDERING_OPTIMIZE_THRESHOLD_FOR_CHECK, old,
+                                       renderingOptimizeThresholdForCheck);
+               }
        }
 
        public double getRenderingOptimizeThresholdForCheck() {
@@ -875,8 +1090,14 @@ public final class AppConfig {
         */
        private boolean enableInterpolationBicubic = true;
 
+       public static final String ENABLE_INTERPOLATION_BICUBIC = "enableInterpolationBicubic";
+
        public void setEnableInterpolationBicubic(boolean enableInterpolationBicubic) {
-               this.enableInterpolationBicubic = enableInterpolationBicubic;
+               boolean old = this.enableInterpolationBicubic;
+               if (old != enableInterpolationBicubic) {
+                       this.enableInterpolationBicubic = enableInterpolationBicubic;
+                       propChangeSupport.firePropertyChange(ENABLE_INTERPOLATION_BICUBIC, old, enableInterpolationBicubic);
+               }
        }
 
        public boolean isEnableInterpolationBicubic() {
@@ -892,8 +1113,17 @@ public final class AppConfig {
                return predefinedZoomRanges;
        }
 
+       public static final String PREDEFINED_ZOOM_RANGES = "predefinedZoomRanges";
+
        public void setPredefinedZoomRanges(String predefinedZoomRanges) {
-               this.predefinedZoomRanges = predefinedZoomRanges;
+               if (predefinedZoomRanges == null) {
+                       throw new IllegalArgumentException();
+               }
+               String old = this.predefinedZoomRanges;
+               if (old == null ? predefinedZoomRanges != null : !old.equals(predefinedZoomRanges)) {
+                       this.predefinedZoomRanges = predefinedZoomRanges;
+                       propChangeSupport.firePropertyChange(PREDEFINED_ZOOM_RANGES, old, predefinedZoomRanges);
+               }
        }
 
        /**
@@ -905,8 +1135,14 @@ public final class AppConfig {
                return enableZoomPanel;
        }
 
+       public static final String ENABLE_ZOOM_PANEL = "enableZoomPanel";
+
        public void setEnableZoomPanel(boolean enableZoomPanel) {
-               this.enableZoomPanel = enableZoomPanel;
+               boolean old = this.enableZoomPanel;
+               if (old != enableZoomPanel) {
+                       this.enableZoomPanel = enableZoomPanel;
+                       propChangeSupport.firePropertyChange(ENABLE_ZOOM_PANEL, old, enableZoomPanel);
+               }
        }
 
        /**
@@ -918,8 +1154,14 @@ public final class AppConfig {
                return zoomPanelActivationArea;
        }
 
+       public static final String ZOOM_PANEL_ACTIVATION_AREA = "zoomPanelActivationArea";
+
        public void setZoomPanelActivationArea(int zoomPanelActivationArea) {
-               this.zoomPanelActivationArea = zoomPanelActivationArea;
+               int old = this.zoomPanelActivationArea;
+               if (old != zoomPanelActivationArea) {
+                       this.zoomPanelActivationArea = zoomPanelActivationArea;
+                       propChangeSupport.firePropertyChange(ZOOM_PANEL_ACTIVATION_AREA, old, zoomPanelActivationArea);
+               }
        }
 
        /**
@@ -927,8 +1169,14 @@ public final class AppConfig {
         */
        private boolean enableRenderingHints = true;
 
+       public static final String ENABLE_RENDERING_HINTS = "enableRenderingHints";
+
        public void setEnableRenderingHints(boolean enableRenderingHints) {
-               this.enableRenderingHints = enableRenderingHints;
+               boolean old = this.enableRenderingHints;
+               if (old != enableRenderingHints) {
+                       this.enableRenderingHints = enableRenderingHints;
+                       propChangeSupport.firePropertyChange(ENABLE_RENDERING_HINTS, old, enableRenderingHints);
+               }
        }
 
        public boolean isEnableRenderingHints() {
@@ -944,18 +1192,32 @@ public final class AppConfig {
                return drawGridMask;
        }
 
+       public static final String DRAW_GRID_MASK = "drawGridMask";
+
        public void setDrawGridMask(int drawGridMask) {
-               this.drawGridMask = drawGridMask & 0x03;
+               drawGridMask &= 0x03;
+               int old = this.drawGridMask;
+               if (old != drawGridMask) {
+                       this.drawGridMask = drawGridMask;
+                       propChangeSupport.firePropertyChange(DRAW_GRID_MASK, old, drawGridMask);
+               }
        }
 
        private int previewGridColor = 0x7f7f0000;
 
+       @StringConverterSpec(UnsignedHexStringConverter.class)
        public int getPreviewGridColor() {
                return previewGridColor;
        }
 
+       public static final String PREVIEW_GRID_COLOR = "previewGridColor";
+
        public void setPreviewGridColor(int previewGridColor) {
-               this.previewGridColor = previewGridColor;
+               int old = this.previewGridColor;
+               if (old != previewGridColor) {
+                       this.previewGridColor = previewGridColor;
+                       propChangeSupport.firePropertyChange(PREVIEW_GRID_COLOR, old, previewGridColor);
+               }
        }
 
        private int previewGridSize = 20;
@@ -964,8 +1226,14 @@ public final class AppConfig {
                return previewGridSize;
        }
 
+       public static final String PREVIEW_GRID_SIZE = "previewGridSize";
+
        public void setPreviewGridSize(int previewGridSize) {
-               this.previewGridSize = previewGridSize;
+               int old = this.previewGridSize;
+               if (old != previewGridSize) {
+                       this.previewGridSize = previewGridSize;
+                       propChangeSupport.firePropertyChange(PREVIEW_GRID_SIZE, old, previewGridSize);
+               }
        }
 
        /**
@@ -977,9 +1245,15 @@ public final class AppConfig {
                return previewUnfilledSpaceForCheckMode;
        }
 
-       public void setPreviewUnfilledSpaceForCheckMode(
-                       int previewUnfilledSpaceForCheckMode) {
-               this.previewUnfilledSpaceForCheckMode = previewUnfilledSpaceForCheckMode;
+       public static final String PREVIEW_UNFILLED_SPACE_FOR_CHECK_MODE = "previewUnfilledSpaceForCheckMode";
+
+       public void setPreviewUnfilledSpaceForCheckMode(int previewUnfilledSpaceForCheckMode) {
+               int old = this.previewUnfilledSpaceForCheckMode;
+               if (old != previewUnfilledSpaceForCheckMode) {
+                       this.previewUnfilledSpaceForCheckMode = previewUnfilledSpaceForCheckMode;
+                       propChangeSupport.firePropertyChange(PREVIEW_UNFILLED_SPACE_FOR_CHECK_MODE, old,
+                                       previewUnfilledSpaceForCheckMode);
+               }
        }
 
        /**
@@ -991,8 +1265,14 @@ public final class AppConfig {
                return enableCheckInfoTooltip;
        }
 
+       public static final String ENABLE_CHECK_INFO_TOOLTIP = "enableCheckInfoTooltip";
+
        public void setEnableCheckInfoTooltip(boolean enableCheckInfoTooltip) {
-               this.enableCheckInfoTooltip = enableCheckInfoTooltip;
+               boolean old = this.enableCheckInfoTooltip;
+               if (old != enableCheckInfoTooltip) {
+                       this.enableCheckInfoTooltip = enableCheckInfoTooltip;
+                       propChangeSupport.firePropertyChange(ENABLE_CHECK_INFO_TOOLTIP, old, enableCheckInfoTooltip);
+               }
        }
 
        /**
@@ -1004,8 +1284,14 @@ public final class AppConfig {
                return wheelScrollUnit;
        }
 
+       public static final String WHEEL_SCROLL_UNIT = "wheelScrollUnit";
+
        public void setWheelScrollUnit(int wheelScrollUnit) {
-               this.wheelScrollUnit = wheelScrollUnit;
+               int old = this.wheelScrollUnit;
+               if (old != wheelScrollUnit) {
+                       this.wheelScrollUnit = wheelScrollUnit;
+                       propChangeSupport.firePropertyChange(WHEEL_SCROLL_UNIT, old, wheelScrollUnit);
+               }
        }
 
        /**
@@ -1018,8 +1304,14 @@ public final class AppConfig {
                return enableOffscreenWallpaper;
        }
 
+       public static final String ENABLE_OFFSCREEN_WALLPAPER = "enableOffscreenWallpaper";
+
        public void setEnableOffscreenWallpaper(boolean enableOffscreenWallpaper) {
-               this.enableOffscreenWallpaper = enableOffscreenWallpaper;
+               boolean old = this.enableOffscreenWallpaper;
+               if (old != enableOffscreenWallpaper) {
+                       this.enableOffscreenWallpaper = enableOffscreenWallpaper;
+                       propChangeSupport.firePropertyChange(ENABLE_OFFSCREEN_WALLPAPER, old, enableOffscreenWallpaper);
+               }
        }
 
        /**
@@ -1031,10 +1323,17 @@ public final class AppConfig {
                return offscreenWallpaperSize;
        }
 
+       private static final String OFFSCREEN_WALLPAPER_SIZE = "offscreenWallpaperSize";
+
        public void setOffscreenWallpaperSize(int offscreenWallpaperSize) {
-               this.offscreenWallpaperSize = offscreenWallpaperSize;
+               int old = this.offscreenWallpaperSize;
+               if (old != offscreenWallpaperSize) {
+                       this.offscreenWallpaperSize = offscreenWallpaperSize;
+                       propChangeSupport.firePropertyChange(OFFSCREEN_WALLPAPER_SIZE, old, offscreenWallpaperSize);
+               }
        }
 
+
        /**
         * ランダム選択パーツの履歴数
         */
@@ -1044,8 +1343,14 @@ public final class AppConfig {
                return randomChooserMaxHistory;
        }
 
+       public static final String RANDOM_CHOOSER_MAX_HISTORY = "randomChooserMaxHistory";
+
        public void setRandomChooserMaxHistory(int randomChooserMaxHistory) {
-               this.randomChooserMaxHistory = randomChooserMaxHistory;
+               int old = this.randomChooserMaxHistory;
+               if (old != randomChooserMaxHistory) {
+                       this.randomChooserMaxHistory = randomChooserMaxHistory;
+                       propChangeSupport.firePropertyChange(RANDOM_CHOOSER_MAX_HISTORY, old, randomChooserMaxHistory);
+               }
        }
 
        /**
@@ -1057,8 +1362,14 @@ public final class AppConfig {
                return defaultFontSize;
        }
 
+       public static final String DEFAULT_FONT_SIZE = "defaultFontSize";
+
        public void setDefaultFontSize(int defaultFontSize) {
-               this.defaultFontSize = defaultFontSize;
+               int old = this.defaultFontSize;
+               if (old != defaultFontSize) {
+                       this.defaultFontSize = defaultFontSize;
+                       propChangeSupport.firePropertyChange(DEFAULT_FONT_SIZE, old, defaultFontSize);
+               }
        }
 
        /**
@@ -1070,8 +1381,17 @@ public final class AppConfig {
                return fontPriority;
        }
 
+       public static final String FONT_PRIORITY = "fontPriority";
+
        public void setFontPriority(String fontPriority) {
-               this.fontPriority = fontPriority;
+               if (fontPriority == null) {
+                       throw new IllegalArgumentException();
+               }
+               String old = this.fontPriority;
+               if (old == null ? fontPriority != null : !old.equals(fontPriority)) {
+                       this.fontPriority = fontPriority;
+                       propChangeSupport.firePropertyChange(FONT_PRIORITY, old, fontPriority);
+               }
        }
 
        /**
@@ -1083,7 +1403,29 @@ public final class AppConfig {
                return enableRestoreWindow;
        }
 
+       public static final String ENABLE_RESTORE_WINDOW = "enableRestoreWindow";
+
        public void setEnableRestoreWindow(boolean enableRestoreWindow) {
-               this.enableRestoreWindow = enableRestoreWindow;
+               boolean old = this.enableRestoreWindow;
+               if (old != enableRestoreWindow) {
+                       this.enableRestoreWindow = enableRestoreWindow;
+                       propChangeSupport.firePropertyChange(ENABLE_RESTORE_WINDOW, old, enableRestoreWindow);
+               }
+       }
+
+       private boolean enableColorAdvancedSettings = true;
+
+       public boolean isEnableColorAdvancedSettings() {
+               return enableColorAdvancedSettings;
+       }
+
+       public static final String ENABLE_COLOR_ADVANCED_SETTINGS = "enableColorAdvancedSettings";
+
+       public void setEnableColorAdvancedSettings(boolean enableColorAdvancedSettings) {
+               boolean old = this.enableColorAdvancedSettings;
+               if (old != enableColorAdvancedSettings) {
+                       this.enableColorAdvancedSettings = enableColorAdvancedSettings;
+                       propChangeSupport.firePropertyChange(ENABLE_COLOR_ADVANCED_SETTINGS, old, enableRestoreWindow);
+               }
        }
 }
index 6e75354..6546284 100644 (file)
@@ -2,11 +2,17 @@ package charactermanaj.ui;
 
 import java.awt.BorderLayout;
 import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Event;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.GridLayout;
 import java.awt.Insets;
 import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ComponentAdapter;
@@ -16,9 +22,14 @@ import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.io.BufferedReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.Semaphore;
@@ -40,15 +51,20 @@ import javax.swing.JComponent;
 import javax.swing.JDialog;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JRootPane;
+import javax.swing.JScrollPane;
 import javax.swing.JSlider;
 import javax.swing.JSpinner;
 import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.JToolBar;
 import javax.swing.KeyStroke;
 import javax.swing.SpinnerNumberModel;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
 
 import charactermanaj.Main;
 import charactermanaj.graphics.colormodel.ColorModel;
@@ -63,13 +79,15 @@ import charactermanaj.model.PartsIdentifier;
 import charactermanaj.ui.model.ColorChangeEvent;
 import charactermanaj.ui.model.ColorChangeListener;
 import charactermanaj.ui.util.SpinnerWheelSupportListener;
+import charactermanaj.util.ErrorMessageHelper;
 import charactermanaj.util.LocalizedResourcePropertyLoader;
+import charactermanaj.util.UIHelper;
 
 
 /**
  * カラーダイアログ.<br>
  * カラーダイアログはカテゴリ別に関連づけられており、カテゴリ内の各レイヤーに対応するタブを持つ.<br>
- * 
+ *
  * @author seraphy
  */
 public class ColorDialog extends JDialog {
@@ -90,46 +108,51 @@ public class ColorDialog extends JDialog {
         * レイヤーごとのタブのマップ
         */
        private HashMap<Layer, ColorDialogTabPanel> tabs = new HashMap<Layer, ColorDialogTabPanel>();
-       
+
        /**
         * タブペイン
         */
        private JTabbedPane tabbedPane;
-       
+
        /**
         * レイヤーに対するタブインデックスのマップ
         */
        private HashMap<Layer, Integer> tabbedPaneIndexMap = new HashMap<Layer, Integer>();
-       
+
        /**
         * 色変更イベントのリスナのコレクション
         */
-       private LinkedList<ColorChangeListener> listeners = new LinkedList<ColorChangeListener>();
+       private final EventListenerList listeners = new EventListenerList();
 
        /**
         * キャプションのプレフィックス
         */
        private String captionBase;
-       
+
        /**
         * 現在表示しているカラー情報の対象としているパーツ識別子
         */
        private PartsIdentifier partsIdentifier;
-       
+
        /**
         * カテゴリ全体に適用するチェックボックス
         */
        private JCheckBox chkApplyAll;
-       
+
        /**
         * リセットアクション
         */
        private Action actReset;
 
-       
+       /**
+        * 詳細設定の表示切り替えチェックボックス
+        */
+       private JCheckBox chkShowAdvancedSettings;
+
+
        /**
         * コンストラクタ
-        * 
+        *
         * @param parent
         *            親フレーム
         * @param partsCategory
@@ -141,8 +164,9 @@ public class ColorDialog extends JDialog {
                super(parent);
                this.partsCategory = partsCategory;
 
-               final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance().getLocalizedProperties("languages/colordialog");
-               
+               final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
+                               .getLocalizedProperties("languages/colordialog");
+
                String caption = strings.getProperty("colordialog.caption");
                String name = partsCategory.getLocalizedCategoryName();
                captionBase = caption + name;
@@ -164,12 +188,12 @@ public class ColorDialog extends JDialog {
                                actHide.actionPerformed(new ActionEvent(ColorDialog.this, 0, "closing"));
                        }
                });
-               
+
                Container container = getContentPane();
-               
+
                this.tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT);
                for (final Layer layer : partsCategory.getLayers()) {
-                       
+
                        final ColorDialogTabPanel tabContainer = new ColorDialogTabPanel(this, layer, colorGroups);
                        final ColorChangeListener innerListener = new ColorChangeListener() {
                                private Semaphore semaphore = new Semaphore(1); // イベントが循環発生することを防ぐ
@@ -239,7 +263,7 @@ public class ColorDialog extends JDialog {
                btnPanel.setLayout(gbl);
 
                int colIdx = 0;
-               
+
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = colIdx++;
                gbc.gridy = 0;
@@ -260,7 +284,7 @@ public class ColorDialog extends JDialog {
                        }
                });
                btnPanel.add(chkApplyAll, gbc);
-               
+
                gbc.gridx = colIdx++;
                gbc.gridy = 0;
                gbc.weightx = 1.;
@@ -268,7 +292,7 @@ public class ColorDialog extends JDialog {
 
                // 「適用」ボタン、アプリケーション設定により有無を選択できる.
                JButton btnApply = null;
-               AppConfig appConfig = AppConfig.getInstance();
+               final AppConfig appConfig = AppConfig.getInstance();
                if ( !appConfig.isEnableAutoColorChange()) {
                        gbc.gridx = colIdx++;
                        gbc.gridy = 0;
@@ -283,10 +307,60 @@ public class ColorDialog extends JDialog {
                JButton btnReset = new JButton(actReset);
                btnPanel.add(btnReset, gbc);
 
+               // ダイアログ上部のボタンバー
+               UIHelper uiUtl = UIHelper.getInstance();
+               JButton copyBtn = uiUtl.createIconButton("icons/copy.png");
+               JButton pasteBtn = uiUtl.createIconButton("icons/paste.png");
+
+               copyBtn.setToolTipText(strings.getProperty("copy"));
+               pasteBtn.setToolTipText(strings.getProperty("paste"));
+
+               Action actCopy = new AbstractAction() {
+                       private static final long serialVersionUID = 1L;
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
+                               onCopy(shift);
+                       }
+               };
+               Action actPaste = new AbstractAction() {
+                       private static final long serialVersionUID = 1L;
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               onPaste();
+                       }
+               };
+
+               copyBtn.addActionListener(actCopy);
+               pasteBtn.addActionListener(actPaste);
+
+               final JToolBar toolBar = new JToolBar();
+               toolBar.setFloatable(false);
+               toolBar.add(copyBtn);
+               toolBar.add(pasteBtn);
+
+               AbstractAction actShowAdvancedSetting = new AbstractAction(
+                               strings.getProperty("chk.showAdvancedSettings")) {
+                       private static final long serialVersionUID = 1L;
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               onChangeShowAdvancedSettings();
+                       }
+               };
+               chkShowAdvancedSettings = new JCheckBox(actShowAdvancedSetting);
+               chkShowAdvancedSettings.setSelected(appConfig.isEnableColorAdvancedSettings());
+               onChangeShowAdvancedSettings();
+
+               Box btns = Box.createHorizontalBox();
+               btns.add(chkShowAdvancedSettings);
+               btns.add(Box.createHorizontalGlue());
+               btns.add(toolBar);
+
                container.setLayout(new BorderLayout());
+               container.add(btns, BorderLayout.NORTH);
                container.add(tabbedPane, BorderLayout.CENTER);
                container.add(btnPanel, BorderLayout.SOUTH);
-               
+
 
                Toolkit tk = Toolkit.getDefaultToolkit();
                JRootPane rootPane = getRootPane();
@@ -295,21 +369,258 @@ public class ColorDialog extends JDialog {
                if (btnApply != null) {
                        rootPane.setDefaultButton(btnApply);
                }
-               
+
                // CTRL-Wでウィンドウを非表示にする. (ESCでは非表示にしない)
                InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
                ActionMap am = rootPane.getActionMap();
-               
-               im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, tk.getMenuShortcutKeyMask()), "hideColorDialog");
+
+               int ctrlMask = tk.getMenuShortcutKeyMask();
+               im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, ctrlMask), "hideColorDialog");
                am.put("hideColorDialog", actHide);
-               
+
+               // CTRL-SHIFT-C でパラメータのコピー
+               im.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, ctrlMask + Event.SHIFT_MASK), "copyColorParam");
+               am.put("copyColorParam", actCopy);
+
+               // CTRL-SHIFT-V でパラメーターの貼り付け
+               im.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, ctrlMask + Event.SHIFT_MASK), "pastColorParam");
+               am.put("pastColorParam", actPaste);
+
+               // CTRL-E で詳細設定の表示切り替え
+               im.put(KeyStroke.getKeyStroke(KeyEvent.VK_E, ctrlMask), "showAdvancedSetting");
+               am.put("showAdvancedSetting", new AbstractAction() {
+                       private static final long serialVersionUID = 1L;
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               // 詳細表示チェックボックスをトグル動作して画面を更新する
+                               chkShowAdvancedSettings.setSelected(!chkShowAdvancedSettings.isSelected());
+                               onChangeShowAdvancedSettings();
+                       }
+               });
+
+               pack();
+       }
+
+       /**
+        * 詳細設定の表示切り替え
+        */
+       protected void onChangeShowAdvancedSettings() {
+               boolean show = chkShowAdvancedSettings.isSelected();
+               for (ColorDialogTabPanel tabContainer : tabs.values()) {
+                       tabContainer.setVisibleAdvancedSettings(show);
+               }
                pack();
        }
-       
+
+       /**
+        * 設定値をクリップボードにコピーする
+        */
+       protected void onCopy(boolean advanced) {
+               Toolkit tk = Toolkit.getDefaultToolkit();
+
+               ColorDialogTabPanel tabContainer = (ColorDialogTabPanel) tabbedPane.getSelectedComponent();
+               if (tabContainer == null) {
+                       tk.beep();
+                       return;
+               }
+
+               ColorConvertParameter param = tabContainer.getColorConvertParameter();
+
+               StringWriter sw = new StringWriter();
+               PrintWriter pw = new PrintWriter(sw);
+
+               // コメントヘッダ
+               if (partsIdentifier != null) {
+                       pw.println("# " + partsIdentifier.getLocalizedPartsName());
+               }
+               pw.println("# " + partsCategory.getLocalizedCategoryName());
+               pw.println("# " + tabContainer.getLayer().getLocalizedName());
+               pw.println();
+
+               // パラメータ
+               pw.println("hue=" + param.getHue());
+               pw.println("saturation=" + param.getSaturation());
+               pw.println("brightness=" + param.getBrightness());
+               pw.println("contrast=" + param.getContrast());
+
+               if (advanced) {
+                       pw.println();
+                       pw.println("offsetR=" + param.getOffsetR());
+                       pw.println("offsetG=" + param.getOffsetG());
+                       pw.println("offsetB=" + param.getOffsetB());
+                       pw.println("offsetA=" + param.getOffsetA());
+
+                       pw.println("factorR=" + param.getFactorR());
+                       pw.println("factorG=" + param.getFactorG());
+                       pw.println("factorB=" + param.getFactorB());
+                       pw.println("factorA=" + param.getFactorA());
+
+                       pw.println("gammaR=" + param.getGammaR());
+                       pw.println("gammaG=" + param.getGammaG());
+                       pw.println("gammaB=" + param.getGammaB());
+                       pw.println("gammaA=" + param.getGammaA());
+
+                       pw.println("grayLevel=" + param.getGrayLevel());
+                       pw.println("replace=" + param.getColorReplace());
+               }
+
+               Clipboard cb = tk.getSystemClipboard();
+               StringSelection selection = new StringSelection(sw.toString());
+               cb.setContents(selection, null);
+       }
+
+       /**
+        * クリップボードから設定値を貼り付ける
+        */
+       protected void onPaste() {
+               Toolkit tk = Toolkit.getDefaultToolkit();
+
+               ColorDialogTabPanel tabContainer = (ColorDialogTabPanel) tabbedPane.getSelectedComponent();
+               if (tabContainer == null) {
+                       tk.beep();
+                       return;
+               }
+
+               Clipboard cb = tk.getSystemClipboard();
+               Transferable trans = cb.getContents(null);
+               if (trans == null) {
+                       tk.beep();
+                       return;
+               }
+
+               try {
+                       // クリップボードでサポートされているフォーマットでもっともテキストに適したフレーバーを取得する
+                       DataFlavor[] flavors = trans.getTransferDataFlavors();
+                   final DataFlavor textFlavor = DataFlavor.selectBestTextFlavor(flavors);
+                   if (textFlavor == null) {
+                               // テキストを持っていない
+                               tk.beep();
+                               return;
+                   }
+
+                   // 現在の設定を取得する
+                       ColorConvertParameter param = tabContainer.getColorConvertParameter();
+                       ColorConvertParameter org = param.clone(); // 変更有無の判定のため現在値をコピーする
+
+                       List<String> errorLines = new ArrayList<String>();
+                       BufferedReader rd = new BufferedReader(textFlavor.getReaderForText(trans));
+                       try {
+                               // テキストを読み込みつつ、対応するパラメータを設定する。
+                               for (;;) {
+                                       String line = rd.readLine();
+                                       if (line == null) {
+                                               break;
+                                       }
+
+                                       // #以降はコメント
+                                       int pt = line.indexOf('#');
+                                       if (pt >= 0) {
+                                               line = line.substring(0, pt);
+                                       }
+                                       line = line.trim();
+
+                                       if (line.isEmpty()) {
+                                               // 空行は無視
+                                               continue;
+                                       }
+
+                                       String[] tokens = line.split("=");
+                                       if (tokens.length == 2) {
+                                               String name = tokens[0].trim().toLowerCase();
+                                               String val = tokens[1].trim();
+
+                                               try {
+                                                       if ("hue".equals(name)) {
+                                                               param.setHue(Float.parseFloat(val));
+                                                       } else if ("saturation".equals(name)) {
+                                                               param.setSaturation(Float.parseFloat(val));
+                                                       } else if ("brightness".equals(name)) {
+                                                               param.setBrightness(Float.parseFloat(val));
+                                                       } else if ("contrast".equals(name)) {
+                                                               param.setContrast(Float.parseFloat(val));
+
+                                                       } else if ("offsetr".equals(name)) {
+                                                               param.setOffsetR(Integer.parseInt(val));
+                                                       } else if ("offsetg".equals(name)) {
+                                                               param.setOffsetG(Integer.parseInt(val));
+                                                       } else if ("offsetb".equals(name)) {
+                                                               param.setOffsetB(Integer.parseInt(val));
+                                                       } else if ("offseta".equals(name)) {
+                                                               param.setOffsetA(Integer.parseInt(val));
+
+                                                       } else if ("factorr".equals(name)) {
+                                                               param.setFactorR(Float.parseFloat(val));
+                                                       } else if ("factorg".equals(name)) {
+                                                               param.setFactorG(Float.parseFloat(val));
+                                                       } else if ("factorb".equals(name)) {
+                                                               param.setFactorB(Float.parseFloat(val));
+                                                       } else if ("factora".equals(name)) {
+                                                               param.setFactorA(Float.parseFloat(val));
+
+                                                       } else if ("gammar".equals(name)) {
+                                                               param.setGammaR(Float.parseFloat(val));
+                                                       } else if ("gammag".equals(name)) {
+                                                               param.setGammaG(Float.parseFloat(val));
+                                                       } else if ("gammab".equals(name)) {
+                                                               param.setGammaB(Float.parseFloat(val));
+                                                       } else if ("gammaa".equals(name)) {
+                                                               param.setGammaA(Float.parseFloat(val));
+
+                                                       } else if ("graylevel".equals(name)) {
+                                                               param.setGrayLevel(Float.parseFloat(val));
+                                                       } else if ("replace".equals(name)) {
+                                                               param.setColorReplace(ColorConv.valueOf(val));
+                                                       } else {
+                                                               // 未知のパラメーター
+                                                               errorLines.add(line);
+                                                       }
+                                               } catch (RuntimeException ex) {
+                                                       // パラメーターエラー
+                                                       logger.log(Level.WARNING, "failed to read the clipboard.", ex);
+                                                       errorLines.add(line);
+                                                       errorLines.add("* " + ex.toString());
+                                               }
+                                       } else {
+                                               // フォーマットが不正
+                                               errorLines.add(line);
+                                       }
+                               }
+                       } finally {
+                               rd.close();
+                       }
+
+                       if (!param.equals(org)) {
+                               // クリップボートから取得されたパラメータを設定します。
+                               tabContainer.applyColorConvertParameter(param);
+                       }
+
+                       // パラメータの取り込みに失敗した行を表示する
+                       if (errorLines.size() > 0) {
+                               StringBuilder buf = new StringBuilder();
+                               String lineBreak = System.getProperty("line.separator");
+                               for (String line : errorLines) {
+                                       buf.append(line).append(lineBreak);
+                               }
+                               JTextArea message = new JTextArea(buf.toString());
+                               message.setEditable(false);
+                               JScrollPane scr = new JScrollPane(message);
+                               scr.setPreferredSize(new Dimension(200, 200));
+
+                               final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
+                                               .getLocalizedProperties("languages/colordialog");
+                               String title = strings.getProperty("clipboard.paste.formatErrorTitle");
+                               JOptionPane.showMessageDialog(this, scr, title, JOptionPane.ERROR_MESSAGE);
+                       }
+
+               } catch (Exception ex) {
+                       ErrorMessageHelper.showErrorDialog(this, ex);
+               }
+       }
+
        /**
         * 各レイヤーのカラー情報のタブが開かれた場合、もしくはカラーの設定値が変更されるたびに 呼び出されて、リセットボタンの状態を変更します.<br>
         * 現在のタブが選択しているパネルと異なるパネルからの要求については無視されます.<br>
-        * 
+        *
         * @param panel
         *            色情報が変更された、もしくは開かれた対象パネル
         */
@@ -319,20 +630,20 @@ public class ColorDialog extends JDialog {
                        actReset.setEnabled(panel.isColorConvertParameterModified());
                }
        }
-       
+
        /**
         * このカラーダイアログが対応するパーツカテゴリを取得する.<br>
-        * 
+        *
         * @return パーツカテゴリ
         */
        public PartsCategory getPartsCategory() {
                return partsCategory;
        }
-       
+
        /**
         * 指定したレイヤーのカラーグループが「連動」しているか?<br>
         * カテゴリに属していないレイヤーを指定した場合は常にfalseを返す.<br>
-        * 
+        *
         * @param layer
         *            レイヤー
         * @return 連動している場合はtrue、そうでなければfalse
@@ -348,7 +659,7 @@ public class ColorDialog extends JDialog {
        /**
         * 指定したレイヤーのカラーグループの連動フラグを設定する.<br>
         * カテゴリに属していないレイヤーを指定した場合は何もしない.<br>
-        * 
+        *
         * @param layer
         *            レイヤー
         * @param selected
@@ -364,7 +675,7 @@ public class ColorDialog extends JDialog {
        /**
         * レイヤーごとの色情報のマップを指定して、各レイヤーに色情報を設定する.<br>
         * カテゴリに属していないレイヤーが含まれる場合は例外となる.<br>
-        * 
+        *
         * @param params
         *            レイヤーと色情報のマップ
         */
@@ -380,12 +691,12 @@ public class ColorDialog extends JDialog {
                        setColorConvertParameter(layer, param);
                }
        }
-       
+
        /**
         * 対象となるパーツ識別子を指定する。<br>
         * カラーダイアログのキャプションにパーツ名を設定される.<br>
         * nullを指定した場合はキャプションからパーツ名が除去される.<br>
-        * 
+        *
         * @param partsIdentifier
         *            パーツ識別子、もしくはnull
         */
@@ -401,7 +712,7 @@ public class ColorDialog extends JDialog {
        /**
         * 対象となるパーツ識別子を取得する.<br>
         * 設定されていなければnullが返される.<br>
-        * 
+        *
         * @return パーツ識別子、もしくはnull
         */
        public PartsIdentifier getPartsIdentifier() {
@@ -412,7 +723,7 @@ public class ColorDialog extends JDialog {
         * 各レイヤーのタブの有効・無効状態を設定します.<br>
         * カテゴリに属さないレイヤーは無視されます.<br>
         * nullを指定した場合は、すべてのレイヤーが「有効」となります.<br>
-        * 
+        *
         * @param layers
         *            有効とするレイヤーのコレクション、もしくはnull
         */
@@ -441,16 +752,16 @@ public class ColorDialog extends JDialog {
 
        /**
         * 「すべてに適用」フラグを取得する.<br>
-        * 
+        *
         * @return すべてに適用フラグ
         */
        public boolean isApplyAll() {
                return chkApplyAll.isSelected();
        }
-       
+
        /**
         * 各レイヤーと、その色情報をマップとして取得する.<br>
-        * 
+        *
         * @return 各レイヤーと、その色情報のマップ
         */
        public Map<Layer, ColorConvertParameter> getColorConvertParameters() {
@@ -466,7 +777,7 @@ public class ColorDialog extends JDialog {
        /**
         * レイヤーを指定して、色情報を設定する.<br>
         * カテゴリに属していないレイヤーを指定した場合は例外となる.<br>
-        * 
+        *
         * @param layer
         *            レイヤー
         * @param param
@@ -486,7 +797,7 @@ public class ColorDialog extends JDialog {
        /**
         * 指定したレイヤーの色情報を取得する.<br>
         * カテゴリに属していないレイヤーを指定した場合は例外となる.<br>
-        * 
+        *
         * @param layer
         *            レイヤー
         * @return 色情報
@@ -501,11 +812,11 @@ public class ColorDialog extends JDialog {
                }
                return tab.getColorConvertParameter();
        }
-       
+
        /**
         * 指定したレイヤーのカラーグループを取得する.<br>
         * カテゴリに属さないレイヤーを指定した場合は例外となる.<br>
-        * 
+        *
         * @param layer
         *            レイヤー
         * @return カラーグループ
@@ -520,11 +831,11 @@ public class ColorDialog extends JDialog {
                }
                return tab.getColorGroup();
        }
-       
+
        /**
         * 指定したレイヤーのカラーグループを設定する.<br>
         * カテゴリに属さないレイヤーを指定した場合は例外となる.<br>
-        * 
+        *
         * @param layer
         *            レイヤー
         * @param colorGroup
@@ -539,10 +850,10 @@ public class ColorDialog extends JDialog {
                        tab.setColorGroup(colorGroup);
                }
        }
-       
+
        /**
         * 色ダイアログが変更された場合に通知を受けるリスナーを登録する.<br>
-        * 
+        *
         * @param listener
         *            リスナー
         */
@@ -550,16 +861,16 @@ public class ColorDialog extends JDialog {
                if (listener == null) {
                        throw new IllegalArgumentException();
                }
-               listeners.add(listener);
+               listeners.add(ColorChangeListener.class, listener);
        }
 
        /**
         * 色ダイアログが変更された場合に通知を受けるリスナーを登録解除する.<br>
-        * 
+        *
         * @param listener
         */
        public void removeColorChangeListener(ColorChangeListener listener) {
-               listeners.remove(listener);
+               listeners.remove(ColorChangeListener.class, listener);
        }
 
        /**
@@ -570,7 +881,7 @@ public class ColorDialog extends JDialog {
                        ColorDialog.this.fireColorChangeEvent(layer, true);
                }
        }
-       
+
        /**
         * カラーをリセットする.
         */
@@ -581,7 +892,7 @@ public class ColorDialog extends JDialog {
        /**
         * 指定したレイヤーに対するカラー変更イベントを通知する.<br>
         * ただし、force引数がfalseである場合、アプリケーション設定で即時プレビューが指定されていない場合は通知しない.<br>
-        * 
+        *
         * @param layer
         *            レイヤー
         * @param force
@@ -597,15 +908,27 @@ public class ColorDialog extends JDialog {
                                return;
                        }
                }
-               ColorChangeEvent event = new ColorChangeEvent(this, layer);
-               for (ColorChangeListener listener : listeners) {
-                       listener.onColorChange(event);
+
+               // Guaranteed to return a non-null array
+               Object[] ll = listeners.getListenerList();
+               // Process the listeners last to first, notifying
+               // those that are interested in this event
+               // ※ 逆順で通知するのがSwingの作法らしい。
+               ColorChangeEvent event = null;
+               for (int i = ll.length - 2; i >= 0; i -= 2) {
+                       if (ll[i] == ColorChangeListener.class) {
+                               // Lazily create the event:
+                               if (event == null) {
+                                       event = new ColorChangeEvent(this, layer);
+                               }
+                               ((ColorChangeListener) ll[i + 1]).onColorChange(event);
+                       }
                }
        }
 
        /**
         * 色グループが変更されたことを通知する.<br>
-        * 
+        *
         * @param layer
         *            レイヤー
         */
@@ -613,12 +936,23 @@ public class ColorDialog extends JDialog {
                if (layer == null) {
                        throw new IllegalArgumentException();
                }
-               ColorChangeEvent event = new ColorChangeEvent(this, layer);
-               for (ColorChangeListener listener : listeners) {
-                       listener.onColorGroupChange(event);
+               // Guaranteed to return a non-null array
+               Object[] ll = listeners.getListenerList();
+               // Process the listeners last to first, notifying
+               // those that are interested in this event
+               // ※ 逆順で通知するのがSwingの作法らしい。
+               ColorChangeEvent event = null;
+               for (int i = ll.length - 2; i >= 0; i -= 2) {
+                       if (ll[i] == ColorChangeListener.class) {
+                               // Lazily create the event:
+                               if (event == null) {
+                                       event = new ColorChangeEvent(this, layer);
+                               }
+                               ((ColorChangeListener) ll[i + 1]).onColorGroupChange(event);
+                       }
                }
        }
-       
+
        @Override
        public String toString() {
                return "ColorDialog(partsCategory:" + partsCategory + ")";
@@ -629,74 +963,80 @@ public class ColorDialog extends JDialog {
 class ColorDialogTabPanel extends JPanel {
        private static final long serialVersionUID = 1L;
 
+       private final ColorDialog parent;
+
+       private Layer layer;
+
        private JComboBox cmbColorReplace;
-       
+
        private JSpinner spinGray;
-       
+
        private JSpinner spinOffsetR;
-       
+
        private JSpinner spinOffsetG;
-       
+
        private JSpinner spinOffsetB;
-       
+
        private JSpinner spinOffsetA;
 
        private JSpinner spinFactorR;
-       
+
        private JSpinner spinFactorG;
-       
+
        private JSpinner spinFactorB;
-       
+
        private JSpinner spinFactorA;
-       
+
        private JSpinner spinHue;
-       
+
        private JSpinner spinSaturation;
-       
+
        private JSpinner spinBrightness;
-       
+
        private JSpinner spinContrast;
 
        private JSpinner spinGammaR;
 
        private JSpinner spinGammaG;
-       
+
        private JSpinner spinGammaB;
-       
+
        private JSpinner spinGammaA;
-       
+
        private JComboBox cmbColorGroup;
-       
+
        private JCheckBox chkColorGroupSync;
 
-       private final ColorDialog parent;
-       
        /**
         * パラメータの明示的変更時に他のパラメータへの反映イベントを停止させるためのセマフォ
         */
        private AtomicInteger changeEventDisableSemaphore = new AtomicInteger();
-       
+
        /**
         * 明示的に設定されたカラーパラメータを保存する.(リセットに使用するため)
         */
        private ColorConvertParameter paramOrg = new ColorConvertParameter();
-       
+
+       /**
+        * 現在の画面項目からカラー情報を組み立てたキャッシュ。
+        * (画面項目の更新によりクリアされる。)
+        */
        private ColorConvertParameter chachedParam;
-       
+
        private LinkedList<ColorChangeListener> listeners = new LinkedList<ColorChangeListener>();
-       
+
        public void addColorChangeListener(ColorChangeListener listener) {
                if (listener == null) {
                        throw new IllegalArgumentException();
                }
                listeners.add(listener);
        }
-       
+
        public void removeColorChangeListener(ColorChangeListener listener) {
                listeners.remove(listener);
        }
-       
-       protected void fireColorChangeEvent(Layer layer) {
+
+       protected void fireColorChangeEvent() {
                if (layer == null) {
                        throw new IllegalArgumentException();
                }
@@ -708,8 +1048,8 @@ class ColorDialogTabPanel extends JPanel {
                        }
                }
        }
-       
-       protected void fireColorGroupChangeEvent(Layer layer) {
+
+       protected void fireColorGroupChangeEvent() {
                if (layer == null) {
                        throw new IllegalArgumentException();
                }
@@ -722,38 +1062,44 @@ class ColorDialogTabPanel extends JPanel {
                }
        }
 
+       private JPanel colorReplacePanel;
+
+       private JPanel colorLevelPanel;
+
        public ColorDialogTabPanel(final ColorDialog parent, final Layer layer, Collection<ColorGroup> colorGroups) {
                if (parent == null || layer == null || colorGroups == null) {
                        throw new IllegalArgumentException();
                }
                this.parent = parent;
+               this.layer = layer;
 
-               final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance().getLocalizedProperties("languages/colordialog");
+               final Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
+                               .getLocalizedProperties("languages/colordialog");
 
                setLayout(new BorderLayout());
                JPanel container = new JPanel();
                BoxLayout boxlayout = new BoxLayout(container, BoxLayout.PAGE_AXIS);
                container.setLayout(boxlayout);
                add(container, BorderLayout.NORTH);
-               
+
                // 変更イベントハンドラ
                final ChangeListener changeEventHandler = new ChangeListener() {
                        public void stateChanged(ChangeEvent e) {
-                               fireColorChangeEvent(layer);
+                               fireColorChangeEvent();
                                firePropertyChange("colorConvertParameter", null, null);
                        }
                };
-               
+
                // 色置換パネル
-               
-               JPanel colorReplacePanel = new JPanel();
+
+               colorReplacePanel = new JPanel();
                colorReplacePanel.setBorder(BorderFactory.createCompoundBorder(
                                BorderFactory.createEmptyBorder(3, 3, 3, 3),
                                BorderFactory.createTitledBorder(strings.getProperty("group.replacergb.caption"))));
                GridBagLayout gbl = new GridBagLayout();
                colorReplacePanel.setLayout(gbl);
                GridBagConstraints gbc = new GridBagConstraints();
-               
+
                JLabel lblColorReplace = new JLabel(strings.getProperty("replacergb"), JLabel.RIGHT);
                cmbColorReplace = new JComboBox(ColorConv.values());
                JLabel lblGray = new JLabel(strings.getProperty("bright"), JLabel.RIGHT);
@@ -761,13 +1107,13 @@ class ColorDialogTabPanel extends JPanel {
                grayModel.addChangeListener(changeEventHandler);
                cmbColorReplace.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
-                               fireColorChangeEvent(layer);
+                               fireColorChangeEvent();
                                firePropertyChange("colorConvertParameter", null, null);
                        }
                });
                spinGray = new JSpinner(grayModel);
                spinGray.addMouseWheelListener(new SpinnerWheelSupportListener(grayModel));
-               
+
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.gridwidth = 1;
@@ -780,7 +1126,7 @@ class ColorDialogTabPanel extends JPanel {
                gbc.ipady = 0;
                gbc.insets = new Insets(3, 3, 3, 3);
                colorReplacePanel.add(lblColorReplace, gbc);
-               
+
                gbc.gridx = 1;
                gbc.gridy = 0;
                gbc.gridwidth = 1;
@@ -788,7 +1134,7 @@ class ColorDialogTabPanel extends JPanel {
                gbc.weightx = 1.;
                gbc.weighty = 0.;
                colorReplacePanel.add(cmbColorReplace, gbc);
-               
+
                gbc.gridx = 2;
                gbc.gridy = 0;
                gbc.gridwidth = 1;
@@ -806,8 +1152,8 @@ class ColorDialogTabPanel extends JPanel {
                colorReplacePanel.add(spinGray, gbc);
 
                // RGB変更パネル
-               
-               JPanel colorLevelPanel = new JPanel();
+
+               colorLevelPanel = new JPanel();
                colorLevelPanel.setBorder(BorderFactory.createCompoundBorder(
                                BorderFactory.createEmptyBorder(3, 3, 3, 3),
                                BorderFactory.createTitledBorder(strings.getProperty("group.rgb.caption"))));
@@ -886,8 +1232,7 @@ class ColorDialogTabPanel extends JPanel {
 
                // 色調パネル
 
-               ColorModel colorModel = ColorModels.safeValueOf(layer
-                               .getColorModelName());
+               ColorModel colorModel = ColorModels.safeValueOf(layer.getColorModelName());
 
                JPanel colorTunePanel = new JPanel();
                colorTunePanel.setBorder(BorderFactory.createCompoundBorder(
@@ -911,12 +1256,12 @@ class ColorDialogTabPanel extends JPanel {
                SpinnerNumberModel hsbModelS = new SpinnerNumberModel(0., -1., 1., 0.001);
                SpinnerNumberModel hsbModelB = new SpinnerNumberModel(0., -1., 1., 0.001);
                SpinnerNumberModel hsbModelC = new SpinnerNumberModel(0., -1., 1., 0.001);
-               
+
                hsbModelH.addChangeListener(changeEventHandler);
                hsbModelS.addChangeListener(changeEventHandler);
                hsbModelB.addChangeListener(changeEventHandler);
                hsbModelC.addChangeListener(changeEventHandler);
-               
+
                spinHue = new JSpinner(hsbModelH);
                spinSaturation = new JSpinner(hsbModelS);
                spinBrightness = new JSpinner(hsbModelB);
@@ -925,17 +1270,17 @@ class ColorDialogTabPanel extends JPanel {
                spinSaturation.addMouseWheelListener(new SpinnerWheelSupportListener(hsbModelS));
                spinBrightness.addMouseWheelListener(new SpinnerWheelSupportListener(hsbModelB));
                spinContrast.addMouseWheelListener(new SpinnerWheelSupportListener(hsbModelC));
-               
+
                colorTunePanel.add(spinHue);
                colorTunePanel.add(spinSaturation);
                colorTunePanel.add(spinBrightness);
                colorTunePanel.add(spinContrast);
-               
+
                JSlider sliderHue = new JSlider();
                JSlider sliderSaturation = new JSlider();
                JSlider sliderBrightness = new JSlider();
                JSlider sliderContrast = new JSlider();
-               
+
                sliderHue.setPreferredSize(spinHue.getPreferredSize());
                sliderSaturation.setPreferredSize(spinSaturation.getPreferredSize());
                sliderBrightness.setPreferredSize(spinBrightness.getPreferredSize());
@@ -948,7 +1293,7 @@ class ColorDialogTabPanel extends JPanel {
 
                JSlider sliders[] = new JSlider[] {sliderHue, sliderSaturation, sliderBrightness, sliderContrast};
                JSpinner spinners[] = new JSpinner[] {spinHue, spinSaturation, spinBrightness, spinContrast};
-               
+
                for (int idx = 0; idx < spinners.length; idx++) {
                        final JSlider sl = sliders[idx];
                        final JSpinner sp = spinners[idx];
@@ -982,7 +1327,7 @@ class ColorDialogTabPanel extends JPanel {
                                }
                        });
                }
-               
+
                // カラーグループ
                ColorGroup colorGroup = layer.getColorGroup();
                JPanel colorGroupPanel = new JPanel();
@@ -1000,7 +1345,7 @@ class ColorDialogTabPanel extends JPanel {
                        public void actionPerformed(ActionEvent e) {
                                ColorGroup selColorGroup = (ColorGroup) cmbColorGroup.getSelectedItem();
                                chkColorGroupSync.setSelected(selColorGroup.isEnabled());
-                               fireColorGroupChangeEvent(layer);
+                               fireColorGroupChangeEvent();
                        }
                });
                chkColorGroupSync = new JCheckBox(strings.getProperty("synchronized"));
@@ -1018,7 +1363,7 @@ class ColorDialogTabPanel extends JPanel {
                gbc2.ipady = 0;
                gbc2.insets = new Insets(3, 3, 3, 3);
                colorGroupPanel.add(lblColorGroup, gbc2);
-               
+
                gbc2.gridx = 1;
                gbc2.gridy = 0;
                gbc2.gridwidth = 1;
@@ -1026,7 +1371,7 @@ class ColorDialogTabPanel extends JPanel {
                gbc2.weightx = 1.;
                gbc2.weighty = 0.;
                colorGroupPanel.add(cmbColorGroup, gbc2);
-               
+
                gbc2.gridx = 2;
                gbc2.gridy = 0;
                gbc2.gridwidth = GridBagConstraints.REMAINDER;
@@ -1034,7 +1379,7 @@ class ColorDialogTabPanel extends JPanel {
                gbc2.weightx = 0.;
                gbc2.weighty = 0.;
                colorGroupPanel.add(chkColorGroupSync, gbc2);
-               
+
                if (colorGroupPanel != null) {
                        container.add(colorGroupPanel);
                }
@@ -1042,7 +1387,33 @@ class ColorDialogTabPanel extends JPanel {
                container.add(colorReplacePanel);
                container.add(colorTunePanel);
        }
-       
+
+       /**
+        * 詳細設定パネルの表示状態
+        * @return
+        */
+       public boolean isVisibleAdvancedSettings() {
+               return colorLevelPanel.isVisible();
+       }
+
+       /**
+        * 詳細設定パネルの表示制御
+        * @param show
+        */
+       public void setVisibleAdvancedSettings(boolean show) {
+               colorLevelPanel.setVisible(show);
+               colorReplacePanel.setVisible(show);
+               revalidate();
+       }
+
+       /**
+        * このパネルのレイヤーを取得する
+        * @return
+        */
+       public Layer getLayer() {
+               return layer;
+       }
+
        /**
         * このパネルで変更された色情報の状態をリセットする.<br>
         * 最後に{@link #setColorConvertParameter(ColorConvertParameter)}された値で 設定し直す.<br>
@@ -1050,12 +1421,39 @@ class ColorDialogTabPanel extends JPanel {
        public void resetColor() {
                setColorConvertParameter(paramOrg);
        }
-       
+
+       /**
+        * 指定されたパラメータでダイアログを設定し、オリジナル値とする。
+        * @param param
+        */
        public void setColorConvertParameter(ColorConvertParameter param) {
+               setColorConvertParameter(param, true);
+       }
+
+       /**
+        * 指定されたパラメータでダイアログを設定し、且つ、変更通知を送信する。
+        * @param param
+        */
+       public void applyColorConvertParameter(ColorConvertParameter param) {
+               setColorConvertParameter(param, false);
+               fireColorChangeEvent();
+       }
+
+       /**
+        * 指定されたパラメータでダイアログを設定する。
+        * @param param 色パラメーター
+        * @param setOriginal オリジナル値に設定するか?
+        */
+       private void setColorConvertParameter(ColorConvertParameter param, boolean setOriginal) {
                if (param == null) {
                        throw new IllegalArgumentException();
                }
-               paramOrg = param.clone();
+
+               if (setOriginal) {
+                       // オリジナル値として設定する
+                       paramOrg = param.clone();
+               }
+
                ColorConv colorReplace = param.getColorReplace();
                if (colorReplace == null) {
                        colorReplace = ColorConv.NONE;
@@ -1084,12 +1482,12 @@ class ColorDialogTabPanel extends JPanel {
                } finally {
                        changeEventDisableSemaphore.decrementAndGet();
                }
-               
+
                chachedParam = param;
-               
+
                firePropertyChange("colorConvertParameter", null, param);
        }
-       
+
        public ColorConvertParameter getColorConvertParameter() {
                if (chachedParam != null) {
                        return chachedParam;
@@ -1116,20 +1514,20 @@ class ColorDialogTabPanel extends JPanel {
                chachedParam = param;
                return param;
        }
-       
+
        /**
         * カラー設定が変更されているか?
-        * 
+        *
         * @return 変更されている場合はtrue、そうでなければfalse
         */
        public boolean isColorConvertParameterModified() {
                return !paramOrg.equals(getColorConvertParameter());
        }
-       
+
        public ColorGroup getColorGroup() {
                return (ColorGroup) cmbColorGroup.getSelectedItem();
        }
-       
+
        public void setColorGroup(ColorGroup colorGroup) {
                if (colorGroup == null) {
                        colorGroup = ColorGroup.NA;
@@ -1141,11 +1539,11 @@ class ColorDialogTabPanel extends JPanel {
                        changeEventDisableSemaphore.decrementAndGet();
                }
        }
-       
+
        public boolean isSyncColorGroup() {
                return chkColorGroupSync == null ? false : chkColorGroupSync.isSelected();
        }
-       
+
        public void setSyncColorGroup(boolean selected) {
                if (chkColorGroupSync != null) {
                        changeEventDisableSemaphore.incrementAndGet();
index 845afa1..a3b5264 100644 (file)
@@ -212,6 +212,7 @@ public class ImageSelectPanel extends JPanel {
         */
        private final PartsCategory partsCategory;
 
+       private final JLabel title;
 
        /**
         * イメージ選択パネルを構築する
@@ -487,9 +488,8 @@ public class ImageSelectPanel extends JPanel {
 
                JPanel header = new JPanel(new BorderLayout());
                header.add(btnPanelGrp, BorderLayout.EAST);
-               final JLabel title = new JLabel(" " + partsCategory.getLocalizedCategoryName() + " ");
-               Font font = title.getFont();
-               title.setFont(font.deriveFont(Font.BOLD));
+               title = new JLabel(" " + partsCategory.getLocalizedCategoryName() + " ");
+
                final Color defaultTitleColor = title.getForeground();
                final Color hilightColor = appConfig.getSelectPanelTitleColor();
 
@@ -534,6 +534,13 @@ public class ImageSelectPanel extends JPanel {
                setDisplayMode(DisplayMode.NORMAL);
        }
 
+       @Override
+       public void doLayout() {
+               Font font = getFont();
+               title.setFont(font.deriveFont(Font.BOLD));
+               super.doLayout();
+       }
+
        /**
         * 表示行数から推奨のパネル高さを求める.<br>
         * パネル高さは1行の高さ x 表示行数 + ヘッダ + ボーダー上下である.<br>
index c9ae762..c40a720 100644 (file)
@@ -23,6 +23,8 @@ import java.awt.event.MouseWheelListener;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -436,6 +438,9 @@ public class MainFrame extends JFrame
                        CustomLayerOrderPersist.newInstance(characterData)
                                        .addCustomLayerOrderPersistListener(this);
 
+                       // アプリケーション設定の変更で画面の再表示を試行する
+                       AppConfig.getInstance().addPropertyChangeListener(appConfigChangeListener);
+
                } catch (RuntimeException ex) {
                        logger.log(Level.SEVERE, "メインフレームの構築中に予期せぬ例外が発生しました。", ex);
                        dispose(); // コンストラクタが呼ばれた時点でJFrameは構築済みなのでdisposeの必要がある.
@@ -554,6 +559,8 @@ public class MainFrame extends JFrame
                                .removeCharacterDataChangeListener(this);
                CustomLayerOrderPersist.newInstance(characterData)
                                .removeCustomLayerOrderPersistListener(this);
+               AppConfig.getInstance()
+                               .removePropertyChangeListener(appConfigChangeListener);
 
            imageLoader.close();
                stopAgents();
@@ -561,6 +568,17 @@ public class MainFrame extends JFrame
        }
 
        /**
+        * AppConfigの設定値が変更されたことを通知されるリスナ
+        */
+       private final PropertyChangeListener appConfigChangeListener = new PropertyChangeListener() {
+               @Override
+               public void propertyChange(PropertyChangeEvent evt) {
+                       // 画面を再描画する
+                       repaint();
+               }
+       };
+
+       /**
         * 画面コンポーネントを設定します.<br>
         * すでに設定されている場合は一旦削除されたのちに再作成されます.<br>
         */
index 9d5bac2..687c56b 100644 (file)
@@ -5,7 +5,10 @@ import java.beans.BeanInfo;
 import java.beans.IntrospectionException;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
-import java.lang.reflect.InvocationTargetException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -22,13 +25,55 @@ import java.util.logging.Logger;
  * @author seraphy
  */
 public final class BeanPropertiesUtilities {
-       
+
        private static final Logger logger = Logger.getLogger(BeanPropertiesUtilities.class.getName());
 
        private BeanPropertiesUtilities() {
                throw new RuntimeException("utilities class.");
        }
-       
+
+       /**
+        * プロパティ値を文字列として変換する
+        */
+       public interface StringConverter {
+               Object valueOf(String text);
+               String toString(Object obj);
+       }
+
+       /**
+        * int値をunsigned 32bit integerとして#つき16進数として文字列化し、
+        * それをint値として受け取れるようにするための文字列変換クラス.
+        */
+       public static class UnsignedHexStringConverter implements StringConverter {
+               @Override
+               public Object valueOf(String text) {
+                       text = (text != null) ? text.trim() : null;
+                       if (text != null && text.length() > 0) {
+                               return (int)(long) Long.decode(text); // 符号無し32ビット値を受け取るためにlongで受け取ってintにする。
+                       }
+                       return 0;
+               }
+
+               @Override
+               public String toString(Object obj) {
+                       if (obj != null) {
+                               return "#" + Long.toString(((Number) obj).longValue() & 0xffffffffL, 16);
+                       }
+                       return "";
+               }
+       }
+
+       /**
+        * プロパティのgetter(またはsetter)のメソッドに付与して、
+        * プロパティファイルへの読み書きや編集時の文字列変換を行うクラスを明示的に指定できるようにする。
+        */
+       @Target({ ElementType.METHOD })
+       @Retention(RetentionPolicy.RUNTIME)
+       public @interface StringConverterSpec {
+
+               Class<? extends StringConverter> value();
+       }
+
        /**
         * ビーンのSetter/Getterのペアをもつプロパティに対して、Propertiesより該当するプロパティの値を
         * 読み取り、プロパティに設定します.<br>
@@ -57,15 +102,27 @@ public final class BeanPropertiesUtilities {
 
                                        String name = propDesc.getName();
 
+                                       // プロパティのStringConverterSpecアノテーションがあれば取得する
+                                       StringConverterSpec anntStringConverter = mtdReader.getAnnotation(StringConverterSpec.class);
+                                       if (anntStringConverter == null) {
+                                               anntStringConverter = mtdWriter.getAnnotation(StringConverterSpec.class);
+                                       }
+
                                        String strVal = props.getProperty(name);
                                        if (strVal == null) {
-                                               // 設定がないのでスキップ
+                                               // 設定がないのでスキップ
                                                continue;
                                        }
+
+
                                        Object val;
                                        Throwable reject = null;
                                        try {
-                                               if (String.class.equals(typ)) {
+                                               if (anntStringConverter != null) {
+                                                       Class<? extends StringConverter> convCls = anntStringConverter.value();
+                                                       StringConverter conv = convCls.getConstructor().newInstance();
+                                                       val = conv.valueOf(strVal);
+                                               } else if (String.class.equals(typ)) {
                                                        val = strVal;
                                                } else if (strVal.length() == 0) {
                                                        val = null;
@@ -97,11 +154,7 @@ public final class BeanPropertiesUtilities {
                                                mtdWriter.invoke(bean, val);
                                                reject = null;
 
-                                       } catch (InvocationTargetException ex) {
-                                               reject = ex;
-                                       } catch (IllegalAccessException ex) {
-                                               reject = ex;
-                                       } catch (RuntimeException ex) {
+                                       } catch (Exception ex) {
                                                reject = ex;
                                        }
 
@@ -119,7 +172,7 @@ public final class BeanPropertiesUtilities {
                }
                return rejectNames;
        }
-       
+
        /**
         * ビーンのSetter/Getterのペアをもつプロパティの各値をPropertiesに文字列として登録します.<br>
         * nullの場合は空文字が設定されます.<br>
@@ -138,12 +191,22 @@ public final class BeanPropertiesUtilities {
                                Method mtdWriter = propDesc.getWriteMethod();
                                if (mtdReader != null && mtdWriter != null) {
                                        // 読み書き双方が可能なもののみ対象とする.
-                                       
+
+                                       // プロパティのStringConverterSpecアノテーションがあれば取得する
+                                       StringConverterSpec anntStringConverter = mtdReader.getAnnotation(StringConverterSpec.class);
+                                       if (anntStringConverter == null) {
+                                               anntStringConverter = mtdWriter.getAnnotation(StringConverterSpec.class);
+                                       }
+
                                        String name = propDesc.getName();
                                        Object val = mtdReader.invoke(bean);
-                                       
+
                                        String strVal;
-                                       if (val == null) {
+                                       if (anntStringConverter != null) {
+                                               StringConverter conv = anntStringConverter.value().getConstructor().newInstance();
+                                               strVal = conv.toString(val);
+
+                                       } else if (val == null) {
                                                strVal = "";
                                        } else if (val instanceof String) {
                                                strVal = (String) val;
@@ -159,18 +222,16 @@ public final class BeanPropertiesUtilities {
                                                                + bean.getClass() + " #" + name);
                                                continue;
                                        }
-                                       
+
                                        props.setProperty(name, strVal);
                                }
                        }
 
-               } catch (IllegalAccessException ex) {
-                       throw new RuntimeException("bean property read failed. :" + bean.getClass(), ex);
-               } catch (InvocationTargetException ex) {
-                       throw new RuntimeException("bean property read failed. :" + bean.getClass(), ex);
                } catch (IntrospectionException ex) {
                        throw new RuntimeException("bean intorospector failed. :" + bean.getClass(), ex);
+               } catch (Exception ex) {
+                       throw new RuntimeException("bean property read failed. :" + bean.getClass(), ex);
                }
        }
-       
+
 }
index 3831c80..a9dbd81 100644 (file)
@@ -9,10 +9,10 @@ http://www.loc.gov/standards/iso639-2/php/English_list.php
 
 mainframe_ja.xml : 日本語 Japanese
 mainframe_en.xml : 英語 English
-mainframe_pt_BR  : ブラジル Brazil 
+mainframe_pt_BR  : ブラジル Brazil
 mainframe_zh_TW  : 台湾 Chinese
 mainframe.xml    : デフォルト default
 
 * 作成したリソースファイルを募集しております。
 We are looking for a resource that you created.
-http://sourceforge.jp/forum/forum.php?forum_id=23932
+https://osdn.net/forum/forum.php?forum_id=23932
index 835bb36..37ca8bb 100644 (file)
@@ -66,8 +66,8 @@ h2 {
 <h2>[ライセンス/使用許諾条件]</h2>
 <p>「キャラクターなんとかJ」はオープンソースソフトウェアです。ソースコードは「The Apache License Version 2.0」です。</p>
 <p><font color="red">本ソフトウェアは完全に無保証です。</font>本ソフトウェアは「現状のまま」、かつ明示か暗黙であるかを問わず、一切の保証を付けずに提供されます。</p>
-<p><a href="http://sourceforge.jp/projects/charactermanaj/releases/">ここから最新リリース</a> 、
-および<a href="http://sourceforge.jp/projects/charactermanaj/scm/svn/">最新リリースのソースコード</a>を取得することができます。</p>
+<p><a href="https://osdn.net/projects/charactermanaj/releases/">ここから最新リリース</a> 、
+および<a href="https://osdn.net/projects/charactermanaj/scm/svn/">最新リリースのソースコード</a>を取得することができます。</p>
 <p>商用利用であるかを否かを問わず、どなたでも、自由にお使いいただけます。登録や費用は一切必要ありません。再配布も自由になさってかまいません。</p>
 <p></p>
 <p>このアプリケーション自身(javaコード)は<a href="http://hp.vector.co.jp/authors/VA017626/">seraphy</a>によって書かれました。<br>
index f33109d..503dfc8 100644 (file)
@@ -29,8 +29,8 @@ h2 {
 <h2>[ライセンス/使用許諾条件]</h2>
 <p>「キャラクターなんとかJ」はオープンソースソフトウェアです。ソースコードは「The Apache License Version 2.0」です。</p>
 <p><font color="red">本ソフトウェアは完全に無保証です。</font>本ソフトウェアは「現状のまま」、かつ明示か暗黙であるかを問わず、一切の保証を付けずに提供されます。</p>
-<p><a href="http://sourceforge.jp/projects/charactermanaj/releases/">ここから最新リリース</a> 、
-および<a href="http://sourceforge.jp/projects/charactermanaj/scm/svn/">最新リリースのソースコード</a>を取得することができます。</p>
+<p><a href="https://osdn.net/projects/charactermanaj/releases/">ここから最新リリース</a> 、
+および<a href="https://osdn.net/projects/charactermanaj/scm/svn/">最新リリースのソースコード</a>を取得することができます。</p>
 <p>商用利用であるかを否かを問わず、どなたでも、自由にお使いいただけます。登録や費用は一切必要ありません。再配布も自由になさってかまいません。</p>
 <p></p>
 <p>このアプリケーション自身(javaコード)は<a href="http://hp.vector.co.jp/authors/VA017626/">seraphy</a>によって書かれました。<br>
index b49c726..3938f71 100644 (file)
@@ -29,8 +29,8 @@ h2 {
 <h2>[程序使用许可条件]</h2>
 <p>「CharacterManaJ」是一个开源软件。源代码遵从「The Apache License Version 2.0」协议。</p>
 <p><font color="red">本ソフトウェアは完全に無保証です。</font>本ソフトウェアは「現状のまま」、かつ明示か暗黙であるかを問わず、一切の保証を付けずに提供されます。</p>
-<p><a href="http://sourceforge.jp/projects/charactermanaj/releases/">ここから最新リリース</a> 、
-および<a href="http://sourceforge.jp/projects/charactermanaj/scm/svn/">最新リリースのソースコード</a>を取得することができます。</p>
+<p><a href="https://osdn.net/projects/charactermanaj/releases/">ここから最新リリース</a> 、
+および<a href="https://osdn.net/projects/charactermanaj/scm/svn/">最新リリースのソースコード</a>を取得することができます。</p>
 <p>商用利用であるかを否かを問わず、どなたでも、自由にお使いいただけます。登録や費用は一切必要ありません。再配布も自由になさってかまいません。</p>
 <p></p>
 <p>このアプリケーション自身(javaコード)は<a href="http://hp.vector.co.jp/authors/VA017626/">seraphy</a>によって書かれました。<br>
diff --git a/src/main/resources/icons/paste.png b/src/main/resources/icons/paste.png
new file mode 100644 (file)
index 0000000..50ebc0f
Binary files /dev/null and b/src/main/resources/icons/paste.png differ
index 3ea0db7..5d2b864 100644 (file)
@@ -45,6 +45,7 @@ If the file already exists, the file is overwritten.]]></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="enableColorAdvancedSettings">22;Enable the advanced color setting.</entry>
 
 <entry key="enableDirWatch">31;Enable Watch Directory</entry>
 <entry key="disableWatchDirIfNotWritable">32;Disable Watch Directory If Not Writable</entry>
index 97d6501..d1b272d 100644 (file)
@@ -31,7 +31,7 @@
 
 <entry key="mainFrameMaxWidth">10;プレビューの初期表示の最大幅</entry>
 <entry key="mainFrameMaxHeight">11;プレビューの初期表示の最大高さ</entry>
-<entry key="enableRenderingHints">12;レンダリングヒントを使用する</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="wheelScrollUnit">19;ホイールによるスクロールの単位</entry>
 <entry key="enableOffscreenWallpaper">1A;壁紙をオフスクリーンで描画する.</entry>
 <entry key="offscreenWallpaperSize">1B;オフスクリーンの既定サイズ</entry>
-<entry key="enableRestoreWindow">1C;ウィンドウサイズ、位置、ズームの復元</entry>
+<entry key="enableRestoreWindow">1C;ウィンドウサイズ、位置、ズームの復元を行う.</entry>
 
 <entry key="enableAutoColorChange">20;カラー変更時、自動的にプレビューに適用する.</entry>
 <entry key="notDisableLayerTab">21;カラーダイアログで存在しないレイヤーをディセーブルにしない.</entry>
+<entry key="enableColorAdvancedSettings">22;カラーダイアログの詳細設定を有効にする.</entry>
 
 <entry key="enableDirWatch">31;フォルダ監視の有効・無効</entry>
-<entry key="disableWatchDirIfNotWritable">32;フォルダに書き込み権限がない場合は監視しない</entry>
+<entry key="disableWatchDirIfNotWritable">32;フォルダに書き込み権限がない場合は監視しない.</entry>
 <entry key="dirWatchInterval">33;フォルダの監視間隔(mSec)</entry>
-<entry key="noRemoveLog">34;正常時でもログを終了時に消去しない</entry>
+<entry key="noRemoveLog">34;正常時でもログを終了時に消去しない.</entry>
 <entry key="purgeLogDays">35;起動時に古いログを消去するまでの日数。(0の場合は削除しない)</entry>
 <entry key="informationDialogOpenMethod">36;情報ダイアログのアクションを「開く」にする。(false時は「編集」)</entry>
 
index 415bea2..e0176ff 100644 (file)
@@ -45,6 +45,7 @@
 
 <entry key="enableAutoColorChange">20;自动刷新颜色</entry>
 <entry key="notDisableLayerTab">21;在颜色菜单显示不存在的图层</entry>
+<entry key="enableColorAdvancedSettings">22;启用高级颜色设置</entry>
 
 <entry key="enableDirWatch">31;开启文件夹监视</entry>
 <entry key="disableWatchDirIfNotWritable">32;文件只读时关闭文件夹监视</entry>
index 3a2da91..1e882cb 100644 (file)
@@ -27,4 +27,8 @@
        <entry key="colorgroup">Color Group</entry>
        <entry key="group">Group</entry>
        <entry key="synchronized">Synchronized</entry>
+       <entry key="chk.showAdvancedSettings">Advenced Settings</entry>
+       <entry key="copy">Copy setting values.(If press the shift key, Copy the advanced setting.)</entry>
+       <entry key="paste">Paste setting values.</entry>
+       <entry key="clipboard.paste.formatErrorTitle">Bad parameters</entry>
 </properties>
index 8d4c5f4..00d972d 100644 (file)
@@ -27,4 +27,8 @@
        <entry key="colorgroup">色グループ</entry>
        <entry key="group">色グループ</entry>
        <entry key="synchronized">連動する</entry>
+       <entry key="chk.showAdvancedSettings">詳細設定</entry>
+       <entry key="copy">設定値をクリップボードにコピーする(シフトキーで詳細設定を含む)</entry>
+       <entry key="paste">設定値をクリップボードから貼り付ける</entry>
+       <entry key="clipboard.paste.formatErrorTitle">不正なパラメータ</entry>
 </properties>
index 470fbc2..aeff924 100644 (file)
@@ -27,4 +27,8 @@
        <entry key="colorgroup">颜色组</entry>
        <entry key="group">组</entry>
        <entry key="synchronized">同步</entry>
+       <entry key="chk.showAdvancedSettings">高级设置</entry>
+       <entry key="copy">复制到剪贴板</entry>
+       <entry key="paste">從剪貼板粘貼</entry>
+       <entry key="clipboard.paste.formatErrorTitle">参数无效</entry>
 </properties>
index 4375df3..a8e0d80 100644 (file)
@@ -12,7 +12,7 @@
        <entry key="input.favoritesOverwrite">Overwrite</entry>
 
        <entry key="help.reportbugs.description">Report bugs</entry>
-       <entry key="help.reportbugs.url">http://sourceforge.jp/projects/charactermanaj/ticket/</entry>
+       <entry key="help.reportbugs.url">http://osdn.net/projects/charactermanaj/ticket/</entry>
        <entry key="help.forum.description">Forum</entry>
-       <entry key="help.forum.url">http://sourceforge.jp/projects/charactermanaj/forums/</entry>
+       <entry key="help.forum.url">http://osdn.net/projects/charactermanaj/forums/</entry>
 </properties>
index ad35e99..84299b2 100644 (file)
@@ -10,9 +10,9 @@
        <entry key="input.favorites">お気に入りの名前</entry>
        <entry key="input.favoritesColorInfo">色情報を含める</entry>
        <entry key="input.favoritesOverwrite">上書きする</entry>
-       
+
        <entry key="help.reportbugs.description">バグレポートは以下のURLにあります。</entry>
-       <entry key="help.reportbugs.url">http://sourceforge.jp/projects/charactermanaj/ticket/</entry>
+       <entry key="help.reportbugs.url">http://osdn.net/projects/charactermanaj/ticket/</entry>
        <entry key="help.forum.description">フォーラムは以下のURLにあります。</entry>
-       <entry key="help.forum.url">http://sourceforge.jp/projects/charactermanaj/forums/</entry>
+       <entry key="help.forum.url">http://osdn.net/projects/charactermanaj/forums/</entry>
 </properties>
index 8684a3f..eb81aee 100644 (file)
@@ -12,7 +12,7 @@
        <entry key="input.favoritesOverwrite">覆盖</entry>
 
        <entry key="help.reportbugs.description">问题反馈(日)</entry>
-       <entry key="help.reportbugs.url">http://sourceforge.jp/projects/charactermanaj/ticket/</entry>
+       <entry key="help.reportbugs.url">http://osdn.net/projects/charactermanaj/ticket/</entry>
        <entry key="help.forum.description">论坛(日)</entry>
-       <entry key="help.forum.url">http://sourceforge.jp/projects/charactermanaj/forums/</entry>
+       <entry key="help.forum.url">http://osdn.net/projects/charactermanaj/forums/</entry>
 </properties>