import java.awt.Graphics;\r
import java.awt.image.BufferedImage;\r
import java.io.IOException;\r
+import java.io.InputStream;\r
import java.sql.Timestamp;\r
import java.util.logging.Level;\r
import java.util.logging.Logger;\r
throw new IllegalArgumentException();\r
}\r
\r
- BufferedImage img = ImageIO.read(imageResource.openStream());\r
+ BufferedImage img;\r
+ InputStream is = imageResource.openStream();\r
+ try {\r
+ img = ImageIO.read(is);\r
+\r
+ } finally {\r
+ is.close();\r
+ }\r
if (img == null) {\r
logger.log(Level.WARNING, "unsuppoted image: " + imageResource);\r
throw new IOException("unsupported image");\r
* 正規化された結果カテゴリが一つもなくなった場合は何も登録されず、falseを返します.<br>\r
* 登録された場合はtrueを返します.<br>\r
* @param partsSet\r
- * @return\r
+ * @return 登録された場合はtrue、登録できない場合はfalse\r
*/\r
public boolean addPartsSet(PartsSet partsSet) {\r
if (partsSet == null) {\r
}\r
\r
/**\r
- * お気に入り(Favorites)を読み込む.\r
+ * お気に入り(Favorites)を読み込む.<br>\r
+ * 現在のパーツセットに追加する形で読み込まれ、同じパーツセットIDのものは上書きされます.<br>\r
* \r
* @param characterData キャラクターデータ\r
* @throws IOException 読み込みに失敗した場合\r
\r
/**\r
* ディレクトリ監視エージェントのファクトリ.<br>\r
- * 同一のキャラクターデータを監視する場合、エージェントの実体は一つとなります.<br> \r
+ * このファクトリ単位でディレクト利監視エージェントは保持されます.<br>\r
+ * このファクトリ上に、すでに同一のキャラクターデータを監視するエージェントがいる場合、それらのエージェントの実体は\r
+ * ハンドルによって共有されます.<br> \r
* @author seraphy\r
*/\r
public final class PartsImageDirectoryWatchAgentFactory {\r
return inst;\r
}\r
\r
+ /**\r
+ * キャラクターデータを指定して、そのキャラクターデータに対する監視エージェントを作成し、そのハンドルを返します.<br>\r
+ * すでに、そのキャラクターデータに対するエージェントが存在する場合は、そのハンドルを返します.<br>\r
+ * 無効なキャラクターデータ、もしくはnullを指定した場合は、エージェントの実体を持たないダミーのハンドルが返されます.<br>\r
+ * @param characterData キャラクターデータ\r
+ * @return 作成された、もしくは既に作成されている監視エージェントのハンドル\r
+ */\r
public PartsImageDirectoryWatchAgent getAgent(CharacterData characterData) {\r
- if (characterData == null) {\r
- throw new IllegalArgumentException();\r
+ if (characterData == null || !characterData.isValid()) {\r
+ // キャラクターデータがnullまたは無効である場合は、\r
+ // 何もしないダミーのディレクトリハンドルを返す.\r
+ return new NullWatchAgentHandle(characterData);\r
}\r
+\r
URI docBase = characterData.getDocBase();\r
PartsImageDirectoryWatchAgentThread agentImpl;\r
synchronized (lock) {\r
}\r
\r
/**\r
- * 監視ディレクトりに対する監視スレッドの実体を複数のメインフレームで共有するための、個々のフレーム用のハンドル.<br>\r
+ * 監視スレッドの実体がない、何もしないハンドル.\r
+ * @author seraphy\r
+ */\r
+class NullWatchAgentHandle implements PartsImageDirectoryWatchAgent, PartsImageDirectoryWatchListener {\r
+\r
+ private CharacterData characterData;\r
+ \r
+ public NullWatchAgentHandle(CharacterData characterData) {\r
+ this.characterData = characterData;\r
+ }\r
+ \r
+ public void addPartsImageDirectoryWatchListener(\r
+ PartsImageDirectoryWatchListener l) {\r
+ }\r
+ // なにもしない.\r
+ \r
+ public void connect() {\r
+ // なにもしない.\r
+ }\r
+ \r
+ public void detectPartsImageChange(PartsImageDirectoryWatchEvent e) {\r
+ // なにもしない.\r
+ }\r
+ \r
+ public void disconnect() {\r
+ // なにもしない.\r
+ }\r
+ \r
+ public CharacterData getCharcterData() {\r
+ return characterData;\r
+ }\r
+ \r
+ public void removePartsImageDirectoryWatchListener(\r
+ PartsImageDirectoryWatchListener l) {\r
+ // なにもしない.\r
+ }\r
+ \r
+ public void resume() {\r
+ // なにもしない.\r
+ }\r
+ \r
+ public void suspend() {\r
+ // なにもしない.\r
+ }\r
+}\r
+\r
+/**\r
+ * 監視ディレクトリに対する監視スレッドの実体を複数のメインフレームで共有するための、個々のフレーム用のハンドル.<br>\r
* @author seraphy\r
*/\r
class PartsImageDirectoryWatchAgentHandle implements PartsImageDirectoryWatchAgent, PartsImageDirectoryWatchListener {\r
\r
import java.io.File;\r
import java.io.IOException;\r
+import java.net.URI;\r
import java.util.HashMap;\r
import java.util.Map;\r
import java.util.logging.Level;\r
\r
RecentData recentData;\r
try {\r
+ File currentCharactersDir = DirectoryConfig.getInstance().getCharactersDir();\r
+\r
Object rawRecentData = recentCharacterStore.load();\r
if (rawRecentData instanceof RecentData) {\r
// 旧形式 (単一)\r
recentData = (RecentData) rawRecentData;\r
logger.log(Level.INFO, "old-recentdata-type: " + recentData);\r
+ \r
+ // 旧形式で保存されているURIが、現在選択しているキャラクターデータと同じ親ディレクトリ\r
+ // でなければ復元しない.\r
+ URI uri = recentData.getDocBase();\r
+ File parentDir = new File(uri).getParentFile().getParentFile(); // 2段上\r
+ if (!currentCharactersDir.equals(parentDir)) {\r
+ logger.log(Level.INFO,\r
+ "unmatched characters-dir. current="\r
+ + currentCharactersDir + "/recent="\r
+ + parentDir);\r
+ recentData = null;\r
+ }\r
\r
} else if (rawRecentData instanceof Map) {\r
// 新形式 (複数のキャラクターディレクトリに対応)\r
@SuppressWarnings("unchecked")\r
Map<File, RecentData> recentDataMap = (Map<File, RecentData>) rawRecentData;\r
- File currentCharactersDir = DirectoryConfig.getInstance().getCharactersDir();\r
recentData = recentDataMap.get(currentCharactersDir);\r
logger.log(Level.INFO, "recent-data: " + currentCharactersDir + "=" + recentData);\r
\r
}\r
if ((colorType & 0x02) != 0) {\r
buf.append("Color ");\r
+\r
} else {\r
buf.append("Greyscale ");\r
}\r
- if ((colorType & 0x03) != 0 || pngHeader.hasTransparencyInformation()) {\r
+\r
+ if (colorType == 6 || pngHeader.hasTransparencyInformation()) {\r
+ // 6:TrueColor または アルファ情報がある場合のみアルファ有りとする.\r
buf.append("Alpha ");\r
}\r
- \r
+\r
buf.append(pngHeader.getBitDepth() + "bit");\r
\r
return buf.toString().trim();\r
final Properties strings = LocalizedResourcePropertyLoader\r
.getInstance().getLocalizedProperties(STRINGS_RESOURCE);\r
if (JOptionPane.showConfirmDialog(this, strings.get("confirm.close"), strings.getProperty("confirm"),\r
- JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {\r
+ JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) {\r
+ // YESでなければ継続しない.\r
+ return;\r
}\r
}\r
dispose();\r
throw new IOException("開くことのできないキャラクターデータです。:" + characterData);\r
}\r
\r
- CharacterData original = characterData.duplicateBasicInfo(false);\r
+ // キャラクターデータのコピーを作成する.(プリセットも含む)\r
+ CharacterData original = characterData.duplicateBasicInfo(true);\r
+ original.clearPartsSets(true); // プリセット以外のパーツセットはクリアする.\r
\r
try {\r
loadFavorites(original);\r