[使用・作成されるファイル等について]
使用・作成されるフォルダ等についてはWikiをご参照ください。
-http://sourceforge.jp/projects/charactermanaj/wiki/FrontPage
+https://osdn.net/projects/charactermanaj/wiki/FrontPage
[ソースコードについて]
ver0.995からソースコードはGitで管理しています。
[使用・作成されるファイル等について]
使用・作成されるフォルダ等についてはWikiをご参照ください。
-http://sourceforge.jp/projects/charactermanaj/wiki/FrontPage
+https://osdn.net/projects/charactermanaj/wiki/FrontPage
[ソースコードについて]
ver0.995からソースコードはGitで管理しています。
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;
* @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");
// 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>(
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;
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 {
*/
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);
+ }
/**
* インスタンスを取得する.
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;
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;
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();
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;
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();
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;
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;
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;
return zipNameEncoding;
}
+ public static final String ZIP_NAME_ENCODING = "zipNameEncoding";
+
public void setZipNameEncoding(String zipNameEncoding) {
if (zipNameEncoding == null) {
throw new IllegalArgumentException();
} 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";
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;
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;
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;
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;
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;
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;
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;
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;
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);
+ }
}
/**
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);
+ }
}
/**
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);
+ }
}
/**
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;
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;
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 = "^.*\\(@\\).*$";
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;
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() {
*/
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() {
*/
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() {
*/
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() {
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);
+ }
}
/**
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);
+ }
}
/**
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);
+ }
}
/**
*/
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() {
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;
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);
+ }
}
/**
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);
+ }
}
/**
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);
+ }
}
/**
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);
+ }
}
/**
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);
+ }
}
/**
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);
+ }
}
+
/**
* ランダム選択パーツの履歴数
*/
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);
+ }
}
/**
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);
+ }
}
/**
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);
+ }
}
/**
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);
+ }
}
}
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;
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;
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;
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 {
* レイヤーごとのタブのマップ
*/
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
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;
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); // イベントが循環発生することを防ぐ
btnPanel.setLayout(gbl);
int colIdx = 0;
-
+
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = colIdx++;
gbc.gridy = 0;
}
});
btnPanel.add(chkApplyAll, gbc);
-
+
gbc.gridx = colIdx++;
gbc.gridy = 0;
gbc.weightx = 1.;
// 「適用」ボタン、アプリケーション設定により有無を選択できる.
JButton btnApply = null;
- AppConfig appConfig = AppConfig.getInstance();
+ final AppConfig appConfig = AppConfig.getInstance();
if ( !appConfig.isEnableAutoColorChange()) {
gbc.gridx = colIdx++;
gbc.gridy = 0;
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();
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
* 色情報が変更された、もしくは開かれた対象パネル
*/
actReset.setEnabled(panel.isColorConvertParameterModified());
}
}
-
+
/**
* このカラーダイアログが対応するパーツカテゴリを取得する.<br>
- *
+ *
* @return パーツカテゴリ
*/
public PartsCategory getPartsCategory() {
return partsCategory;
}
-
+
/**
* 指定したレイヤーのカラーグループが「連動」しているか?<br>
* カテゴリに属していないレイヤーを指定した場合は常にfalseを返す.<br>
- *
+ *
* @param layer
* レイヤー
* @return 連動している場合はtrue、そうでなければfalse
/**
* 指定したレイヤーのカラーグループの連動フラグを設定する.<br>
* カテゴリに属していないレイヤーを指定した場合は何もしない.<br>
- *
+ *
* @param layer
* レイヤー
* @param selected
/**
* レイヤーごとの色情報のマップを指定して、各レイヤーに色情報を設定する.<br>
* カテゴリに属していないレイヤーが含まれる場合は例外となる.<br>
- *
+ *
* @param params
* レイヤーと色情報のマップ
*/
setColorConvertParameter(layer, param);
}
}
-
+
/**
* 対象となるパーツ識別子を指定する。<br>
* カラーダイアログのキャプションにパーツ名を設定される.<br>
* nullを指定した場合はキャプションからパーツ名が除去される.<br>
- *
+ *
* @param partsIdentifier
* パーツ識別子、もしくはnull
*/
/**
* 対象となるパーツ識別子を取得する.<br>
* 設定されていなければnullが返される.<br>
- *
+ *
* @return パーツ識別子、もしくはnull
*/
public PartsIdentifier getPartsIdentifier() {
* 各レイヤーのタブの有効・無効状態を設定します.<br>
* カテゴリに属さないレイヤーは無視されます.<br>
* nullを指定した場合は、すべてのレイヤーが「有効」となります.<br>
- *
+ *
* @param layers
* 有効とするレイヤーのコレクション、もしくはnull
*/
/**
* 「すべてに適用」フラグを取得する.<br>
- *
+ *
* @return すべてに適用フラグ
*/
public boolean isApplyAll() {
return chkApplyAll.isSelected();
}
-
+
/**
* 各レイヤーと、その色情報をマップとして取得する.<br>
- *
+ *
* @return 各レイヤーと、その色情報のマップ
*/
public Map<Layer, ColorConvertParameter> getColorConvertParameters() {
/**
* レイヤーを指定して、色情報を設定する.<br>
* カテゴリに属していないレイヤーを指定した場合は例外となる.<br>
- *
+ *
* @param layer
* レイヤー
* @param param
/**
* 指定したレイヤーの色情報を取得する.<br>
* カテゴリに属していないレイヤーを指定した場合は例外となる.<br>
- *
+ *
* @param layer
* レイヤー
* @return 色情報
}
return tab.getColorConvertParameter();
}
-
+
/**
* 指定したレイヤーのカラーグループを取得する.<br>
* カテゴリに属さないレイヤーを指定した場合は例外となる.<br>
- *
+ *
* @param layer
* レイヤー
* @return カラーグループ
}
return tab.getColorGroup();
}
-
+
/**
* 指定したレイヤーのカラーグループを設定する.<br>
* カテゴリに属さないレイヤーを指定した場合は例外となる.<br>
- *
+ *
* @param layer
* レイヤー
* @param colorGroup
tab.setColorGroup(colorGroup);
}
}
-
+
/**
* 色ダイアログが変更された場合に通知を受けるリスナーを登録する.<br>
- *
+ *
* @param listener
* リスナー
*/
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);
}
/**
ColorDialog.this.fireColorChangeEvent(layer, true);
}
}
-
+
/**
* カラーをリセットする.
*/
/**
* 指定したレイヤーに対するカラー変更イベントを通知する.<br>
* ただし、force引数がfalseである場合、アプリケーション設定で即時プレビューが指定されていない場合は通知しない.<br>
- *
+ *
* @param layer
* レイヤー
* @param force
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
* レイヤー
*/
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 + ")";
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();
}
}
}
}
-
- protected void fireColorGroupChangeEvent(Layer layer) {
+
+ protected void fireColorGroupChangeEvent() {
if (layer == null) {
throw new IllegalArgumentException();
}
}
}
+ 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);
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;
gbc.ipady = 0;
gbc.insets = new Insets(3, 3, 3, 3);
colorReplacePanel.add(lblColorReplace, gbc);
-
+
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 1.;
gbc.weighty = 0.;
colorReplacePanel.add(cmbColorReplace, gbc);
-
+
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridwidth = 1;
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"))));
// 色調パネル
- ColorModel colorModel = ColorModels.safeValueOf(layer
- .getColorModelName());
+ ColorModel colorModel = ColorModels.safeValueOf(layer.getColorModelName());
JPanel colorTunePanel = new JPanel();
colorTunePanel.setBorder(BorderFactory.createCompoundBorder(
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);
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());
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];
}
});
}
-
+
// カラーグループ
ColorGroup colorGroup = layer.getColorGroup();
JPanel colorGroupPanel = new JPanel();
public void actionPerformed(ActionEvent e) {
ColorGroup selColorGroup = (ColorGroup) cmbColorGroup.getSelectedItem();
chkColorGroupSync.setSelected(selColorGroup.isEnabled());
- fireColorGroupChangeEvent(layer);
+ fireColorGroupChangeEvent();
}
});
chkColorGroupSync = new JCheckBox(strings.getProperty("synchronized"));
gbc2.ipady = 0;
gbc2.insets = new Insets(3, 3, 3, 3);
colorGroupPanel.add(lblColorGroup, gbc2);
-
+
gbc2.gridx = 1;
gbc2.gridy = 0;
gbc2.gridwidth = 1;
gbc2.weightx = 1.;
gbc2.weighty = 0.;
colorGroupPanel.add(cmbColorGroup, gbc2);
-
+
gbc2.gridx = 2;
gbc2.gridy = 0;
gbc2.gridwidth = GridBagConstraints.REMAINDER;
gbc2.weightx = 0.;
gbc2.weighty = 0.;
colorGroupPanel.add(chkColorGroupSync, gbc2);
-
+
if (colorGroupPanel != null) {
container.add(colorGroupPanel);
}
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>
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;
} finally {
changeEventDisableSemaphore.decrementAndGet();
}
-
+
chachedParam = param;
-
+
firePropertyChange("colorConvertParameter", null, param);
}
-
+
public ColorConvertParameter getColorConvertParameter() {
if (chachedParam != null) {
return chachedParam;
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;
changeEventDisableSemaphore.decrementAndGet();
}
}
-
+
public boolean isSyncColorGroup() {
return chkColorGroupSync == null ? false : chkColorGroupSync.isSelected();
}
-
+
public void setSyncColorGroup(boolean selected) {
if (chkColorGroupSync != null) {
changeEventDisableSemaphore.incrementAndGet();
*/
private final PartsCategory partsCategory;
+ private final JLabel title;
/**
* イメージ選択パネルを構築する
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();
setDisplayMode(DisplayMode.NORMAL);
}
+ @Override
+ public void doLayout() {
+ Font font = getFont();
+ title.setFont(font.deriveFont(Font.BOLD));
+ super.doLayout();
+ }
+
/**
* 表示行数から推奨のパネル高さを求める.<br>
* パネル高さは1行の高さ x 表示行数 + ヘッダ + ボーダー上下である.<br>
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;
CustomLayerOrderPersist.newInstance(characterData)
.addCustomLayerOrderPersistListener(this);
+ // アプリケーション設定の変更で画面の再表示を試行する
+ AppConfig.getInstance().addPropertyChangeListener(appConfigChangeListener);
+
} catch (RuntimeException ex) {
logger.log(Level.SEVERE, "メインフレームの構築中に予期せぬ例外が発生しました。", ex);
dispose(); // コンストラクタが呼ばれた時点でJFrameは構築済みなのでdisposeの必要がある.
.removeCharacterDataChangeListener(this);
CustomLayerOrderPersist.newInstance(characterData)
.removeCustomLayerOrderPersistListener(this);
+ AppConfig.getInstance()
+ .removePropertyChangeListener(appConfigChangeListener);
imageLoader.close();
stopAgents();
}
/**
+ * AppConfigの設定値が変更されたことを通知されるリスナ
+ */
+ private final PropertyChangeListener appConfigChangeListener = new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ // 画面を再描画する
+ repaint();
+ }
+ };
+
+ /**
* 画面コンポーネントを設定します.<br>
* すでに設定されている場合は一旦削除されたのちに再作成されます.<br>
*/
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;
* @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>
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;
mtdWriter.invoke(bean, val);
reject = null;
- } catch (InvocationTargetException ex) {
- reject = ex;
- } catch (IllegalAccessException ex) {
- reject = ex;
- } catch (RuntimeException ex) {
+ } catch (Exception ex) {
reject = ex;
}
}
return rejectNames;
}
-
+
/**
* ビーンのSetter/Getterのペアをもつプロパティの各値をPropertiesに文字列として登録します.<br>
* nullの場合は空文字が設定されます.<br>
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;
+ 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);
}
}
-
+
}
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
<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>
<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>
<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>
<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>
<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>
<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="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>
<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>
<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>
<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>
<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>
<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>