diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 0d327bf95..9ec42418b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -617,6 +617,12 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { */ @Internal public String debuggerPackage = null; + + /** + * Lock for getting dependent + */ + @Internal + private final Object dependentLock = new Object(); /** * Imported characterId to SWF map. @@ -1156,14 +1162,11 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { * @return Map of characterId to set of dependent characterIds */ public Map> getDependentCharacters() { - if (dependentCharacters == null) { - synchronized (this) { - if (dependentCharacters == null) { - computeDependentCharacters(); - } - } + synchronized (dependentLock) { + if (dependentCharacters == null) { + computeDependentCharacters(); + } } - return dependentCharacters; } @@ -1244,6 +1247,22 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { dependentClassFrames = depCls; } + /** + * Check if dependent characters are loaded + * @return True if loaded + */ + public boolean isDependentCharactersLoaded() { + return dependentCharacters != null; + } + + /** + * Check if dependent frames are loaded + * @return True if loaded + */ + public boolean isDependentFramesLoaded() { + return dependentFrames != null && dependentClassFrames != null; + } + /** * Gets dependent frames for specified character. * @@ -1251,11 +1270,9 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { * @return Set of dependent characterids */ public Set getDependentFrames(int characterId) { - if (dependentFrames == null) { - synchronized (this) { - if (dependentFrames == null) { - computeDependentFrames(); - } + synchronized (dependentLock) { + if (dependentFrames == null) { + computeDependentFrames(); } } @@ -1270,7 +1287,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { */ public Set getDependentFramesByClass(String characterClass) { if (dependentClassFrames == null) { - synchronized (this) { + synchronized (dependentLock) { if (dependentClassFrames == null) { computeDependentFrames(); } diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index fa77e95e6..9640d4f69 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -263,6 +263,8 @@ import java.util.Map.Entry; import java.util.Random; import java.util.Set; import java.util.WeakHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -448,6 +450,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private static final DataFlavor TREE_FILE_FLAVOR = new DataFlavor(TreeFileFlavor.class, "TreeFile"); private boolean editingStatusSet = false; + + private ExecutorService loadTagInfoExecutor = Executors.newSingleThreadExecutor(); public synchronized void setLoadingScrollPosEnabled(boolean loadingScrollPosEnabled) { this.loadingScrollPosEnabled = loadingScrollPosEnabled; @@ -6579,18 +6583,33 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se tagInfo.addInfo("general", "neededCharacters", Helper.joinStrings(needed, ", ")); } - if (tag instanceof CharacterTag) { + if (tag instanceof CharacterTag) { + int characterId = ((CharacterTag) tag).getCharacterId(); - Set dependent = tag.getSwf().getDependentCharacters(characterId); - if (dependent != null) { - if (dependent.size() > 0) { - tagInfo.addInfo("general", "dependentCharacters", Helper.joinStrings(dependent, ", ")); - } - } - - Set dependent2 = tag.getSwf().getDependentFrames(characterId); - if (dependent2 != null && dependent2.size() > 0) { - tagInfo.addInfo("general", "dependentFrames", Helper.joinStrings(dependent2, ", ")); + + //getting dependent characters/frames for the first time may be long task + + Runnable addDependentFramesRunnable = new Runnable() { + @Override + public void run() { + Set dependent = tag.getSwf().getDependentCharacters(characterId); + if (dependent != null) { + if (!dependent.isEmpty()) { + tagInfo.addInfo("general", "dependentCharacters", Helper.joinStrings(dependent, ", ")); + } + } + Set dependent2 = tag.getSwf().getDependentFrames(characterId); + if (dependent2 != null && !dependent2.isEmpty()) { + tagInfo.addInfo("general", "dependentFrames", Helper.joinStrings(dependent2, ", ")); + } + tagInfoPanel.updateTagInfo(); + } + }; + + if (tag.getSwf().isDependentFramesLoaded() && tag.getSwf().isDependentCharactersLoaded()) { + addDependentFramesRunnable.run(); + } else { + loadTagInfoExecutor.execute(addDependentFramesRunnable); } } diff --git a/src/com/jpexs/decompiler/flash/gui/TagInfoPanel.java b/src/com/jpexs/decompiler/flash/gui/TagInfoPanel.java index 853638079..3f066a20b 100644 --- a/src/com/jpexs/decompiler/flash/gui/TagInfoPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/TagInfoPanel.java @@ -108,13 +108,17 @@ public class TagInfoPanel extends JPanel { this.tagInfo = tagInfo; buildHtmlContent(); } + + public void updateTagInfo() { + buildHtmlContent(); + } public void clear() { this.tagInfo = new TagInfo(null); buildHtmlContent(); } - private void updateHtmlContent(boolean expand, boolean showDetails) { + private synchronized void updateHtmlContent(boolean expand, boolean showDetails) { String categoryName = "general"; StringBuilder result = new StringBuilder(); result.append(""); @@ -232,7 +236,6 @@ public class TagInfoPanel extends JPanel { } result.append("
"); - editorPane.setText(result.toString()); }