--- /dev/null
+eclipse.preferences.version=1\r
+formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile\r
+formatter_settings_version=12\r
import java.util.logging.Level;\r
import java.util.logging.Logger;\r
\r
+import javax.management.JMException;\r
import javax.swing.JOptionPane;\r
import javax.swing.SwingUtilities;\r
import javax.swing.UIDefaults;\r
import javax.swing.UIManager;\r
\r
import charactermanaj.clipboardSupport.ImageSelection;\r
+import charactermanaj.graphics.io.ImageCacheMBeanImpl;\r
import charactermanaj.model.AppConfig;\r
import charactermanaj.model.util.StartupSupport;\r
import charactermanaj.ui.MainFrame;\r
\r
/**\r
* エントリポイント用クラス\r
- * \r
+ *\r
* @author seraphy\r
*/\r
public final class Main implements Runnable {\r
- \r
+\r
/**\r
* ロガー.<br>\r
*/\r
* Mac OS Xであるか?\r
*/\r
private static final boolean isMacOSX;\r
- \r
+\r
/**\r
* Linuxであるか?\r
*/\r
isMacOSX = lcOS.startsWith("mac os x");\r
isLinux = lcOS.indexOf("linux") >= 0;\r
}\r
- \r
+\r
/**\r
* ロガーの初期化.<br>\r
* 失敗しても継続する.<br>\r
// SwingのEDT内の例外ハンドラの設定 (ロギングするだけ)\r
System.setProperty("sun.awt.exception.handler",\r
AWTExceptionLoggingHandler.class.getName());\r
- \r
+\r
} catch (Throwable ex) {\r
// ロガーの準備に失敗した場合はロガーがないかもなので\r
// コンソールに出力する.\r
logger.log(Level.SEVERE, "logger initiation failed. " + ex, ex);\r
}\r
}\r
- \r
+\r
/**\r
* Javaの簡易なバージョンを取得する.<br>\r
* 不明な場合は0を返す.<br>\r
- * \r
+ *\r
* @return バージョン\r
*/\r
private static double getJavaVersion() {\r
\r
/**\r
* UIをセットアップする.\r
- * \r
+ *\r
* @throws Exception\r
* いろいろな失敗\r
*/\r
private static void setupUIManager() throws Exception {\r
//System.setProperty("swing.aatext", "true");\r
//System.setProperty("awt.useSystemAAFontSettings", "on");\r
- \r
+\r
if (isMacOSX()) {\r
// MacOSXであれば、スクリーンメニューを有効化\r
System.setProperty("apple.laf.useScreenMenuBar", "true");\r
System.setProperty(\r
"com.apple.mrj.application.apple.menu.about.name",\r
"CharacterManaJ");\r
- \r
+\r
// Java7以降であればノーマライズをセットアップする.\r
if (getJavaVersion() >= 1.7) {\r
charactermanaj.util.FileNameNormalizer.setupNFCNormalizer();\r
\r
// 実行プラットフォームのネイティブな外観にする.\r
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());\r
- \r
+\r
// JSpliderのvalueを非表示 (GTKではデフォルトで有効のため)\r
UIManager.put("Slider.paintValue", Boolean.FALSE);\r
\r
}\r
UIManager.put("TextArea.font", textFieldFontUI);\r
}\r
- \r
+\r
/**\r
* 初期処理およびメインフレームを構築する.<br>\r
* SwingのUIスレッドで実行される.<br>\r
*/\r
public void run() {\r
- try {\r
+ try {\r
// UIManagerのセットアップ.\r
try {\r
setupUIManager();\r
ex.printStackTrace();\r
logger.log(Level.WARNING, "UIManager setup failed.", ex);\r
}\r
- \r
+\r
// アプリケーション設定の読み込み\r
AppConfig appConfig = AppConfig.getInstance();\r
appConfig.loadConfig();\r
- \r
+\r
// クリップボードサポートの設定\r
if ( !ImageSelection.setupSystemFlavorMap()) {\r
logger.log(Level.WARNING, "failed to set the clipboard-support.");\r
\r
// スタートアップ時の初期化\r
StartupSupport.getInstance().doStartup();\r
- \r
+\r
// デフォルトのプロファイルを開く.\r
// (最後に使ったプロファイルがあれば、それが開かれる.)\r
MainFrame mainFrame = ProfileListManager.openDefaultProfile();\r
logger.log(Level.CONFIG, "The Apple Java Extensions is not found.", ex);\r
}\r
}\r
- \r
+\r
// 表示(および位置あわせ)\r
mainFrame.showMainFrame();\r
\r
MainFrame.closeAllProfiles();\r
}\r
}\r
- \r
+\r
/**\r
* エントリポイント.<br>\r
* 最初のメインフレームを開いたときにMac OS Xであればスクリーンメニューの登録も行う.<br>\r
- * \r
+ *\r
* @param args\r
* 引数(未使用)\r
*/\r
public static void main(String[] args) {\r
// ロガー等の初期化\r
initLogger();\r
- \r
- // フレームの生成等は、SwingのEDTで実行する.\r
+\r
+ // MBeanのセットアップ\r
+ try {\r
+ ImageCacheMBeanImpl.setupMBean();\r
+\r
+ } catch (JMException ex) {\r
+ // 失敗しても無視して継続する.\r
+ logger.log(Level.SEVERE, ex.getMessage(), ex);\r
+ }\r
+\r
+ // フレームの生成等は、SwingのEDTで実行する.\r
SwingUtilities.invokeLater(new Main());\r
}\r
- \r
+\r
/**\r
* Mac OS Xで動作しているか?\r
- * \r
+ *\r
* @return Max OS X上であればtrue\r
*/\r
public static boolean isMacOSX() {\r
\r
/**\r
* Mac OS X、もしくはlinuxで動作しているか?\r
- * \r
+ *\r
* @return Mac OS X、もしくはlinuxで動作していればtrue\r
*/\r
public static boolean isLinuxOrMacOSX() {\r
public class ColorConvertedImageCachedLoader extends ColorConvertedImageLoaderImpl {\r
\r
private ImageCache<ColorConvertedImageKey> caches = new ImageCache<ColorConvertedImageKey>();\r
- \r
+\r
public ColorConvertedImageCachedLoader() {\r
this(new ImageCachedLoader());\r
}\r
- \r
+\r
public ColorConvertedImageCachedLoader(ImageLoader imageLoader) {\r
super(imageLoader);\r
}\r
param = colorConvParam.clone();\r
}\r
ColorConvertedImageKey key = new ColorConvertedImageKey(param, file);\r
- \r
+\r
synchronized (caches) {\r
LoadedImage loadedImage = caches.get(key);\r
if (loadedImage == null) {\r
return loadedImage;\r
}\r
}\r
- \r
+\r
+ @Override\r
+ public void close() {\r
+ caches.clear();\r
+ super.close();\r
+ }\r
+\r
public void unlockImages() {\r
caches.unlockImages();\r
}\r
- \r
+\r
}\r
\r
final class ColorConvertedImageKey {\r
- \r
+\r
private final ColorConvertParameter colorConvParameter;\r
- \r
+\r
private final ImageResource imageResource;\r
- \r
+\r
private final long lastModified;\r
- \r
+\r
private final int hashCode;\r
- \r
+\r
public ColorConvertedImageKey(ColorConvertParameter colorConvParameter, ImageResource imageResource) {\r
if (colorConvParameter == null || imageResource == null) {\r
throw new IllegalArgumentException();\r
this.hashCode = imageResource.hashCode()\r
^ colorConvParameter.hashCode() ^ (int) this.lastModified;\r
}\r
- \r
+\r
@Override\r
public int hashCode() {\r
return this.hashCode;\r
}\r
- \r
+\r
@Override\r
public boolean equals(Object obj) {\r
if (obj == this) {\r
\r
import java.awt.image.BufferedImage;\r
import java.awt.image.RescaleOp;\r
+import java.io.Closeable;\r
import java.io.IOException;\r
\r
import charactermanaj.graphics.colormodel.ColorModel;\r
* 画像リソースをロードし色変換された結果の画像イメージとして返す.<br>\r
* @author seraphy\r
*/\r
-public class ColorConvertedImageLoaderImpl implements ColorConvertedImageLoader {\r
+public class ColorConvertedImageLoaderImpl implements ColorConvertedImageLoader, Closeable {\r
\r
private static final ColorConvertParameter NULL_COLORCONVPARAM = new ColorConvertParameter();\r
\r
private ImageLoader loader;\r
\r
- \r
+\r
public ColorConvertedImageLoaderImpl(ImageLoader loader) {\r
if (loader == null) {\r
throw new IllegalArgumentException();\r
}\r
this.loader = loader;\r
}\r
- \r
- \r
+\r
+\r
/**\r
* 画像リソースをロードし色変換した結果のBufferedImageを返します.<br>\r
* 返される形式はARGBに変換されています.<br>\r
- * \r
+ *\r
* @param file\r
* 画像リソース\r
* @param colorConvParam\r
colorModel);\r
return new LoadedImage(image, loadedImage.getLastModified());\r
}\r
- \r
+\r
+ public void close() {\r
+ if (loader instanceof Closeable) {\r
+ try {\r
+ ((Closeable) loader).close();\r
+\r
+ } catch (RuntimeException ex) {\r
+ throw ex;\r
+ } catch (Exception ex) {\r
+ throw new RuntimeException(ex);\r
+ }\r
+ }\r
+ }\r
+\r
/**\r
* 色変換ロジック.\r
* @param img 元画像(ARGB形式)\r
param.getSaturation(),\r
param.getBrightness()\r
};\r
- \r
+\r
float contrast = param.getContrast();\r
\r
ColorConvertFilter colorConvert_op = new ColorConvertFilter(\r
* 画像のキャッシュ.<br>\r
* キャッシュは自動的にガベージコレクタにより回収されます.<br>\r
* ただし、{@link #unlockImages()}が呼び出されるまで、{@link #set(Object, BufferedImage)}されたイメージは\r
- * ガベージコレクトの対象にはなりません。 \r
+ * ガベージコレクトの対象にはなりません。\r
* @author seraphy\r
*\r
* @param <K>\r
*/\r
public class ImageCache<K> {\r
- \r
+\r
private static final Logger logger = Logger.getLogger(ImageCache.class.getName());\r
\r
+ private static final ImageCacheMBeanImpl imageCacheMBean = ImageCacheMBeanImpl.getSingleton();\r
+\r
private HashMap<K, BufferedImageWithKeyReference<K>> lockedImages\r
= new HashMap<K, BufferedImageWithKeyReference<K>>();\r
- \r
- private ReferenceQueue<? super LoadedImage> queue\r
- = new ReferenceQueue<LoadedImage>();\r
- \r
+\r
+ private ReferenceQueue<LoadedImage> queue = new ReferenceQueue<LoadedImage>();\r
+\r
private HashMap<K, BufferedImageWithKeyReference<K>> caches\r
= new HashMap<K, BufferedImageWithKeyReference<K>>();\r
- \r
+\r
+ public ImageCache() {\r
+ imageCacheMBean.incrementInstance();\r
+ }\r
+\r
+ @Override\r
+ protected void finalize() throws Throwable {\r
+ clear();\r
+ imageCacheMBean.decrementInstance();\r
+ super.finalize();\r
+ }\r
+\r
public LoadedImage get(K key) {\r
if (key == null) {\r
return null;\r
if (ref != null) {\r
img = ref.get();\r
}\r
+ imageCacheMBean.incrementReadCount(img != null);\r
sweep();\r
return img;\r
}\r
return;\r
}\r
synchronized (caches) {\r
- if (img == null) {\r
+ // 現在キャッシュされているものがあれば、いったん解放する.\r
+ BufferedImageWithKeyReference<K> ref = caches.get(key);\r
+ if (ref != null) {\r
+ ref.enqueue();\r
+ }\r
+\r
+ if (img == null) {\r
if (logger.isLoggable(Level.FINE)) {\r
logger.log(Level.FINE, "remove cache: " + key);\r
}\r
caches.remove(key);\r
+\r
} else {\r
BufferedImageWithKeyReference<K> cacheData = new BufferedImageWithKeyReference<K>(key, img, queue);\r
lockedImages.put(key, cacheData);\r
caches.put(key, cacheData);\r
+\r
+ imageCacheMBean.cacheIn(cacheData.getImageSize());\r
}\r
- sweep();\r
+\r
+ // 解放済みのアイテムエントリを除去する.\r
+ sweep();\r
}\r
}\r
- \r
+\r
public void unlockImages() {\r
synchronized (caches) {\r
lockedImages.clear();\r
sweep();\r
}\r
}\r
- \r
+\r
+ /**\r
+ * すべてのエントリをキャッシュアウトしてクリアする.\r
+ */\r
+ public void clear() {\r
+ synchronized (caches) {\r
+ lockedImages.clear();\r
+ for (BufferedImageWithKeyReference<K> ref : caches.values()) {\r
+ ref.enqueue();\r
+ }\r
+ sweep();\r
+ caches.clear();\r
+ }\r
+ }\r
+\r
public void sweep() {\r
synchronized (caches) {\r
// ガベージコレクト済みアイテムを除去する\r
boolean removed = false;\r
while ((ref = queue.poll()) != null) {\r
@SuppressWarnings("unchecked")\r
- K key = ((BufferedImageWithKeyReference<K>) ref).getKey();\r
+ BufferedImageWithKeyReference<K> r =\r
+ (BufferedImageWithKeyReference<K>) ref;\r
+ K key = r.getKey();\r
if (key != null) {\r
if (caches.get(key).get() == null) {\r
if (logger.isLoggable(Level.FINE)) {\r
caches.remove(key);\r
}\r
}\r
+\r
+ int imageSize = r.getImageSize();\r
+ imageCacheMBean.cacheOut(imageSize);\r
}\r
if (removed) {\r
if (logger.isLoggable(Level.FINE)) {\r
* @param <K> キー\r
*/\r
class BufferedImageWithKeyReference<K> extends SoftReference<LoadedImage> {\r
- \r
+\r
private final K key;\r
- \r
+\r
+ private final int imageSize;\r
+\r
public BufferedImageWithKeyReference(K key, LoadedImage img, ReferenceQueue<? super LoadedImage> queue) {\r
super(img, queue);\r
this.key = key;\r
+ this.imageSize = (img == null) ? 0 : img.getImageSize();\r
}\r
- \r
+\r
public K getKey() {\r
return key;\r
}\r
+\r
+ public int getImageSize() {\r
+ return imageSize;\r
+ }\r
}\r
--- /dev/null
+package charactermanaj.graphics.io;\r
+\r
+public interface ImageCacheMBean {\r
+\r
+ long getReadCount();\r
+\r
+ long getCacheHitCount();\r
+\r
+ long getTotalBytes();\r
+\r
+ long getMaxBytes();\r
+\r
+ int getTotalCount();\r
+\r
+ int getInstanceCount();\r
+\r
+ void reset();\r
+}\r
--- /dev/null
+package charactermanaj.graphics.io;\r
+\r
+import java.lang.management.ManagementFactory;\r
+\r
+import javax.management.JMException;\r
+import javax.management.MBeanServer;\r
+import javax.management.ObjectName;\r
+import javax.management.StandardMBean;\r
+\r
+public final class ImageCacheMBeanImpl implements ImageCacheMBean {\r
+\r
+ private static ImageCacheMBeanImpl singleton = new ImageCacheMBeanImpl();\r
+\r
+ private ImageCacheMBeanImpl() {\r
+ super();\r
+ }\r
+\r
+ public static ImageCacheMBeanImpl getSingleton() {\r
+ return singleton;\r
+ }\r
+\r
+ public static void setupMBean() throws JMException {\r
+ MBeanServer srv = ManagementFactory.getPlatformMBeanServer();\r
+ srv.registerMBean(\r
+ new StandardMBean(singleton, ImageCacheMBean.class),\r
+ new ObjectName("CharacterManaJ:type=ImageCache,name=Singleton"));\r
+ }\r
+\r
+ private long readCount;\r
+\r
+ private long cacheHitCount;\r
+\r
+ private long totalBytes;\r
+\r
+ private long maxBytes;\r
+\r
+ private int totalCount;\r
+\r
+ private int instanceCount;\r
+\r
+ public synchronized long getReadCount() {\r
+ return readCount;\r
+ }\r
+\r
+ public synchronized void setReadCount(long readCount) {\r
+ this.readCount = readCount;\r
+ }\r
+\r
+ public synchronized long getCacheHitCount() {\r
+ return cacheHitCount;\r
+ }\r
+\r
+ public synchronized void setCacheHitCount(long cacheHitCount) {\r
+ this.cacheHitCount = cacheHitCount;\r
+ }\r
+\r
+ public synchronized long getTotalBytes() {\r
+ return totalBytes;\r
+ }\r
+\r
+ public synchronized void setTotalBytes(long totalBytes) {\r
+ this.totalBytes = totalBytes;\r
+ }\r
+\r
+ public synchronized long getMaxBytes() {\r
+ return maxBytes;\r
+ }\r
+\r
+ public synchronized void setMaxBytes(long maxBytes) {\r
+ this.maxBytes = maxBytes;\r
+ }\r
+\r
+ public synchronized void incrementReadCount(boolean cacheHit) {\r
+ readCount++;\r
+ if (cacheHit) {\r
+ cacheHitCount++;\r
+ }\r
+ }\r
+\r
+ public synchronized void cacheIn(long bytes) {\r
+ totalCount++;\r
+ totalBytes += bytes;\r
+ if (totalBytes > maxBytes) {\r
+ maxBytes = totalBytes;\r
+ }\r
+ }\r
+\r
+ public synchronized void cacheOut(long bytes) {\r
+ totalCount--;\r
+ totalBytes -= bytes;\r
+ }\r
+\r
+ public synchronized int getTotalCount() {\r
+ return totalCount;\r
+ }\r
+\r
+ public synchronized int getInstanceCount() {\r
+ return instanceCount;\r
+ }\r
+\r
+ public synchronized void incrementInstance() {\r
+ instanceCount++;\r
+ }\r
+\r
+ public synchronized void decrementInstance() {\r
+ instanceCount--;\r
+ }\r
+\r
+ public synchronized void reset() {\r
+ cacheHitCount = 0;\r
+ readCount = 0;\r
+ totalCount = 0;\r
+ totalBytes = 0;\r
+ maxBytes = 0;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ synchronized (this) {\r
+ StringBuilder buf = new StringBuilder();\r
+ buf.append("imageCacheMBean ");\r
+ buf.append(cacheHitCount);\r
+ buf.append("/");\r
+ buf.append(readCount);\r
+ return buf.toString();\r
+ }\r
+ }\r
+}\r
package charactermanaj.graphics.io;\r
\r
+import java.io.Closeable;\r
import java.io.IOException;\r
\r
\r
/**\r
* 一度読み込んだ画像をキャッシュする画像ローダ.<br>\r
- * すでに読み込まれており、ファイルの更新日に変更がなければ読み込み済みの画像をかえす.<br> \r
+ * すでに読み込まれており、ファイルの更新日に変更がなければ読み込み済みの画像をかえす.<br>\r
* @author seraphy\r
*/\r
-public class ImageCachedLoader extends ImageLoaderImpl {\r
+public class ImageCachedLoader extends ImageLoaderImpl implements Closeable {\r
\r
/**\r
* リソースに対するイメージキャッシュ.<br>\r
* リソースは複数のプロファイルで共有しえるのでstaticとしている。\r
*/\r
private static ImageCache<ImageResourceCacheKey> caches = new ImageCache<ImageResourceCacheKey>();\r
- \r
- public LoadedImage load(ImageResource imageResource) throws IOException {\r
+\r
+ @Override\r
+ public LoadedImage load(ImageResource imageResource) throws IOException {\r
if (imageResource == null) {\r
throw new IllegalArgumentException();\r
}\r
loadedImage = null;\r
}\r
}\r
- \r
+\r
if (loadedImage == null) {\r
loadedImage = super.load(imageResource);\r
caches.set(key, loadedImage);\r
return loadedImage;\r
}\r
}\r
+\r
+ public void close() {\r
+ caches.clear();\r
+ }\r
}\r
\r
final class ImageResourceCacheKey {\r
\r
private final ImageResource imageResource;\r
- \r
+\r
private final int hashCode;\r
- \r
+\r
public ImageResourceCacheKey(ImageResource imageResource) {\r
if (imageResource == null) {\r
throw new IllegalArgumentException();\r
this.imageResource = imageResource;\r
this.hashCode = imageResource.hashCode();\r
}\r
- \r
+\r
@Override\r
public int hashCode() {\r
return this.hashCode;\r
}\r
- \r
+\r
@Override\r
public boolean equals(Object obj) {\r
if (obj == this) {\r
package charactermanaj.graphics.io;\r
\r
import java.awt.image.BufferedImage;\r
+import java.awt.image.DataBuffer;\r
\r
/**\r
* ロードされたイメージ情報\r
public final class LoadedImage {\r
\r
private final BufferedImage image;\r
- \r
+\r
private final long lastModified;\r
- \r
+\r
+ private final int imageSize;\r
+\r
public LoadedImage(BufferedImage image, long lastModified) {\r
this.image = image;\r
this.lastModified = lastModified;\r
+ this.imageSize = getBufferSize(image);\r
}\r
- \r
+\r
public BufferedImage getImage() {\r
return image;\r
}\r
- \r
+\r
public long getLastModified() {\r
return lastModified;\r
}\r
- \r
+\r
+ public int getImageSize() {\r
+ return imageSize;\r
+ }\r
+\r
+ /**\r
+ * 画像バッファのバイト数を求める.<br>\r
+ * @param image イメージ\r
+ * @return バイト数\r
+ */\r
+ private static int getBufferSize(BufferedImage image) {\r
+ if (image == null) {\r
+ return 0;\r
+ }\r
+ DataBuffer buff = image.getRaster().getDataBuffer();\r
+ int bytes = buff.getSize() * DataBuffer.getDataTypeSize(buff.getDataType()) / 8;\r
+ return bytes;\r
+ }\r
}\r
/**\r
* メインフレーム.<br>\r
* アプリケーションがアクティブである場合は最低でも1つのメインフレームが表示されている.<br>\r
- * \r
+ *\r
* @author seraphy\r
*/\r
public class MainFrame extends JFrame {\r
\r
private static final long serialVersionUID = 1L;\r
- \r
+\r
private static final Logger logger = Logger.getLogger(MainFrame.class.getName());\r
\r
- \r
+\r
protected static final String STRINGS_RESOURCE = "languages/mainframe";\r
- \r
+\r
protected static final String MENU_STRINGS_RESOURCE = "menu/menu";\r
- \r
+\r
\r
/**\r
* メインフレームのアイコン.<br>\r
*/\r
protected BufferedImage icon;\r
- \r
+\r
\r
/**\r
* 現在アクティブなメインフレーム.<br>\r
*/\r
protected CharacterData characterData;\r
\r
- \r
+\r
/**\r
* プレビューペイン\r
*/\r
private PreviewPanel previewPane;\r
- \r
+\r
/**\r
* パーツ選択マネージャ\r
*/\r
protected PartsSelectionManager partsSelectionManager;\r
- \r
+\r
/**\r
* パネルの最小化モード\r
*/\r
* パーツ選択パネルリスト\r
*/\r
protected ImageSelectPanelList imageSelectPanels;\r
- \r
+\r
/**\r
* パーツ選択パネルを納めるスクロールペイン\r
*/\r
protected JScrollPane imgSelectPanelsPanelSp;\r
- \r
+\r
/**\r
* カラーグループのマネージャ\r
*/\r
protected ColorGroupCoordinator colorGroupCoordinator;\r
- \r
+\r
/**\r
* パーツカラーのマネージャ\r
- */ \r
+ */\r
protected PartsColorCoordinator partsColorCoordinator;\r
- \r
+\r
\r
/**\r
* キャッシュつきのイメージローダ.<br>\r
*/\r
private AsyncImageBuilder imageBuilder;\r
\r
- \r
+\r
/**\r
* パーツイメージを画像として保存する場合のヘルパー.<br>\r
* 最後に使ったディレクトリを保持するためのメンバ変数としている.<br>\r
*/\r
private ImageSaveHelper imageSaveHelper = new ImageSaveHelper();\r
- \r
+\r
/**\r
* 伺か用出力ヘルパ.<br>\r
* 最後に使ったディレクトリ、ファイル名、モードなどを保持するためのメンバ変数としている.<br>\r
* パーツディレクトリを定期的にチェックし、パーツイメージが変更・追加・削除されている場合に パーツリストを更新するためのウォッチャー\r
*/\r
private PartsImageDirectoryWatchAgent watchAgent;\r
- \r
+\r
/**\r
* デフォルトのパーツセット表示名\r
*/\r
private String defaultPartsSetTitle;\r
- \r
+\r
/**\r
* 最後に使用したプリセット.<br>\r
* (一度もプリセットを使用していなければnull).\r
*/\r
private PartsSet lastUsePresetParts;\r
- \r
+\r
/**\r
* 最後に使用した検索ダイアログ.<br>\r
* nullであれば一度も使用していない.<br>\r
* (nullでなくとも閉じられている可能性がある.)<br>\r
*/\r
private SearchPartsDialog lastUseSearchPartsDialog;\r
- \r
+\r
/**\r
* 最後に使用した壁紙情報\r
*/\r
private WallpaperInfo wallpaperInfo;\r
- \r
- \r
+\r
+\r
/**\r
* アクティブなメインフレームを設定する.\r
- * \r
+ *\r
* @param mainFrame\r
* メインフレーム\r
*/\r
}\r
activedMainFrame = mainFrame;\r
}\r
- \r
+\r
/**\r
* 現在アクティブなメインフレームを取得する. まだメインフレームが開かれていない場合はnull.<br>\r
* 最後のメインフレームが破棄中、もしくは破棄済みであれば破棄されたフレームを示すことに注意.<br>\r
- * \r
+ *\r
* @return メインフレーム、もしくはnull\r
*/\r
public static MainFrame getActivedMainFrame() {\r
return activedMainFrame;\r
}\r
- \r
+\r
/**\r
* インポートされパーツが増減した可能性がある場合に呼び出される.\r
- * \r
+ *\r
* @param cd\r
* 対象\r
* @param newCd\r
return;\r
}\r
logger.log(Level.FINE, "parts imported for active profiles: " + newCd);\r
- \r
+\r
\r
if ( !cd.isSameStructure(newCd)) {\r
// キャラクターデータそのものが変更されている場合\r
\r
} else {\r
// パーツ構成は変更されていない場合\r
- \r
+\r
// Frameのうち、ネイティブリソースと関連づけられているアクティブなフレームを調査\r
for (Frame frame : JFrame.getFrames()) {\r
if (frame.isDisplayable() && frame instanceof MainFrame) {\r
caller.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));\r
try {\r
mainFrame.reloadPartsAndFavorites(newCd, true);\r
- \r
+\r
} finally {\r
mainFrame.setCursor(oldCur != null ? oldCur : Cursor.getDefaultCursor());\r
}\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(mainFrame, ex);\r
}\r
}\r
}\r
}\r
- \r
+\r
/**\r
* キャラクターデータが変更されたことを通知される.<br>\r
- * \r
+ *\r
* @param cd\r
* キャラクターデータ(変更前)\r
* @param newCd\r
return;\r
}\r
logger.log(Level.FINE, "change active profile: " + newCd);\r
- \r
+\r
if (!ProfileListManager.isUsingCharacterData(cd)) {\r
// 使用中のプロファイルではないので何もしない.\r
return;\r
}\r
- \r
+\r
caller.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));\r
try {\r
// キャラクターデータが、まだ読み込まれていなければ読み込む.\r
ProfileListManager.loadCharacterData(newCd);\r
ProfileListManager.loadFavorites(newCd);\r
}\r
- \r
+\r
// Frameのうち、ネイティブリソースと関連づけられているアクティブなフレームを調査\r
for (Frame frame : JFrame.getFrames()) {\r
if (frame.isDisplayable() && frame instanceof MainFrame) {\r
try {\r
// 現在情報の保存\r
mainFrame.saveWorkingSet();\r
- \r
+\r
// 画面構成の再構築\r
mainFrame.initComponent(newCd);\r
- \r
+\r
} finally {\r
mainFrame.setCursor(oldCur != null ? oldCur : Cursor.getDefaultCursor());\r
}\r
- \r
+\r
} catch (RuntimeException ex) {\r
ErrorMessageHelper.showErrorDialog(mainFrame, ex);\r
}\r
\r
/**\r
* お気に入りデータが変更されたことを通知される.\r
- * \r
+ *\r
* @param cd\r
* キャラクターデータ\r
*/\r
if (cd == null) {\r
throw new IllegalArgumentException();\r
}\r
- \r
+\r
// Frameのうち、ネイティブリソースと関連づけられているアクティブなフレームを調査\r
for (Frame frame : JFrame.getFrames()) {\r
if (frame.isDisplayable() && frame instanceof MainFrame) {\r
\r
/**\r
* メインフレームを構築する.\r
- * \r
+ *\r
* @param characterData\r
* キャラクターデータ\r
*/\r
if (characterData == null) {\r
throw new IllegalArgumentException();\r
}\r
- \r
+\r
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);\r
addWindowListener(new WindowAdapter() {\r
@Override\r
// アイコンの設定\r
icon = UIHelper.getInstance().getImage("icons/icon.png");\r
setIconImage(icon);\r
- \r
+\r
// 画面コンポーネント作成\r
initComponent(characterData);\r
JMenuBar menuBar = createMenuBar();\r
setJMenuBar(menuBar);\r
- \r
+\r
// メインスクリーンサイズを取得する.\r
GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();\r
Rectangle desktopSize = genv.getMaximumWindowBounds(); // メインスクリーンのサイズ(デスクトップ領域のみ)\r
logger.log(Level.CONFIG, "desktopSize=" + desktopSize);\r
- \r
+\r
Dimension imageSize = characterData.getImageSize();\r
// 画像サイズ300x400を基準サイズとして、それ以下にはならない.\r
// アプリケーション設定の最大サイズ以上の場合はウィンドウサイズは固定してスクロールバーに任せる\r
\r
// 次回表示時にプラットフォーム固有位置に表示するように予約\r
setLocationByPlatform(true);\r
- \r
+\r
} catch (RuntimeException ex) {\r
logger.log(Level.SEVERE, "メインフレームの構築中に予期せぬ例外が発生しました。", ex);\r
dispose(); // コンストラクタが呼ばれた時点でJFrameは構築済みなのでdisposeの必要がある.\r
throw ex;\r
}\r
}\r
- \r
+\r
/**\r
* メインフレームを表示する.<br>\r
* デスクトップ領域からはみ出した場合は位置を補正する.<br>\r
if (watchAgent != null) {\r
try {\r
watchAgent.disconnect();\r
- \r
+\r
} catch (Throwable ex) {\r
logger.log(Level.SEVERE, "フォルダ監視スレッドの停止に失敗しました。", ex);\r
}\r
*/\r
@Override\r
public void dispose() {\r
+ imageLoader.close();\r
stopAgents();\r
super.dispose();\r
}\r
- \r
+\r
/**\r
* 画面コンポーネントを設定します.<br>\r
* すでに設定されている場合は一旦削除されたのちに再作成されます.<br>\r
*/\r
private void initComponent(CharacterData characterData) {\r
- \r
+\r
CharacterData oldCd;\r
synchronized (this) {\r
oldCd = this.characterData;\r
// 使用中のキャラクターデータであることを登録する.\r
ProfileListManager.registerUsedCharacterData(characterData);\r
}\r
- \r
+\r
// 設定まわり準備\r
AppConfig appConfig = AppConfig.getInstance();\r
Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()\r
title = strings.getProperty("title");\r
}\r
setTitle(title + characterData.getName());\r
- \r
+\r
// デフォルトのパーツセット表示名\r
defaultPartsSetTitle = strings.getProperty("defaultPartsSetTitle");\r
\r
\r
// コンポーネント配置\r
Container contentPane = getContentPane();\r
- \r
+\r
// すでにあるコンポーネントを削除\r
for (Component comp : contentPane.getComponents()) {\r
contentPane.remove(comp);\r
}\r
// 開いている検索ダイアログを閉じる\r
closeSearchDialog();\r
- \r
+\r
PartsColorManager partsColorManager = characterData.getPartsColorManager();\r
\r
// デフォルトの背景色の設定\r
wallpaperInfo = new WallpaperInfo();\r
wallpaperInfo.setBackgroundColor(bgColor);\r
\r
+ if (imageLoader != null) {\r
+ imageLoader.close();\r
+ }\r
imageLoader = new ColorConvertedImageCachedLoader();\r
imageBuilder = new AsyncImageBuilder(imageLoader);\r
partsSelectionManager = new PartsSelectionManager(partsColorManager,\r
if ( !e.isShiftKeyPressed()) {\r
// 画像出力\r
onSavePicture();\r
- \r
+\r
} else {\r
// シフトキーにて「伺か」用出力\r
onSaveAsUkagaka();\r
onFlipHolizontal();\r
}\r
});\r
- \r
+\r
imageSelectPanels = new ImageSelectPanelList();\r
- \r
+\r
JPanel imgSelectPanelsPanel = new JPanel();\r
BoxLayout bl = new BoxLayout(imgSelectPanelsPanel, BoxLayout.PAGE_AXIS);\r
imgSelectPanelsPanel.setLayout(bl);\r
imageSelectPanels.add(imageSelectPanel);\r
partsSelectionManager.register(imageSelectPanel);\r
}\r
- \r
+\r
imgSelectPanelsPanelSp = new JScrollPane(imgSelectPanelsPanel) {\r
private static final long serialVersionUID = 1L;\r
@Override\r
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, imgSelectPanelsPanelSp, previewPane);\r
contentPane.add(splitPane, BorderLayout.CENTER);\r
\r
- \r
+\r
imgSelectPanelsPanelSp.requestFocus();\r
- \r
+\r
ArrayList<ColorGroup> colorGroups = new ArrayList<ColorGroup>();\r
colorGroups.addAll(characterData.getColorGroups());\r
- \r
+\r
final ColorChangeListener colorChangeListener = new ColorChangeListener() {\r
public void onColorGroupChange(ColorChangeEvent event) {\r
// do nothing.\r
}\r
};\r
colorGroupCoordinator.addColorChangeListener(colorChangeListener);\r
- \r
+\r
for (int idx = 0; idx < imageSelectPanels.size(); idx++) {\r
ImageSelectPanel imageSelectPanel = imageSelectPanels.get(idx);\r
final PartsCategory partsCategory = imageSelectPanel.getPartsCategory();\r
}\r
});\r
}\r
- \r
+\r
// 全パーツのロード\r
partsSelectionManager.loadParts();\r
- \r
+\r
// 保存されているワーキングセットを復元する.\r
// 復元できなかった場合はパーツセットを初期選択する.\r
if ( !loadWorkingSet()) {\r
if (!imageBuilder.isAlive()) {\r
imageBuilder.start();\r
}\r
- \r
+\r
// ドロップターゲットの設定\r
new DropTarget(imgSelectPanelsPanelSp, new FileDropTarget() {\r
@Override\r
ErrorMessageHelper.showErrorDialog(MainFrame.this, ex);\r
}\r
});\r
- \r
+\r
// ディレクトリを監視し変更があった場合にパーツをリロードするリスナ\r
watchAgent.addPartsImageDirectoryWatchListener(new PartsImageDirectoryWatchListener() {\r
public void detectPartsImageChange(PartsImageDirectoryWatchEvent e) {\r
if (appConfig.isEnableDirWatch() && characterData.isWatchDirectory()) {\r
watchAgent.connect();\r
}\r
- \r
+\r
// パーツカテゴリの自動縮小が設定されている場合\r
minimizeMode = false;\r
if (appConfig.isEnableAutoShrinkPanel()) {\r
onClickPartsCategoryTitle(null, true);\r
}\r
- \r
+\r
// コンポーネントの再構築の場合\r
if (oldCd != null) {\r
validate();\r
protected void scrollToSelectedParts() {\r
partsSelectionManager.scrollToSelectedParts();\r
}\r
- \r
+\r
/**\r
* 指定したパーツカテゴリ以外のパーツ選択パネルを最小化する.\r
- * \r
+ *\r
* @param partsCategory\r
* パーツカテゴリ、nullの場合は全て最小化する.\r
* @param dblClick\r
* デフォルトパーツがなければお気に入りの最初のものを選択する.<br>\r
* それもなければ空として表示する.<br>\r
* パーツの適用に失敗した場合はfalseを返します.(例外は返されません.)<br>\r
- * \r
+ *\r
* @param force\r
* すでに選択があっても選択しなおす場合はtrue、falseの場合は選択があれば何もしない.\r
* @return パーツ選択された場合。force=trueの場合はエラーがなければ常にtrueとなります。\r
return false;\r
}\r
}\r
- \r
+\r
// デフォルトのパーツセットを取得する\r
String defaultPresetId = characterData.getDefaultPartsSetId();\r
PartsSet partsSet = null;\r
if (defaultPresetId != null) {\r
partsSet = characterData.getPartsSets().get(defaultPresetId);\r
}\r
- \r
+\r
// デフォルトのパーツセットがなければ、お気に入りの最初を選択する.\r
if (partsSet == null) {\r
List<PartsSet> partssets = getPartsSetList();\r
partsSet = partssets.get(0);\r
}\r
}\r
- \r
+\r
// パーツセットがあれば、それを表示要求する.\r
// パーツセットがなければカラーダイアログを初期化するのみ\r
if (partsSet == null) {\r
} else {\r
selectPresetParts(partsSet);\r
}\r
- \r
+\r
} catch (Exception ex) {\r
logger.log(Level.WARNING, "パーツのデフォルト適用に失敗しました。", ex);\r
return false;\r
}\r
return true;\r
}\r
- \r
+\r
/**\r
* プリセットを適用しキャラクターイメージを再構築します.<br>\r
* 実行時エラーは画面のレポートされます.<br>\r
- * \r
+ *\r
* @param presetParts\r
* パーツセット, nullの場合は何もしない.\r
*/\r
partsColorCoordinator.initColorDialog();\r
// 再表示\r
requestPreview();\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* プリセットとお気に入りを表示順に並べて返す.\r
- * \r
+ *\r
* @return プリセットとお気に入りのリスト(表示順)\r
*/\r
protected List<PartsSet> getPartsSetList() {\r
});\r
return partssets;\r
}\r
- \r
+\r
/**\r
* お気に入りメニューが開いたとき\r
- * \r
+ *\r
* @param menu\r
*/\r
protected void onSelectedFavoriteMenu(JMenu menu) {\r
menu.remove(separatorIdx + 1);\r
}\r
}\r
- \r
+\r
// 表示順にソート\r
List<PartsSet> partssets = getPartsSetList();\r
- \r
+\r
// メニューの再構築\r
\r
MenuBuilder menuBuilder = new MenuBuilder();\r
menu.add(favoriteMenu);\r
}\r
}\r
- \r
+\r
/**\r
* ヘルプメニューを開いたときにお勧めメニューを構築する.\r
- * \r
+ *\r
* @param menu\r
*/\r
protected void onSelectedRecommendationMenu(JMenu mnuRecomendation) {\r
for (RecommendationURL recommendation : recommendations) {\r
String displayName = recommendation.getDisplayName();\r
String url = recommendation.getUrl();\r
- \r
+\r
JMenuItem mnuItem = menuBuilder.createJMenuItem();\r
mnuItem.setText(displayName);\r
mnuItem.addActionListener(\r
mnuRecomendation.add(mnuItem);\r
}\r
}\r
- \r
+\r
// お勧めリンクメニューのリストがnullでなく空でもない場合は有効、そうでなければ無効にする.\r
mnuRecomendation.setEnabled(recommendations != null && !recommendations.isEmpty());\r
}\r
\r
- \r
+\r
/**\r
* 最後に選択されたお気に入りと同じ構成であれば、 このお気に入りの名前をプレビューペインのタイトルに設定する.<br>\r
* そうでなければデフォルトのパーツセット名(no titleとか)を表示する.<br>\r
* 色情報が異なる場合に末尾に「*」マークがつけられる.<br>\r
- * \r
+ *\r
* @param requestPartsSet\r
* 表示するパーツセット(名前は設定されていなくて良い。お気に入り側を使うので。), nullの場合はデフォルトのパーツ名\r
*/\r
}\r
previewPane.setTitle(title);\r
}\r
- \r
+\r
/**\r
* パーツセット名を推定する.<br>\r
* 最後に選択されたお気に入りと同じ構成であれば、 このお気に入りの名前を返す.<br>\r
* お気に入りが選択されていないか構成が異なる場合、お気に入りに名前がない場合はnullを返す.<br>\r
- * \r
+ *\r
* @param requestPartsSet\r
* 表示するパーツセット(名前は設定されていなくて良い。お気に入り側を使うので。)\r
* @param markColorChange\r
}\r
return null;\r
}\r
- \r
+\r
/**\r
* プレビューの更新を要求する. 更新は非同期に行われる.\r
*/\r
if (!characterData.isValid()) {\r
return;\r
}\r
- \r
+\r
// 選択されているパーツの各イメージを取得しレイヤー順に並び替えて合成する.\r
// 合成は別スレッドにて非同期に行われる.\r
// リクエストは随時受け付けて、最新のリクエストだけが処理される.\r
* 構築するパーツセット情報\r
*/\r
private PartsSet requestPartsSet;\r
- \r
+\r
/**\r
* 非同期のイメージ構築要求の番号.<br>\r
*/\r
private long ticket;\r
- \r
+\r
@Override\r
public void onQueueing(long ticket) {\r
this.ticket = ticket;\r
// スレッドによるSwingのイベントディスパッチスレッド以外からの呼び出しの場合、\r
// Swingディスパッチスレッドでパーツの選択状態を取得する.\r
SwingUtilities.invokeAndWait(collectPartsSetJob);\r
- \r
+\r
} catch (InvocationTargetException e) {\r
throw new RuntimeException(e.getMessage(), e);\r
} catch (InterruptedException e) {\r
}\r
});\r
}\r
- \r
+\r
/**\r
* プロファイルを開く\r
*/\r
getJMenuBar().setEnabled(true);\r
}\r
}\r
- \r
+\r
/**\r
* 壁紙を変更する.\r
*/\r
protected void onChangeWallpaper() {\r
try {\r
WallpaperDialog wallpaperDialog = new WallpaperDialog(this);\r
- \r
+\r
// 最後に使用した壁紙情報でダイアログを設定する.\r
wallpaperDialog.setWallpaperInfo(this.wallpaperInfo);\r
- \r
+\r
// 壁紙情報を設定するモーダルダイアログを開く\r
WallpaperInfo wallpaperInfo = wallpaperDialog.showDialog();\r
if (wallpaperInfo == null) {\r
\r
// 壁紙情報を保存し、その情報をもとに背景を再描画する.\r
applyWallpaperInfo(wallpaperInfo, false);\r
- \r
+\r
} catch (WallpaperFactoryException ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* 背景色のみ変更し、背景を再描画する.<br>\r
* 壁紙情報全体の更新よりも効率化するためのメソッドである.<br>\r
- * \r
+ *\r
* @param bgColor\r
* 背景色\r
*/\r
/**\r
* 壁紙情報を保存し、その情報をもとに背景を再描画する.<br>\r
* ignoreErrorがtrueである場合、適用に失敗した場合はログに記録するのみで、 壁紙情報は保存されず、壁紙も更新されない.<br>\r
- * \r
+ *\r
* @param wallpaperInfo\r
* 壁紙情報、null不可\r
* @param ignoreError\r
if (ignoreError) {\r
handler = new WallpaperFactoryErrorRecoverHandler();\r
}\r
- \r
+\r
// 壁紙情報\r
wallpaper = wallpaperFactory.createWallpaper(wallpaperInfo, handler);\r
- \r
+\r
} catch (WallpaperFactoryException ex) {\r
logger.log(Level.WARNING, "壁紙情報の適用に失敗しました。", ex);\r
if ( !ignoreError) {\r
throw ex;\r
}\r
}\r
- \r
+\r
if (wallpaper == null) {\r
return;\r
}\r
- \r
+\r
// 壁紙を更新する.\r
previewPane.setWallpaper(wallpaper);\r
- \r
+\r
// 壁紙情報として記憶する.\r
this.wallpaperInfo = wallpaperInfo;\r
}\r
- \r
+\r
/**\r
* プリビューしている画像をファイルに保存する。 サポートしているのはPNG/JPEGのみ。\r
*/\r
tk.beep();\r
return;\r
}\r
- \r
+\r
try {\r
// 出力オプションの調整\r
OutputOption outputOption = imageSaveHelper.getOutputOption();\r
}\r
try {\r
DesktopUtilities.browseBaseDir(characterData.getDocBase());\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
if (newCd != null) {\r
MainFrame.notifyChangeCharacterData(cd, newCd, this);\r
}\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* パーツの管理ダイアログを開く.<br>\r
*/\r
tk.beep();\r
return;\r
}\r
- \r
+\r
PartsManageDialog mrgDlg = new PartsManageDialog(this, characterData);\r
mrgDlg.setVisible(true);\r
- \r
+\r
if (mrgDlg.isUpdated()) {\r
// パーツ管理情報が更新された場合、\r
// パーツデータをリロードする.\r
tk.beep();\r
return;\r
}\r
- \r
+\r
if (lastUseSearchPartsDialog != null) {\r
// 開いているダイアログがあれば、それにフォーカスを当てる.\r
if (lastUseSearchPartsDialog.isDisplayable() && lastUseSearchPartsDialog.isVisible()) {\r
return;\r
}\r
}\r
- \r
+\r
SearchPartsDialog searchPartsDlg = new SearchPartsDialog(this, characterData, partsSelectionManager);\r
searchPartsDlg.adjustLocation(0);\r
searchPartsDlg.setVisible(true);\r
}\r
}\r
}\r
- \r
+\r
/**\r
* クリップボードにコピー\r
- * \r
+ *\r
* @param screenImage\r
* スクリーンイメージ\r
*/\r
tk.beep();\r
return;\r
}\r
- \r
+\r
if (screenImage) {\r
// 表示している内容をそのままコピーする.\r
img = previewPane.getScreenImage();\r
}\r
- \r
+\r
Color imgBgColor = wallpaperInfo.getBackgroundColor();\r
ClipboardUtil.setImage(img, imgBgColor);\r
\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* アプリケーションの設定ダイアログを開く\r
*/\r
* 現在のプロファイルに対するインポートウィザードを実行する.<br>\r
* インポートが実行された場合は、パーツをリロードする.<br>\r
* インポートウィザード表示中は監視スレッドは停止される.<br>\r
- * \r
+ *\r
* @param initFile\r
* アーカイブファィルまたはディレクトリ、指定がなければnull\r
*/\r
} finally {\r
watchAgent.resume();\r
}\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
* まだロードされていない場合はあらたにロードする.<br>\r
* 引数newCdが指定されている場合は、現在のキャラクター定義の説明文を更新する.<br>\r
* (説明文の更新以外には使用されない.)<br>\r
- * \r
+ *\r
* @param newCd\r
* 説明文更新のための更新されたキャラクターデータを指定する。null可\r
* @param forceRepaint\r
// (インポート画面では説明文のみ更新するので、それだけ取得)\r
characterData.setDescription(newCd.getDescription());\r
}\r
- \r
+\r
if ( !characterData.isPartsLoaded()) {\r
// キャラクターデータが、まだ読み込まれていなければ読み込む.\r
ProfileListManager.loadCharacterData(characterData);\r
requestPreview();\r
}\r
}\r
- \r
+\r
protected void onExport() {\r
if (!characterData.isValid()) {\r
Toolkit tk = Toolkit.getDefaultToolkit();\r
tk.beep();\r
return;\r
}\r
- \r
+\r
Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()\r
.getLocalizedProperties(STRINGS_RESOURCE);\r
- \r
+\r
if (JOptionPane.showConfirmDialog(this, strings.get("confirm.resetcolors"), strings.getProperty("confirm"),\r
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) != JOptionPane.YES_OPTION) {\r
return;\r
partsColorCoordinator.initColorDialog();\r
requestPreview();\r
}\r
- \r
+\r
/**\r
* プロファイルを閉じる.\r
*/\r
protected void onCloseProfile() {\r
saveWorkingSet();\r
ProfileListManager.unregisterUsedCharacterData(characterData);\r
- \r
+\r
if (characterData.isValid()) {\r
\r
// 最後に使用したキャラクターデータとして記憶する.\r
\r
// フレームウィンドウを破棄する.\r
dispose();\r
- \r
+\r
// 破棄されたことをロギングする.\r
logger.log(Level.FINE, "dispose mainframe.");\r
}\r
- \r
+\r
/**\r
* 開いている、すべてのプロファイルを閉じる.<br>\r
* (Mac OS Xのcmd+Qで閉じる場合などで使用される.)<br>\r
\r
// gcをかけてファイナライズを促進させる\r
SystemUtil.gc();\r
- \r
+\r
// ファイナライズされていないFrameのうち、ネイティブリソースと関連づけられている\r
// フレームについて、それがMainFrameのインスタンスであれば閉じる.\r
// ただし、現在アクティブなものは除く\r
((MainFrame) frame).onCloseProfile();\r
}\r
}\r
- \r
+\r
} catch (Throwable ex) {\r
logger.log(Level.SEVERE, "mainframe closing failed.", ex);\r
// フレームを閉じるときに失敗した場合、通常、致命的問題だが\r
// クローズ処理は継続しなければならない.\r
}\r
}\r
- \r
+\r
// 現在アクティブなフレームを閉じる.\r
// 最後に閉じることで「最後に使ったプロファイル」として記憶させる.\r
if (activedMainFrame != null && activedMainFrame.isDisplayable()) {\r
}\r
}\r
}\r
- \r
+\r
/**\r
* 画面の作業状態を保存するユーザーデータを取得する.\r
- * \r
+ *\r
* @param modeRead\r
* 読み込みモード\r
* @return ユーザーデータ\r
protected UserData getWorkingSetUserData(boolean modeRead) {\r
return getWorkingSetUserData(characterData, modeRead);\r
}\r
- \r
+\r
/**\r
* 画面の作業状態を保存するユーザーデータを取得する.<br>\r
* キャラクターデータがnullまたは有効でない場合はnullを返す.<br>\r
- * \r
+ *\r
* @param cd\r
* キャラクターデータ\r
* @param modeRead\r
UserDataFactory userDataFactory = UserDataFactory.getInstance();\r
return userDataFactory.getMangledNamedUserData(cd.getDocBase(), "workingset.ser");\r
}\r
- \r
+\r
/**\r
* 画面の作業状態を保存する.\r
*/\r
\r
UserData workingSetStore = getWorkingSetUserData(false);\r
workingSetStore.save(workingSet);\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* 画面の作業状態を復元する.\r
- * \r
+ *\r
* @return\r
*/\r
protected boolean loadWorkingSet() {\r
logger.info("workingset cd-structure mismatch: actual=" + characterData + "/workingSet=" + workingSet);\r
return false;\r
}\r
- \r
+\r
// 現在のパーツ色情報にワーキングセットで保存した内容を設定する.\r
Map<PartsIdentifier, PartsColorInfo> partsColorInfoMap = characterData.getPartsColorManager().getPartsColorInfoMap();\r
Map<PartsIdentifier, PartsColorInfo> workingPartsColorInfoMap = workingSet.getPartsColorInfoMap();\r
partsColorInfoMap.put(partsIdentifier, partsColorInfo);\r
}\r
}\r
- \r
+\r
// 選択されているパーツの復元\r
PartsSet partsSet = workingSet.getPartsSet();\r
if (partsSet != null) {\r
// 最後に保存したディレクトリを復元する.\r
imageSaveHelper.setLastUseSaveDir(workingSet.getLastUsedSaveDir());\r
ExportWizardDialog.setLastUsedDir(workingSet.getLastUsedExportDir());\r
- \r
+\r
// 壁紙情報を取得する.\r
WallpaperInfo wallpaperInfo = workingSet.getWallpaperInfo();\r
if (wallpaperInfo != null) {\r
// (適用に失敗した場合はエラーは無視し、壁紙情報は保存しない.)\r
applyWallpaperInfo(wallpaperInfo, true);\r
}\r
- \r
+\r
return true;\r
}\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
try {\r
AboutBox aboutBox = new AboutBox(this);\r
aboutBox.showAboutBox();\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
String helpDescription = strings.getProperty("help.show");\r
DesktopUtilities.browse(this, helpURL, helpDescription);\r
}\r
- \r
+\r
protected void onFlipHolizontal() {\r
if (!characterData.isValid()) {\r
Toolkit tk = Toolkit.getDefaultToolkit();\r
partsSelectionManager.setAffineTransformParameter(affineTransformParameter);\r
requestPreview();\r
}\r
- \r
+\r
protected void onSetDefaultPicture() {\r
if (!characterData.isValid()) {\r
Toolkit tk = Toolkit.getDefaultToolkit();\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
protected void onInformation() {\r
if (!characterData.isValid()) {\r
Toolkit tk = Toolkit.getDefaultToolkit();\r
InformationDialog infoDlg = new InformationDialog(this, characterData, partsSet);\r
infoDlg.setVisible(true);\r
}\r
- \r
+\r
protected void onManageFavorites() {\r
if (!characterData.isValid()) {\r
Toolkit tk = Toolkit.getDefaultToolkit();\r
try {\r
CharacterDataPersistent persiste = CharacterDataPersistent.getInstance();\r
persiste.saveFavorites(characterData);\r
- \r
+\r
notifyChangeFavorites(characterData);\r
\r
} finally {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* 最新のお気に入りの状態を取り出す.<br>\r
*/\r
logger.log(Level.WARNING, "can't refresh favorites: " + characterData, ex);\r
}\r
}\r
- \r
+\r
protected void onRegisterFavorite() {\r
if (!characterData.isValid()) {\r
Toolkit tk = Toolkit.getDefaultToolkit();\r
\r
Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()\r
.getLocalizedProperties(STRINGS_RESOURCE);\r
- \r
+\r
// お気に入りに登録するパーツセットが最後に使用したお気に入りと同じ構成であれば、\r
// そのお気に入り名を使用する.\r
String initName = getSuggestPartsSetName(partsSet, false);\r
- \r
+\r
// カラー情報の有無のチェックボックス.\r
JCheckBox chkColorInfo = new JCheckBox(strings.getProperty("input.favoritesColorInfo"));\r
chkColorInfo.setSelected(true);\r
JCheckBox chkOverwrite = new JCheckBox(strings.getProperty("input.favoritesOverwrite"));\r
chkOverwrite.setSelected(partsSetId != null && partsSetId.length() > 0);\r
chkOverwrite.setEnabled(partsSetId != null && partsSetId.length() > 0);\r
- \r
+\r
// チェックボックスパネル\r
Box checkboxsPanel = new Box(BoxLayout.PAGE_AXIS);\r
checkboxsPanel.add(chkColorInfo);\r
checkboxsPanel.add(chkOverwrite);\r
- \r
+\r
// 入力ダイアログを開く\r
String name = (String) JOptionPane.showInputDialog(this,\r
checkboxsPanel,\r
// カラー情報を除去する.\r
partsSet.removeColorInfo();\r
}\r
- \r
+\r
// 新規の場合、もしくは上書きしない場合はIDを設定する.\r
if (partsSetId == null || !chkOverwrite.isSelected()) {\r
partsSetId = "ps" + UUID.randomUUID().toString();\r
// 現在の最新情報を取り出す.\r
characterData.clearPartsSets(true);\r
persiste.loadFavorites(characterData);\r
- \r
+\r
// お気に入りコレクションに登録\r
characterData.addPartsSet(partsSet);\r
\r
persiste.saveFavorites(characterData);\r
\r
notifyChangeFavorites(characterData);\r
- \r
+\r
} finally {\r
setCursor(Cursor.getDefaultCursor());\r
}\r
- \r
+\r
// 最後に選択したお気に入りにする\r
lastUsePresetParts = partsSet;\r
showPresetName(partsSet);\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* すべての解除可能なパーツの選択を解除する。\r
*/\r
protected void onDeselectAll() {\r
partsSelectionManager.deselectAll();\r
}\r
- \r
+\r
/**\r
* 単一選択カテゴリのパーツの解除を許可する。\r
*/\r
\r
/**\r
* メニューバーを構築します.\r
- * \r
+ *\r
* @return メニューバー\r
*/\r
protected JMenuBar createMenuBar() {\r
final Properties strings = LocalizedResourcePropertyLoader\r
.getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);\r
- \r
+\r
MenuDataFactory[] menus = new MenuDataFactory[] {\r
new MenuDataFactory("menu.file", new MenuDataFactory[] {\r
new MenuDataFactory("file.openProfile", new ActionListener() {\r
onChangeWallpaper();\r
}\r
}),\r
- \r
+\r
}),\r
new MenuDataFactory("menu.favorite", new MenuDataFactory[] {\r
new MenuDataFactory("favorite.register", new ActionListener() {\r
final MenuBuilder menuBuilder = new MenuBuilder();\r
\r
JMenuBar menuBar = menuBuilder.createMenuBar(menus);\r
- \r
+\r
menuBuilder.getJMenu("menu.edit").addMenuListener(new MenuListener() {\r
public void menuCanceled(MenuEvent e) {\r
// do nothing.\r
onSelectedFavoriteMenu(mnuFavorites);\r
}\r
});\r
- \r
+\r
// J2SE5の場合は「パーツディレクトリを開く」コマンドは使用不可とする.\r
if (System.getProperty("java.version").startsWith("1.5")) {\r
menuBuilder.getJMenuItem("file.opendir").setEnabled(false);\r
}\r
- \r
+\r
// お勧めサイトメニュー構築\r
final JMenu mnuRecomendation = menuBuilder.getJMenu("help.recommendations");\r
JMenu mnuHelp = menuBuilder.getJMenu("menu.help");\r
\r
return menuBar;\r
}\r
- \r
+\r
}\r
\r
/**\r
* プロファイルを選択するためのダイアログ、およびデフォルトプロファイルを開く\r
- * \r
+ *\r
* @author seraphy\r
*/\r
public class ProfileSelectorDialog extends JDialog {\r
\r
private static final long serialVersionUID = -6883202891172975022L;\r
- \r
+\r
private static final Logger logger = Logger.getLogger(ProfileSelectorDialog.class.getName());\r
\r
\r
protected static final String STRINGS_RESOURCE = "languages/profileselectordialog";\r
- \r
+\r
/**\r
* サンプルイメージをロードするためのローダー\r
*/\r
private ImageCachedLoader imageLoader = new ImageCachedLoader();\r
\r
- \r
+\r
/**\r
* サンプルイメージファイルが保存可能であるか?<br>\r
* 有効なキャラクターデータが選択されており、サンプルイメージの更新が許可されていればtrue.<br>\r
*/\r
private boolean canWriteSamplePicture;\r
- \r
+\r
/**\r
* サンプルイメージを表示するパネル\r
*/\r
private SamplePicturePanel sampleImgPanel;\r
\r
private Action actOK;\r
- \r
+\r
private Action actCancel;\r
- \r
+\r
private Action actProfileNew;\r
\r
private Action actProfileCopy;\r
* プロファイル一覧を表示するリストコンポーネント\r
*/\r
private JTable characterList;\r
- \r
+\r
/**\r
* プロファイル一覧のリストモデル\r
*/\r
private ProfileSelectorTableModel characterListModel;\r
- \r
+\r
/**\r
* プロファイルの説明用テキストエリア\r
*/\r
private JTextArea descriptionArea;\r
- \r
- \r
+\r
+\r
\r
/**\r
* ダイアログをOKで閉じた場合に選択していたキャラクターデータを示す.<br>\r
*/\r
private CharacterData selectedCharacterData;\r
\r
- \r
+\r
/**\r
* プロファイルの選択ダイアログを構築する.\r
- * \r
+ *\r
* @param parent\r
* 親フレーム、もしくはnull\r
* @param characterDatas\r
onClosing();\r
}\r
});\r
- \r
+\r
final Properties strings = LocalizedResourcePropertyLoader\r
.getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);\r
\r
setTitle(strings.getProperty("title"));\r
\r
JPanel pnlProfiles = new JPanel(new BorderLayout());\r
- \r
+\r
characterListModel = new ProfileSelectorTableModel();\r
characterListModel.setModel(characterDatas);\r
- \r
+\r
characterList = new JTable(characterListModel) {\r
private static final long serialVersionUID = 1L;\r
\r
}\r
}\r
});\r
- \r
+\r
JScrollPane characterListSP = new JScrollPane(characterList);\r
characterListSP.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);\r
characterListSP\r
.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);\r
pnlProfiles.add(characterListSP, BorderLayout.CENTER);\r
- \r
+\r
actOK = new AbstractAction(strings.getProperty("btn.select")) {\r
private static final long serialVersionUID = 1L;\r
public void actionPerformed(ActionEvent e) {\r
JButton btnProfileImport = new JButton(actProfileImport);\r
JButton btnProfileExport = new JButton(actProfileExport);\r
JButton btnProfileTemplate = new JButton(actProfileTemplate);\r
- \r
+\r
JPanel pnlProfileEditButtons = new JPanel();\r
pnlProfileEditButtons.setLayout(new GridBagLayout());\r
GridBagConstraints gbc = new GridBagConstraints();\r
- \r
+\r
gbc.gridx = 0;\r
gbc.gridy = 0;\r
gbc.gridwidth = 1;\r
gbc.gridy = 5;\r
gbc.weighty = 0.;\r
pnlProfileEditButtons.add(btnProfileBrowse, gbc);\r
- \r
+\r
gbc.gridx = 0;\r
gbc.gridy = 6;\r
gbc.weighty = 0.;\r
descriptionPanel.setBorder(BorderFactory.createCompoundBorder(\r
BorderFactory.createEmptyBorder(3, 3, 3, 3), BorderFactory\r
.createTitledBorder(strings.getProperty("description"))));\r
- \r
+\r
descriptionArea = new JTextArea();\r
descriptionArea.setEditable(false);\r
descriptionPanel.add(new JScrollPane(descriptionArea), BorderLayout.CENTER);\r
\r
// サンプルピクャパネル\r
sampleImgPanel = new SamplePicturePanel();\r
- \r
+\r
// サンプルピクチャファイルのドラッグアンドドロップ\r
new DropTarget(sampleImgPanel, new FileDropTarget() {\r
@Override\r
ErrorMessageHelper.showErrorDialog(ProfileSelectorDialog.this, ex);\r
}\r
});\r
- \r
+\r
// サンプルピクチャのコンテキストメニュー\r
final JPopupMenu popupMenu = new JPopupMenu();\r
final JMenuItem popupMenuCut = popupMenu.add(new AbstractAction(strings.getProperty("samplepicture.cut")) {\r
sampleImgTitledPanel.setBorder(BorderFactory.createCompoundBorder(\r
BorderFactory.createEmptyBorder(3, 3, 3, 3), BorderFactory\r
.createTitledBorder(strings.getProperty("sample-image"))));\r
- \r
+\r
infoPanel.add(descriptionPanel);\r
infoPanel.add(sampleImgTitledPanel);\r
- \r
+\r
JSplitPane centerPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);\r
centerPane.setResizeWeight(1.f); // ウィンドウサイズ変更時に上を可変とする.\r
centerPane.setDividerLocation(Integer.parseInt(strings\r
\r
centerPane.add(pnlProfilesGroup);\r
centerPane.add(infoPanel);\r
- \r
+\r
Container contentPane = getContentPane();\r
contentPane.setLayout(new BorderLayout());\r
contentPane.add(centerPane, BorderLayout.CENTER);\r
- \r
+\r
// OK/CANCEL ボタンパネル\r
\r
JPanel btnPanel = new JPanel();\r
BoxLayout boxLayout = new BoxLayout(btnPanel, BoxLayout.LINE_AXIS);\r
btnPanel.setLayout(boxLayout);\r
btnPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 42));\r
- \r
+\r
JButton btnOK = new JButton(actOK);\r
JButton btnCancel = new JButton(actCancel);\r
if (Main.isLinuxOrMacOSX()) {\r
btnPanel.add(btnOK);\r
btnPanel.add(btnCancel);\r
}\r
- \r
+\r
JPanel btnPanel2 = new JPanel(new BorderLayout());\r
btnPanel2.add(btnPanel, BorderLayout.EAST);\r
- \r
+\r
contentPane.add(btnPanel2, BorderLayout.SOUTH);\r
- \r
+\r
Toolkit tk = Toolkit.getDefaultToolkit();\r
JRootPane rootPane = getRootPane();\r
rootPane.setDefaultButton(btnOK);\r
- \r
+\r
InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);\r
ActionMap am = rootPane.getActionMap();\r
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "closeProfileSelectorDialog");\r
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, tk.getMenuShortcutKeyMask()), "closeProfileSelectorDialog");\r
am.put("closeProfileSelectorDialog", actCancel);\r
- \r
+\r
int width = Integer.parseInt(strings.getProperty("windowWidth"));\r
int height = Integer.parseInt(strings.getProperty("windowHeight"));\r
setSize(width, height);\r
characterList.requestFocus();\r
updateUIState();\r
}\r
- \r
+\r
public CharacterData getSelectedCharacterData() {\r
return selectedCharacterData;\r
}\r
- \r
+\r
/**\r
* キャラクターデータの選択変更に伴い、ボタンやサンプルピクチャなどを切り替える.\r
*/\r
if (selRow >= 0) {\r
characterData = characterListModel.getRow(selRow);\r
}\r
- \r
+\r
final Properties strings = LocalizedResourcePropertyLoader\r
.getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);\r
\r
&& characterData.canWrite();\r
\r
actOK.setEnabled(selected);\r
- \r
+\r
actProfileNew.setEnabled(true);\r
actProfileCopy.setEnabled(selected);\r
actProfileEdit.setEnabled(selected);\r
actProfileExport.setEnabled(selected);\r
actProfileBrowse.setEnabled(selected);\r
actProfileTemplate.setEnabled(selected);\r
- \r
+\r
if (enableEdit) {\r
actProfileEdit.putValue(Action.NAME,\r
strings.getProperty("profile.edit"));\r
actProfileEdit.putValue(Action.NAME,\r
strings.getProperty("profile.edit.readonly"));\r
}\r
- \r
+\r
// 有効なキャラクターデータであり、且つ、書き込み可能であり、且つ、使用中でなければ削除可能\r
boolean removable = characterData != null && characterData.isValid()\r
&& !ProfileListManager.isUsingCharacterData(characterData)\r
descriptionArea.setText(sw.toString());\r
descriptionArea.setSelectionStart(0);\r
descriptionArea.setSelectionEnd(0);\r
- \r
+\r
// sample picture\r
try {\r
CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
sampleImage = null;\r
}\r
}\r
- \r
+\r
this.canWriteSamplePicture = canWriteSamplePicture;\r
\r
String dropHere = strings.getProperty("dropHere");\r
sampleImgPanel.setSamplePicture(sampleImage);\r
sampleImgPanel.setAlternateText(canWriteSamplePicture ? dropHere : noPicture);\r
}\r
- \r
+\r
\r
/**\r
* サンプルピクチャのファイルを削除し、表示されている画像をクリップボードに保存する\r
// クリップボードにイメージをセット\r
Color bgColor = AppConfig.getInstance().getSampleImageBgColor();\r
ClipboardUtil.setImage(img, bgColor);\r
- \r
+\r
// サンプルピクチャを削除\r
CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
persist.saveSamplePicture(characterData, null);\r
- \r
+\r
// プレビューを更新\r
sampleImgPanel.setSamplePicture(null);\r
\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* サンプルピクチャをクリップボードから貼り付け、それをファイルに保存する\r
*/\r
// 画像が読み込まれた場合、それを保存する.\r
CharacterDataPersistent persist = CharacterDataPersistent.getInstance();\r
persist.saveSamplePicture(characterData, img);\r
- \r
+\r
sampleImgPanel.setSamplePicture(img);\r
- \r
+\r
} else {\r
// サンプルピクチャは更新されなかった。\r
tk.beep();\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* サンプルピクチャパネルにドロップされた画像ファイルをサンプルピクチャとしてコピーします.<br>\r
- * \r
+ *\r
* @param dtde\r
* ドロップイベント\r
*/\r
BufferedImage img = null;\r
if (dropFile != null && dropFile.isFile() && dropFile.canRead()) {\r
try {\r
- LoadedImage loadedImage = imageLoader.load(new FileImageResource(dropFile)); \r
+ LoadedImage loadedImage = imageLoader.load(new FileImageResource(dropFile));\r
img = loadedImage.getImage();\r
- \r
+\r
} catch (IOException ex) {\r
// イメージのロードができない = 形式が不正であるなどの場合は\r
// 読み込みせず、継続する.\r
// サンプルピクチャは更新されなかった。\r
tk.beep();\r
}\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
+ @Override\r
+ public void dispose() {\r
+ imageLoader.close();\r
+ super.dispose();\r
+ }\r
+\r
/**\r
* 閉じる場合\r
*/\r
protected void onClosing() {\r
dispose();\r
}\r
- \r
+\r
/**\r
* OKボタン押下\r
*/\r
}\r
dispose();\r
}\r
- \r
+\r
/**\r
* キャンセルボタン押下\r
*/\r
selectedCharacterData = null;\r
onClosing();\r
}\r
- \r
+\r
/**\r
* プロファイルの作成\r
- * \r
+ *\r
* @param makeDefault\r
* デフォルトのプロファイルで作成する場合\r
*/\r
return;\r
}\r
}\r
- \r
+\r
// 基本情報をコピーします。\r
CharacterData newCd = cd.duplicateBasicInfo();\r
// DocBaseはnullにする。これにより新規作成と判断される.\r
\r
ProfileEditDialog editDlg = new ProfileEditDialog(this, newCd);\r
editDlg.setVisible(true);\r
- \r
+\r
newCd = editDlg.getResult();\r
if (newCd == null) {\r
// キャンセルされた場合\r
return;\r
}\r
- \r
+\r
// 新規プロファイルを保存する.\r
try {\r
persist.createProfile(newCd);\r
tk.beep();\r
return;\r
}\r
- \r
+\r
final Properties strings = LocalizedResourcePropertyLoader\r
.getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);\r
\r
String msgTempl = strings.getProperty("profile.remove.confirm");\r
MessageFormat fmt = new MessageFormat(msgTempl);\r
String msg = fmt.format(new Object[]{cd.getName()});\r
- \r
+\r
JPanel msgPanel = new JPanel(new BorderLayout(5, 5));\r
msgPanel.add(new JLabel(msg), BorderLayout.CENTER);\r
JCheckBox chkRemoveForce = new JCheckBox(strings.getProperty("profile.remove.force"));\r
if (ret == null || ((Number) ret).intValue() != JOptionPane.YES_OPTION) {\r
return;\r
}\r
- \r
+\r
if (!cd.canWrite() || cd.getDocBase() == null) {\r
JOptionPane.showMessageDialog(this, strings.getProperty("profile.remove.cannot"));\r
return;\r
}\r
- \r
+\r
boolean forceRemove = chkRemoveForce.isSelected();\r
- \r
+\r
try {\r
CharacterDataPersistent persiste = CharacterDataPersistent.getInstance();\r
persiste.remove(cd, forceRemove);\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
return;\r
}\r
- \r
+\r
// モデルから該当キャラクターを削除して再描画\r
characterListModel.remove(selRow);\r
characterList.repaint();\r
updateUIState();\r
}\r
- \r
+\r
/**\r
* 場所を開く\r
*/\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
}\r
- \r
+\r
/**\r
* インポート\r
*/\r
btnUpdate.setSelected(true);\r
radioPanel.add(btnUpdate, BorderLayout.NORTH);\r
radioPanel.add(btnNew, BorderLayout.SOUTH);\r
- \r
+\r
int ret = JOptionPane.showConfirmDialog(this, radioPanel,\r
strings.getProperty("confirmUpdateProfile"),\r
JOptionPane.OK_CANCEL_OPTION);\r
if (ret != JOptionPane.OK_OPTION) {\r
return;\r
}\r
- \r
+\r
if (btnNew.isSelected()) {\r
// 選択されていないことにする.\r
selCd = null;\r
}\r
}\r
- \r
+\r
// キャラクターデータをロードし直す.\r
CharacterData cd;\r
if (selCd != null) {\r
try {\r
ProfileListManager.loadCharacterData(cd);\r
ProfileListManager.loadFavorites(cd);\r
- \r
+\r
} catch (IOException ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
// 継続する.\r
} else {\r
cd = null;\r
}\r
- \r
+\r
// ディレクトリ監視エージェントの停止\r
PartsImageDirectoryWatchAgentFactory agentFactory = PartsImageDirectoryWatchAgentFactory.getFactory();\r
PartsImageDirectoryWatchAgent agent = agentFactory.getAgent(cd);\r
// インポートウィザードの実行\r
ImportWizardDialog importWizDialog = new ImportWizardDialog(this, cd);\r
importWizDialog.setVisible(true);\r
- \r
+\r
CharacterData newCd = importWizDialog.getImportedCharacterData();\r
if (importWizDialog.getExitCode() == ImportWizardDialog.EXIT_PROFILE_CREATED) {\r
- \r
+\r
// 作成されたプロファイルを一覧に追加する.\r
characterListModel.add(newCd);\r
- \r
+\r
} else if (importWizDialog.getExitCode() == ImportWizardDialog.EXIT_PROFILE_UPDATED) {\r
- \r
+\r
// 更新されたプロファイルを通知する\r
MainFrame.notifyImportedPartsOrFavorites(cd, newCd, this);\r
}\r
} finally {\r
agent.resume();\r
}\r
- \r
+\r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
tk.beep();\r
return;\r
}\r
- \r
+\r
try {\r
// コピーした情報に対してパーツデータをロードする.\r
final CharacterData newCd = cd.duplicateBasicInfo();\r