diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 2f2038a8d..9e8e63137 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -436,6 +436,10 @@ public class Configuration { public static final ConfigurationItem lastSessionData = null; + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("ui") + public static final ConfigurationItem loopMedia = null; + @ConfigurationDefaultBoolean(true) @ConfigurationCategory("ui") public static final ConfigurationItem allowOnlyOneInstance = null; diff --git a/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java b/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java index 790785944..d7502b143 100644 --- a/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java @@ -364,17 +364,13 @@ public class AdvancedSettingsDialog extends AppDialog implements ActionListener private void showRestartConfirmDialod() { if (View.showConfirmDialog(this, translate("advancedSettings.restartConfirmation"), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - Logger.getLogger(AdvancedSettingsDialog.class.getName()).log(Level.SEVERE, null, ex); - } - SelectLanguageDialog.reloadUi(); + View.execInEventDispatchLater(() -> { + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + Logger.getLogger(AdvancedSettingsDialog.class.getName()).log(Level.SEVERE, null, ex); } + SelectLanguageDialog.reloadUi(); }); } diff --git a/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java b/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java index d4a92442a..cd31a8fa0 100644 --- a/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java +++ b/src/com/jpexs/decompiler/flash/gui/ErrorLogFrame.java @@ -85,12 +85,9 @@ public class ErrorLogFrame extends AppFrame { public static ErrorLogFrame getInstance() { if (instance == null) { instance = new ErrorLogFrame(); - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - Logger logger = Logger.getLogger(""); - logger.addHandler(instance.getHandler()); - } + View.execInEventDispatch(() -> { + Logger logger = Logger.getLogger(""); + logger.addHandler(instance.getHandler()); }); } return instance; @@ -98,12 +95,9 @@ public class ErrorLogFrame extends AppFrame { public static ErrorLogFrame createNewInstance() { if (instance != null) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - Logger logger = Logger.getLogger(""); - logger.removeHandler(instance.getHandler()); - } + View.execInEventDispatch(() -> { + Logger logger = Logger.getLogger(""); + logger.removeHandler(instance.getHandler()); }); instance.setVisible(false); instance.dispose(); @@ -210,110 +204,107 @@ public class ErrorLogFrame extends AppFrame { private void log(final Level level, final String msg, final String detail) { if (logItemCount.getAndIncrement() < MAX_LOG_ITEM_COUNT) { - View.execInEventDispatchLater(new Runnable() { - @Override - public void run() { - notifyMainFrame(level); + View.execInEventDispatchLater(() -> { + notifyMainFrame(level); - JPanel pan = new JPanel(); - pan.setBackground(Color.white); - pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS)); + JPanel pan = new JPanel(); + pan.setBackground(Color.white); + pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS)); - JComponent detailComponent; - if (detail == null) { - detailComponent = null; - } else { - final JTextArea detailTextArea = new JTextArea(detail); - detailTextArea.setEditable(false); - detailTextArea.setOpaque(false); - detailTextArea.setFont(new JLabel().getFont()); - detailTextArea.setBackground(Color.white); - detailComponent = detailTextArea; + JComponent detailComponent; + if (detail == null) { + detailComponent = null; + } else { + final JTextArea detailTextArea = new JTextArea(detail); + detailTextArea.setEditable(false); + detailTextArea.setOpaque(false); + detailTextArea.setFont(new JLabel().getFont()); + detailTextArea.setBackground(Color.white); + detailComponent = detailTextArea; + } + JPanel header = new JPanel(); + header.setLayout(new BoxLayout(header, BoxLayout.X_AXIS)); + header.setBackground(Color.white); + + SimpleDateFormat format = new SimpleDateFormat("dd/MM/YYYY HH:mm:ss"); + final String dateStr = format.format(new Date()); + + JToggleButton copyButton = new JToggleButton(View.getIcon("copy16")); + copyButton.setFocusPainted(false); + copyButton.setBorderPainted(false); + copyButton.setFocusable(false); + copyButton.setContentAreaFilled(false); + copyButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + copyButton.setMargin(new Insets(2, 2, 2, 2)); + copyButton.setToolTipText(translate("copy")); + copyButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringSelection stringSelection = new StringSelection(dateStr + " " + level.toString() + " " + msg + "\r\n" + detail); + clipboard.setContents(stringSelection, null); } - JPanel header = new JPanel(); - header.setLayout(new BoxLayout(header, BoxLayout.X_AXIS)); - header.setBackground(Color.white); + }); - SimpleDateFormat format = new SimpleDateFormat("dd/MM/YYYY HH:mm:ss"); - final String dateStr = format.format(new Date()); + final JToggleButton expandButton = new JToggleButton(collapseIcon); + expandButton.setFocusPainted(false); + expandButton.setBorderPainted(false); + expandButton.setFocusable(false); + expandButton.setContentAreaFilled(false); + expandButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + expandButton.setMargin(new Insets(2, 2, 2, 2)); + expandButton.setToolTipText(translate("details")); - JToggleButton copyButton = new JToggleButton(View.getIcon("copy16")); - copyButton.setFocusPainted(false); - copyButton.setBorderPainted(false); - copyButton.setFocusable(false); - copyButton.setContentAreaFilled(false); - copyButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - copyButton.setMargin(new Insets(2, 2, 2, 2)); - copyButton.setToolTipText(translate("copy")); - copyButton.addActionListener(new ActionListener() { + final JScrollPane scrollPane; + if (detailComponent != null) { + scrollPane = new JScrollPane(detailComponent); + scrollPane.setAlignmentX(0f); + } else { + scrollPane = null; + } + + if (detailComponent != null) { + expandButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - StringSelection stringSelection = new StringSelection(dateStr + " " + level.toString() + " " + msg + "\r\n" + detail); - clipboard.setContents(stringSelection, null); + expandButton.setIcon(expandButton.isSelected() ? expandIcon : collapseIcon); + scrollPane.setVisible(expandButton.isSelected()); + revalidate(); + repaint(); } }); - - final JToggleButton expandButton = new JToggleButton(collapseIcon); - expandButton.setFocusPainted(false); - expandButton.setBorderPainted(false); - expandButton.setFocusable(false); - expandButton.setContentAreaFilled(false); - expandButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - expandButton.setMargin(new Insets(2, 2, 2, 2)); - expandButton.setToolTipText(translate("details")); - - final JScrollPane scrollPane; - if (detailComponent != null) { - scrollPane = new JScrollPane(detailComponent); - scrollPane.setAlignmentX(0f); - } else { - scrollPane = null; - } - - if (detailComponent != null) { - expandButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - expandButton.setIcon(expandButton.isSelected() ? expandIcon : collapseIcon); - scrollPane.setVisible(expandButton.isSelected()); - revalidate(); - repaint(); - } - }); - } - - if (detailComponent != null) { - header.add(expandButton); - } - JLabel dateLabel = new JLabel(dateStr); - dateLabel.setPreferredSize(new Dimension(200, (int) dateLabel.getPreferredSize().getHeight())); - dateLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - header.add(dateLabel); - - JLabel levelLabel = new JLabel(level.getName()); - levelLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - header.add(levelLabel); - JTextArea msgLabel = new JTextArea(msg); - msgLabel.setEditable(false); - msgLabel.setOpaque(false); - msgLabel.setFont(levelLabel.getFont()); - - msgLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - header.add(msgLabel); - header.setAlignmentX(0f); - - header.add(copyButton); - pan.add(header); - if (detailComponent != null) { - pan.add(scrollPane); - scrollPane.setVisible(false); - } - pan.setAlignmentX(0f); - logViewInner.add(pan); - revalidate(); - repaint(); } + + if (detailComponent != null) { + header.add(expandButton); + } + JLabel dateLabel = new JLabel(dateStr); + dateLabel.setPreferredSize(new Dimension(200, (int) dateLabel.getPreferredSize().getHeight())); + dateLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + header.add(dateLabel); + + JLabel levelLabel = new JLabel(level.getName()); + levelLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + header.add(levelLabel); + JTextArea msgLabel = new JTextArea(msg); + msgLabel.setEditable(false); + msgLabel.setOpaque(false); + msgLabel.setFont(levelLabel.getFont()); + + msgLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + header.add(msgLabel); + header.setAlignmentX(0f); + + header.add(copyButton); + pan.add(header); + if (detailComponent != null) { + pan.add(scrollPane); + scrollPane.setVisible(false); + } + pan.setAlignmentX(0f); + logViewInner.add(pan); + revalidate(); + repaint(); }); } } diff --git a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java index 367d6ee52..20ec7bd65 100644 --- a/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FolderPreviewPanel.java @@ -254,12 +254,8 @@ public class FolderPreviewPanel extends JPanel { cachedPreviews.put(index, renderImage(treeItem.getSwf(), treeItem)); if (!repaintQueued) { repaintQueued = true; - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - repaint(); - } + View.execInEventDispatchLater(() -> { + repaint(); }); } return null; diff --git a/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java b/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java index 136304ee0..a7c6c73f0 100644 --- a/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/GenericTagPanel.java @@ -313,11 +313,8 @@ public class GenericTagPanel extends JPanel implements ChangeListener { } catch (InterruptedException ex) { Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); } - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val); - } + View.execInEventDispatch(() -> { + genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val); }); } @@ -362,11 +359,8 @@ public class GenericTagPanel extends JPanel implements ChangeListener { } catch (InterruptedException ex) { Logger.getLogger(GenericTagPanel.class.getName()).log(Level.SEVERE, null, ex); } - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val); - } + View.execInEventDispatch(() -> { + genericTagPropertiesEditPanelScrollPanel.getVerticalScrollBar().setValue(val); }); } diff --git a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index 75efb4802..3af8c1bcf 100644 --- a/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -83,6 +83,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis private int frame = -1; + private boolean loop; + private boolean zoomAvailable = false; private int counter = 0; @@ -363,6 +365,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis setOpaque(true); setBackground(View.getDefaultBackgroundColor()); + loop = true; iconPanel = new IconPanel(); //labelPan.add(label, new GridBagConstraints()); add(iconPanel, BorderLayout.CENTER); @@ -529,7 +532,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis public void setTimelined(final Timelined drawable, final SWF swf, int frame) { synchronized (ImagePanel.class) { - pause(); + stopInternal(); if (drawable instanceof ButtonTag) { frame = ButtonTag.FRAME_UP; } @@ -650,7 +653,13 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis @Override public void pause() { - stop(); + stopInternal(); + } + + @Override + public void stop() { + stopInternal(); + rewind(); } private void stopAllSounds() { @@ -677,7 +686,17 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis synchronized (ImagePanel.class) { if (timelined != null && counter == this.counter) { int frameCount = timelined.getTimeline().getFrameCount(); - int newframe = frameCount > 0 ? (frame + 1) % frameCount : frame; + int newframe; + if (frameCount > 0) { + if (frame + 1 >= frameCount && !loop) { + newframe = frame; + } else { + newframe = (frame + 1) % frameCount; + } + } else { + newframe = frame; + } + if (stillFrame) { newframe = frame; } @@ -904,7 +923,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis } public synchronized void clearAll() { - stop(); + stopInternal(); clearImagePanel(); timelined = null; swf = null; @@ -912,14 +931,14 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis fireMediaDisplayStateChanged(); } - public synchronized void stop() { + private synchronized void stopInternal() { clear(); stopAllSounds(); } @Override public synchronized void play() { - pause(); + stopInternal(); if (timelined != null) { Timeline timeline = timelined.getTimeline(); int frameRate = timeline.frameRate; @@ -992,6 +1011,11 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis return (timelined.getTimeline().getFrameCount() <= 1) || (timer != null); } + @Override + public void setLoop(boolean loop) { + this.loop = loop; + } + @Override public synchronized void gotoFrame(int frame) { if (timelined == null) { @@ -1006,7 +1030,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis } this.frame = frame; - stop(); + stopInternal(); shouldDraw.set(true); startTimer(counter, true, 0); fireMediaDisplayStateChanged(); @@ -1028,6 +1052,11 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis return loaded; } + @Override + public boolean loopAvailable() { + return false; + } + @Override public boolean screenAvailable() { return true; diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 4d6bccd27..33a5caaf7 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -179,12 +179,9 @@ public class Main { } public static void startProxy(int port) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - if (proxyFrame == null) { - proxyFrame = new ProxyFrame(mainFrame); - } + View.execInEventDispatch(() -> { + if (proxyFrame == null) { + proxyFrame = new ProxyFrame(mainFrame); } }); proxyFrame.setPort(port); @@ -235,15 +232,12 @@ public class Main { public static void stopWork() { working = false; - View.execInEventDispatchLater(new Runnable() { - @Override - public void run() { - if (mainFrame != null) { - mainFrame.getPanel().setWorkStatus("", null); - } - if (loadingDialog != null) { - loadingDialog.setDetail(""); - } + View.execInEventDispatchLater(() -> { + if (mainFrame != null) { + mainFrame.getPanel().setWorkStatus("", null); + } + if (loadingDialog != null) { + loadingDialog.setDetail(""); } }); } @@ -478,12 +472,9 @@ public class Main { } try { Main.startWork(AppStrings.translate("work.creatingwindow") + "..."); - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - ensureMainFrame(); - mainFrame.getPanel().load(swfs1, first1); - } + View.execInEventDispatch(() -> { + ensureMainFrame(); + mainFrame.getPanel().load(swfs1, first1); }); } catch (Exception ex) { @@ -846,31 +837,21 @@ public class Main { logger.log(Level.SEVERE, null, ex); } } - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - ErrorLogFrame.createNewInstance(); - } + View.execInEventDispatch(() -> { + ErrorLogFrame.createNewInstance(); }); autoCheckForUpdates(); offerAssociation(); - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - loadingDialog = new LoadingDialog(); - } + View.execInEventDispatch(() -> { + loadingDialog = new LoadingDialog(); }); } public static void showModeFrame() { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - ensureMainFrame(); - mainFrame.setVisible(true); - } + View.execInEventDispatch(() -> { + ensureMainFrame(); + mainFrame.setVisible(true); }); } diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameStatusPanel.java b/src/com/jpexs/decompiler/flash/gui/MainFrameStatusPanel.java index b248d0bfd..21a2ea0ae 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameStatusPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameStatusPanel.java @@ -169,16 +169,13 @@ public class MainFrameStatusPanel extends JPanel implements ActionListener { blinkTimer.schedule(new TimerTask() { @Override public void run() { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - blinkPos++; - if ((blinkPos % 2) == 0 || (blinkPos >= 4)) { - errorNotificationButton.setIcon(currentIcon); - } else { - errorNotificationButton.setIcon(null); - errorNotificationButton.setSize(16, 16); - } + View.execInEventDispatch(() -> { + blinkPos++; + if ((blinkPos % 2) == 0 || (blinkPos >= 4)) { + errorNotificationButton.setIcon(currentIcon); + } else { + errorNotificationButton.setIcon(null); + errorNotificationButton.setSize(16, 16); } }); diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index fdbdc5cf6..a261bd55d 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -695,12 +695,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec private void ensureActionPanel() { if (actionPanel == null) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - actionPanel = new ActionPanel(MainPanel.this); - displayPanel.add(actionPanel, CARDACTIONSCRIPTPANEL); - } + View.execInEventDispatch(() -> { + actionPanel = new ActionPanel(MainPanel.this); + displayPanel.add(actionPanel, CARDACTIONSCRIPTPANEL); }); } } @@ -854,11 +851,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec refreshTree(null); if (updateNeeded) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - tagTree.updateUI(); - } + View.execInEventDispatch(() -> { + tagTree.updateUI(); }); } } @@ -887,21 +881,18 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec actionPanel.initSplits(); } - View.execInEventDispatchLater(new Runnable() { - @Override - public void run() { - splitPane1.setDividerLocation(Configuration.guiSplitPane1DividerLocation.get(getWidth() / 3)); - int confDivLoc = Configuration.guiSplitPane2DividerLocation.get(splitPane2.getHeight() * 3 / 5); - if (confDivLoc > splitPane2.getHeight() - 10) { //In older releases, divider location was saved when detailPanel was invisible too - confDivLoc = splitPane2.getHeight() * 3 / 5; - } - splitPane2.setDividerLocation(confDivLoc); - previewPanel.setDividerLocation(Configuration.guiPreviewSplitPaneDividerLocation.get(previewPanel.getWidth() / 2)); - - splitPos = splitPane2.getDividerLocation(); - splitsInited = true; - previewPanel.setSplitsInited(); + View.execInEventDispatchLater(() -> { + splitPane1.setDividerLocation(Configuration.guiSplitPane1DividerLocation.get(getWidth() / 3)); + int confDivLoc = Configuration.guiSplitPane2DividerLocation.get(splitPane2.getHeight() * 3 / 5); + if (confDivLoc > splitPane2.getHeight() - 10) { //In older releases, divider location was saved when detailPanel was invisible too + confDivLoc = splitPane2.getHeight() * 3 / 5; } + splitPane2.setDividerLocation(confDivLoc); + previewPanel.setDividerLocation(Configuration.guiPreviewSplitPaneDividerLocation.get(previewPanel.getWidth() / 2)); + + splitPos = splitPane2.getDividerLocation(); + splitsInited = true; + previewPanel.setSplitsInited(); }); } @@ -1310,22 +1301,16 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec if (swf.isAS3()) { if (abcPanel != null && abcPanel.search(txt, searchDialog.ignoreCaseCheckBox.isSelected(), searchDialog.regexpCheckBox.isSelected())) { found = true; - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - showDetail(DETAILCARDAS3NAVIGATOR); - showCard(CARDACTIONSCRIPT3PANEL); - } + View.execInEventDispatch(() -> { + showDetail(DETAILCARDAS3NAVIGATOR); + showCard(CARDACTIONSCRIPT3PANEL); }); } } else { if (getActionPanel().search(txt, searchDialog.ignoreCaseCheckBox.isSelected(), searchDialog.regexpCheckBox.isSelected())) { found = true; - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - showCard(CARDACTIONSCRIPTPANEL); - } + View.execInEventDispatch(() -> { + showCard(CARDACTIONSCRIPTPANEL); }); } } @@ -1970,14 +1955,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec Main.stopWork(); View.showMessageDialog(null, translate("work.deobfuscating.complete")); - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - clearAllScriptCache(); - getABCPanel().reload(); - updateClassesList(); - } + View.execInEventDispatch(() -> { + clearAllScriptCache(); + getABCPanel().reload(); + updateClassesList(); }); } }.execute(); @@ -2077,12 +2058,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec ignoreMissingCharacters ? JOptionPane.OK_OPTION : JOptionPane.CANCEL_OPTION) == JOptionPane.OK_OPTION; return false; } - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - font.addCharacter(character, f); - } + View.execInEventDispatch(() -> { + font.addCharacter(character, f); }); return true; @@ -2533,9 +2510,10 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return; } - TreeItem treeItem = (TreeItem) tagTree.getLastSelectedPathComponent(); - if (treeItem == null) { - return; + TreeItem treeItem = null; + TreePath treePath = tagTree.getSelectionPath(); + if (treePath != null && tagTree.getModel().treePathExists(treePath)) { + treeItem = (TreeItem) treePath.getLastPathComponent(); } if (!forceReload && (treeItem == oldItem)) { @@ -2693,7 +2671,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewPanel.showImagePanel(new SerializableImage(View.loadImage("sound32"))); previewPanel.setImageReplaceButtonVisible(treeItem instanceof DefineSoundTag); try { - SoundTagPlayer soundThread = new SoundTagPlayer((SoundTag) treeItem, Integer.MAX_VALUE, true); + SoundTagPlayer soundThread = new SoundTagPlayer((SoundTag) treeItem, Configuration.loopMedia.get() ? Integer.MAX_VALUE : 1, true); previewPanel.setMedia(soundThread); } catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) { logger.log(Level.SEVERE, null, ex); diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java index 36e009b8b..ee7245ad5 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewPanel.java @@ -395,6 +395,7 @@ public class PreviewPanel extends JSplitPane implements ActionListener { JPanel previewCnt = new JPanel(new BorderLayout()); imagePanel = new ImagePanel(); + imagePanel.setLoop(Configuration.loopMedia.get()); previewCnt.add(imagePanel, BorderLayout.CENTER); previewCnt.add(imagePlayControls = new PlayerControls(mainPanel, imagePanel), BorderLayout.SOUTH); imagePlayControls.setMedia(imagePanel); diff --git a/src/com/jpexs/decompiler/flash/gui/SearchPanel.java b/src/com/jpexs/decompiler/flash/gui/SearchPanel.java index f8f060180..6c6a5e5fd 100644 --- a/src/com/jpexs/decompiler/flash/gui/SearchPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/SearchPanel.java @@ -124,12 +124,9 @@ public class SearchPanel extends JPanel implements ActionListener { } private void doUpdate() { - View.execInEventDispatchLater(new Runnable() { - @Override - public void run() { - searchPos.setText((foundPos + 1) + "/" + found.size()); - listener.updateSearchPos(found.get(foundPos)); - } + View.execInEventDispatchLater(() -> { + searchPos.setText((foundPos + 1) + "/" + found.size()); + listener.updateSearchPos(found.get(foundPos)); }); } diff --git a/src/com/jpexs/decompiler/flash/gui/SearchResultsDialog.java b/src/com/jpexs/decompiler/flash/gui/SearchResultsDialog.java index 2e77a0062..a712c911c 100644 --- a/src/com/jpexs/decompiler/flash/gui/SearchResultsDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/SearchResultsDialog.java @@ -112,13 +112,8 @@ public class SearchResultsDialog extends AppDialog implements ActionListener private void gotoElement() { if (resultsList.getSelectedIndex() != -1) { - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - listener.updateSearchPos(resultsList.getSelectedValue()); - } - + View.execInEventDispatchLater(() -> { + listener.updateSearchPos(resultsList.getSelectedValue()); }); } } diff --git a/src/com/jpexs/decompiler/flash/gui/SelectLanguageDialog.java b/src/com/jpexs/decompiler/flash/gui/SelectLanguageDialog.java index eaf42bfb8..13ecb96ca 100644 --- a/src/com/jpexs/decompiler/flash/gui/SelectLanguageDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/SelectLanguageDialog.java @@ -128,15 +128,11 @@ public class SelectLanguageDialog extends AppDialog implements ActionListener { } public static void reloadUi() { - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - Locale.setDefault(Locale.forLanguageTag(Configuration.locale.get())); - DefaultSyntaxKit.reloadConfigs(); - Main.initLang(); - Main.reloadApp(); - } + View.execInEventDispatchLater(() -> { + Locale.setDefault(Locale.forLanguageTag(Configuration.locale.get())); + DefaultSyntaxKit.reloadConfigs(); + Main.initLang(); + Main.reloadApp(); }); } diff --git a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java index ee7015e29..3ee757274 100644 --- a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java +++ b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java @@ -30,6 +30,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.Logger; import javax.sound.sampled.AudioSystem; @@ -56,8 +58,12 @@ public class SoundTagPlayer implements MediaDisplay { private final SoundTag tag; + private final Timer timer; + private final List listeners = new ArrayList<>(); + private boolean rewindAfterStop = false; + @Override public void addEventListener(MediaDisplayListener listener) { listeners.add(listener); @@ -68,6 +74,12 @@ public class SoundTagPlayer implements MediaDisplay { listeners.remove(listener); } + public void fireMediaDisplayStateChanged() { + for (MediaDisplayListener l : listeners) { + l.mediaDisplayStateChanged(this); + } + } + private void firePlayingFinished() { for (MediaDisplayListener l : listeners) { l.playingFinished(this); @@ -85,7 +97,6 @@ public class SoundTagPlayer implements MediaDisplay { @Override public void update(LineEvent event) { if (event.getType() == LineEvent.Type.STOP) { - //clip.close(); synchronized (playLock) { if (!paused) { decreaseLoopCount(); @@ -98,10 +109,32 @@ public class SoundTagPlayer implements MediaDisplay { } } } + + if (rewindAfterStop) { + rewind(); + rewindAfterStop = false; + } } + + fireMediaDisplayStateChanged(); } }); + timer = new Timer(); + timer.schedule(new TimerTask() { + + @Override + public void run() { + + try { + fireMediaDisplayStateChanged(); + } catch (Exception ex) { + // ignore + cancel(); + } + } + }, 100, 100); + if (!async) { paused = true; openSound(tag); @@ -168,6 +201,13 @@ public class SoundTagPlayer implements MediaDisplay { } } + @Override + public void stop() { + rewindAfterStop = true; + pause(); + rewind(); + } + @Override public void play() { synchronized (playLock) { @@ -181,6 +221,8 @@ public class SoundTagPlayer implements MediaDisplay { clip.start(); } } + + fireMediaDisplayStateChanged(); } @Override @@ -195,6 +237,11 @@ public class SoundTagPlayer implements MediaDisplay { } } + @Override + public boolean loopAvailable() { + return true; + } + @Override public boolean screenAvailable() { return false; @@ -219,19 +266,18 @@ public class SoundTagPlayer implements MediaDisplay { return null; } + @Override + public void setLoop(boolean loop) { + loopCount = loop ? Integer.MAX_VALUE : 1; + } + @Override public void gotoFrame(int frame) { synchronized (playLock) { - boolean active = clip.isActive(); - if (active) { - clip.stop(); - } clip.setMicrosecondPosition((long) frame * FRAME_DIVISOR); - - if (active) { - clip.start(); - } } + + fireMediaDisplayStateChanged(); } @Override @@ -257,6 +303,8 @@ public class SoundTagPlayer implements MediaDisplay { @Override protected void finalize() throws Throwable { try { + timer.cancel(); + if (clip != null) { clip.close(); } diff --git a/src/com/jpexs/decompiler/flash/gui/TextPanel.java b/src/com/jpexs/decompiler/flash/gui/TextPanel.java index 86112dc4b..cc6f5f09e 100644 --- a/src/com/jpexs/decompiler/flash/gui/TextPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/TextPanel.java @@ -313,12 +313,8 @@ public class TextPanel extends JPanel { public void updateSearchPos() { textValue.setCaretPosition(0); - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - textSearchPanel.showQuickFindDialog(textValue); - } + View.execInEventDispatchLater(() -> { + textSearchPanel.showQuickFindDialog(textValue); }); } diff --git a/src/com/jpexs/decompiler/flash/gui/View.java b/src/com/jpexs/decompiler/flash/gui/View.java index bd3776004..5d2a8b0eb 100644 --- a/src/com/jpexs/decompiler/flash/gui/View.java +++ b/src/com/jpexs/decompiler/flash/gui/View.java @@ -150,109 +150,105 @@ public class View { } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException ignored) { } - execInEventDispatch(new Runnable() { - @Override - public void run() { + execInEventDispatch(() -> { + try { + UIManager.setLookAndFeel(new SubstanceOfficeBlue2007LookAndFeel()); + SubstanceLookAndFeel.setSkin(Configuration.guiSkin.get()); + UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, 0.999);//This works for not changing labels color and not changing Dialogs title + UIManager.put("Tree.expandedIcon", getIcon("expand16")); + UIManager.put("Tree.collapsedIcon", getIcon("collapse16")); + UIManager.put("ColorChooserUI", BasicColorChooserUI.class.getName()); + UIManager.put("ColorChooser.swatchesRecentSwatchSize", new Dimension(20, 20)); + UIManager.put("ColorChooser.swatchesSwatchSize", new Dimension(20, 20)); + UIManager.put("RibbonApplicationMenuPopupPanelUI", MyRibbonApplicationMenuPopupPanelUI.class.getName()); + UIManager.put("RibbonApplicationMenuButtonUI", MyRibbonApplicationMenuButtonUI.class.getName()); + UIManager.put("ProgressBarUI", MyProgressBarUI.class.getName()); + UIManager.put("TextField.background", Color.white); + UIManager.put("FormattedTextField.background", Color.white); + UIManager.put("CommandButtonUI", MyCommandButtonUI.class.getName()); - try { - UIManager.setLookAndFeel(new SubstanceOfficeBlue2007LookAndFeel()); - SubstanceLookAndFeel.setSkin(Configuration.guiSkin.get()); - UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, 0.999);//This works for not changing labels color and not changing Dialogs title - UIManager.put("Tree.expandedIcon", getIcon("expand16")); - UIManager.put("Tree.collapsedIcon", getIcon("collapse16")); - UIManager.put("ColorChooserUI", BasicColorChooserUI.class.getName()); - UIManager.put("ColorChooser.swatchesRecentSwatchSize", new Dimension(20, 20)); - UIManager.put("ColorChooser.swatchesSwatchSize", new Dimension(20, 20)); - UIManager.put("RibbonApplicationMenuPopupPanelUI", MyRibbonApplicationMenuPopupPanelUI.class.getName()); - UIManager.put("RibbonApplicationMenuButtonUI", MyRibbonApplicationMenuButtonUI.class.getName()); - UIManager.put("ProgressBarUI", MyProgressBarUI.class.getName()); - UIManager.put("TextField.background", Color.white); - UIManager.put("FormattedTextField.background", Color.white); - UIManager.put("CommandButtonUI", MyCommandButtonUI.class.getName()); + FontPolicy pol = SubstanceLookAndFeel.getFontPolicy(); + final FontSet fs = pol.getFontSet("Substance", null); - FontPolicy pol = SubstanceLookAndFeel.getFontPolicy(); - final FontSet fs = pol.getFontSet("Substance", null); + //Restore default font for chinese characters + SubstanceLookAndFeel.setFontPolicy(new FontPolicy() { - //Restore default font for chinese characters - SubstanceLookAndFeel.setFontPolicy(new FontPolicy() { + private final FontSet fontSet = new FontSet() { - private final FontSet fontSet = new FontSet() { + private FontUIResource controlFont; - private FontUIResource controlFont; + private FontUIResource menuFont; - private FontUIResource menuFont; + private FontUIResource titleFont; - private FontUIResource titleFont; + private FontUIResource windowTitleFont; - private FontUIResource windowTitleFont; + private FontUIResource smallFont; - private FontUIResource smallFont; - - private FontUIResource messageFont; - - @Override - public FontUIResource getControlFont() { - if (controlFont == null) { - FontUIResource f = fs.getControlFont(); - controlFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); - } - return controlFont; - } - - @Override - public FontUIResource getMenuFont() { - if (menuFont == null) { - FontUIResource f = fs.getMenuFont(); - menuFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); - } - return menuFont; - } - - @Override - public FontUIResource getTitleFont() { - if (titleFont == null) { - FontUIResource f = fs.getTitleFont(); - titleFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); - } - return titleFont; - } - - @Override - public FontUIResource getWindowTitleFont() { - if (windowTitleFont == null) { - FontUIResource f = fs.getWindowTitleFont(); - windowTitleFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); - } - return windowTitleFont; - } - - @Override - public FontUIResource getSmallFont() { - if (smallFont == null) { - FontUIResource f = fs.getSmallFont(); - smallFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); - } - return smallFont; - } - - @Override - public FontUIResource getMessageFont() { - if (messageFont == null) { - FontUIResource f = fs.getMessageFont(); - messageFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); - } - return messageFont; - } - }; + private FontUIResource messageFont; @Override - public FontSet getFontSet(String string, UIDefaults uid) { - return fontSet; + public FontUIResource getControlFont() { + if (controlFont == null) { + FontUIResource f = fs.getControlFont(); + controlFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); + } + return controlFont; } - }); - } catch (UnsupportedLookAndFeelException ex) { - Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex); - } + + @Override + public FontUIResource getMenuFont() { + if (menuFont == null) { + FontUIResource f = fs.getMenuFont(); + menuFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); + } + return menuFont; + } + + @Override + public FontUIResource getTitleFont() { + if (titleFont == null) { + FontUIResource f = fs.getTitleFont(); + titleFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); + } + return titleFont; + } + + @Override + public FontUIResource getWindowTitleFont() { + if (windowTitleFont == null) { + FontUIResource f = fs.getWindowTitleFont(); + windowTitleFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); + } + return windowTitleFont; + } + + @Override + public FontUIResource getSmallFont() { + if (smallFont == null) { + FontUIResource f = fs.getSmallFont(); + smallFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); + } + return smallFont; + } + + @Override + public FontUIResource getMessageFont() { + if (messageFont == null) { + FontUIResource f = fs.getMessageFont(); + messageFont = new FontUIResource(defaultFont.getName(), f.getStyle(), f.getSize()); + } + return messageFont; + } + }; + + @Override + public FontSet getFontSet(String string, UIDefaults uid) { + return fontSet; + } + }); + } catch (UnsupportedLookAndFeelException ex) { + Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex); } }); @@ -389,11 +385,8 @@ public class View { public static int showOptionDialog(final Component parentComponent, final Object message, final String title, final int optionType, final int messageType, final Icon icon, final Object[] options, final Object initialValue) { final int[] ret = new int[1]; - execInEventDispatch(new Runnable() { - @Override - public void run() { - ret[0] = JOptionPane.showOptionDialog(parentComponent, message, title, optionType, messageType, icon, options, initialValue); - } + execInEventDispatch(() -> { + ret[0] = JOptionPane.showOptionDialog(parentComponent, message, title, optionType, messageType, icon, options, initialValue); }); return ret[0]; } @@ -404,11 +397,8 @@ public class View { public static int showConfirmDialog(final Component parentComponent, final Object message, final String title, final int optionType, final int messageTyp) { final int ret[] = new int[1]; - execInEventDispatch(new Runnable() { - @Override - public void run() { - ret[0] = JOptionPane.showConfirmDialog(parentComponent, message, title, optionType, messageTyp); - } + execInEventDispatch(() -> { + ret[0] = JOptionPane.showConfirmDialog(parentComponent, message, title, optionType, messageTyp); }); return ret[0]; } @@ -431,11 +421,8 @@ public class View { } final int ret[] = new int[1]; - execInEventDispatch(new Runnable() { - @Override - public void run() { - ret[0] = JOptionPane.showConfirmDialog(parentComponent, warPanel, title, optionType, messageTyp); - } + execInEventDispatch(() -> { + ret[0] = JOptionPane.showConfirmDialog(parentComponent, warPanel, title, optionType, messageTyp); }); showAgainConfig.set(!donotShowAgainCheckBox.isSelected()); return ret[0]; @@ -471,21 +458,15 @@ public class View { } public static void showMessageDialog(final Component parentComponent, final Object message) { - execInEventDispatch(new Runnable() { - @Override - public void run() { - JOptionPane.showMessageDialog(parentComponent, message); - } + execInEventDispatch(() -> { + JOptionPane.showMessageDialog(parentComponent, message); }); } public static String showInputDialog(final Object message, final Object initialSelection) { final String[] ret = new String[1]; - execInEventDispatch(new Runnable() { - @Override - public void run() { - ret[0] = JOptionPane.showInputDialog(message, initialSelection); - } + execInEventDispatch(() -> { + ret[0] = JOptionPane.showInputDialog(message, initialSelection); }); return ret[0]; } @@ -623,52 +604,49 @@ public class View { } public static JTable autoResizeColWidth(final JTable table, final TableModel model) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); - table.setModel(model); + View.execInEventDispatch(() -> { + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + table.setModel(model); - int margin = 5; + int margin = 5; - for (int i = 0; i < table.getColumnCount(); i++) { - int vColIndex = i; - DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel(); - TableColumn col = colModel.getColumn(vColIndex); - int width; + for (int i = 0; i < table.getColumnCount(); i++) { + int vColIndex = i; + DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel(); + TableColumn col = colModel.getColumn(vColIndex); + int width; - // Get width of column header - TableCellRenderer renderer = col.getHeaderRenderer(); + // Get width of column header + TableCellRenderer renderer = col.getHeaderRenderer(); - if (renderer == null) { - renderer = table.getTableHeader().getDefaultRenderer(); - } - - Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0); - - width = comp.getPreferredSize().width; - - // Get maximum width of column data - for (int r = 0; r < table.getRowCount(); r++) { - renderer = table.getCellRenderer(r, vColIndex); - comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, vColIndex), false, false, - r, vColIndex); - width = Math.max(width, comp.getPreferredSize().width); - } - - // Add margin - width += 2 * margin; - - // Set the width - col.setPreferredWidth(width); + if (renderer == null) { + renderer = table.getTableHeader().getDefaultRenderer(); } - ((DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer()).setHorizontalAlignment( - SwingConstants.LEFT); + Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0); - // table.setAutoCreateRowSorter(true); - table.getTableHeader().setReorderingAllowed(false); + width = comp.getPreferredSize().width; + + // Get maximum width of column data + for (int r = 0; r < table.getRowCount(); r++) { + renderer = table.getCellRenderer(r, vColIndex); + comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, vColIndex), false, false, + r, vColIndex); + width = Math.max(width, comp.getPreferredSize().width); + } + + // Add margin + width += 2 * margin; + + // Set the width + col.setPreferredWidth(width); } + + ((DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer()).setHorizontalAlignment( + SwingConstants.LEFT); + + // table.setAutoCreateRowSorter(true); + table.getTableHeader().setReorderingAllowed(false); }); return table; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index f71d92876..33c7b2327 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -219,14 +219,10 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se searchPanel.setSearchText(txt); - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - SearchResultsDialog sr = new SearchResultsDialog<>(ABCPanel.this.mainPanel.getMainFrame().getWindow(), txt, ABCPanel.this); - sr.setResults(found); - sr.setVisible(true); - } + View.execInEventDispatch(() -> { + SearchResultsDialog sr = new SearchResultsDialog<>(ABCPanel.this.mainPanel.getMainFrame().getWindow(), txt, ABCPanel.this); + sr.setResults(found); + sr.setVisible(true); }); return true; @@ -703,12 +699,9 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se public void hilightScript(ScriptPack pack) { TagTreeModel ttm = (TagTreeModel) mainPanel.tagTree.getModel(); final TreePath tp = ttm.getTreePath(pack); - View.execInEventDispatchLater(new Runnable() { - @Override - public void run() { - mainPanel.tagTree.setSelectionPath(tp); - mainPanel.tagTree.scrollPathToVisible(tp); - } + View.execInEventDispatchLater(() -> { + mainPanel.tagTree.setSelectionPath(tp); + mainPanel.tagTree.scrollPathToVisible(tp); }); } @@ -721,12 +714,8 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se hilightScript(pack); decompiledTextArea.setCaretPosition(0); - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - searchPanel.showQuickFindDialog(decompiledTextArea); - } + View.execInEventDispatchLater(() -> { + searchPanel.showQuickFindDialog(decompiledTextArea); }); } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 9790969f5..935b87b78 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -499,11 +499,8 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL @Override public void caretUpdate(final CaretEvent e) { if (!SwingUtilities.isEventDispatchThread()) { - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - caretUpdate(e); - } + View.execInEventDispatch(() -> { + caretUpdate(e); }); return; } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java index e569c0b3c..97d141bc3 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java @@ -159,39 +159,35 @@ public class DetailPanel extends JPanel implements ActionListener { } public void showCard(final String name, final Trait trait) { - View.execInEventDispatch(new Runnable() { + View.execInEventDispatch(() -> { + CardLayout layout = (CardLayout) innerPanel.getLayout(); + layout.show(innerPanel, name); + boolean b = cardMap.get(name) instanceof TraitDetail; + buttonsPanel.setVisible(b); - @Override - public void run() { - CardLayout layout = (CardLayout) innerPanel.getLayout(); - layout.show(innerPanel, name); - boolean b = cardMap.get(name) instanceof TraitDetail; - buttonsPanel.setVisible(b); - - TraitDetail newDetail = null; - if (b) { - newDetail = (TraitDetail) cardMap.get(name); - } - for (JComponent v : cardMap.values()) { - if (v instanceof TraitDetail) { - if (v != newDetail) { - TraitDetail oldDetail = (TraitDetail) v; - oldDetail.setActive(false); - } + TraitDetail newDetail = null; + if (b) { + newDetail = (TraitDetail) cardMap.get(name); + } + for (JComponent v : cardMap.values()) { + if (v instanceof TraitDetail) { + if (v != newDetail) { + TraitDetail oldDetail = (TraitDetail) v; + oldDetail.setActive(false); } } - if (newDetail != null) { - newDetail.setActive(true); - } + } + if (newDetail != null) { + newDetail.setActive(true); + } - selectedCard = name; - selectedLabel.setText(selectedCard); - if (trait == null) { - traitNameLabel.setText("-"); - } else { - if (abcPanel != null) { - traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList<>(), false)); - } + selectedCard = name; + selectedLabel.setText(selectedCard); + if (trait == null) { + traitNameLabel.setText("-"); + } else { + if (abcPanel != null) { + traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList<>(), false)); } } }); diff --git a/src/com/jpexs/decompiler/flash/gui/abc/UndoFixedEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/UndoFixedEditorPane.java index 3a1254fe2..96c072c42 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/UndoFixedEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/UndoFixedEditorPane.java @@ -42,12 +42,8 @@ public class UndoFixedEditorPane extends JEditorPane { @Override public void setText(final String t) { - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - setText(t, getContentType()); - } + View.execInEventDispatch(() -> { + setText(t, getContentType()); }); } diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index ae92aeac1..23ffff714 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -277,14 +277,10 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene Main.stopWork(); searchPanel.setSearchText(txt); - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - SearchResultsDialog sr = new SearchResultsDialog<>(ActionPanel.this.mainPanel.getMainFrame().getWindow(), txt, ActionPanel.this); - sr.setResults(found); - sr.setVisible(true); - } + View.execInEventDispatch(() -> { + SearchResultsDialog sr = new SearchResultsDialog<>(ActionPanel.this.mainPanel.getMainFrame().getWindow(), txt, ActionPanel.this); + sr.setResults(found); + sr.setVisible(true); }); return true; //return searchPanel.setResults(found); @@ -293,52 +289,40 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene } private void setDecompiledText(final String text) { - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - ignoreCarret = true; - decompiledEditor.setText(text); - ignoreCarret = false; - } + View.execInEventDispatch(() -> { + ignoreCarret = true; + decompiledEditor.setText(text); + ignoreCarret = false; }); } private void setEditorText(final String text, final String contentType) { - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - ignoreCarret = true; - editor.setContentType(contentType); - editor.setText(text); - ignoreCarret = false; - } + View.execInEventDispatch(() -> { + ignoreCarret = true; + editor.setContentType(contentType); + editor.setText(text); + ignoreCarret = false; }); } private void setText(final HighlightedText text, final String contentType) { - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - int pos = editor.getCaretPosition(); - Highlighting lastH = null; - for (Highlighting h : disassembledHilights) { - if (pos < h.startPos) { - break; - } - lastH = h; + View.execInEventDispatch(() -> { + int pos = editor.getCaretPosition(); + Highlighting lastH = null; + for (Highlighting h : disassembledHilights) { + if (pos < h.startPos) { + break; } - Long offset = lastH == null ? 0 : lastH.getProperties().offset; - disassembledHilights = text.instructionHilights; - String stripped = text.text; - setEditorText(stripped, contentType); - Highlighting h = Highlighting.searchOffset(disassembledHilights, offset); - if (h != null) { - if (h.startPos <= editor.getDocument().getLength()) { - editor.setCaretPosition(h.startPos); - } + lastH = h; + } + Long offset = lastH == null ? 0 : lastH.getProperties().offset; + disassembledHilights = text.instructionHilights; + String stripped = text.text; + setEditorText(stripped, contentType); + Highlighting h = Highlighting.searchOffset(disassembledHilights, offset); + if (h != null) { + if (h.startPos <= editor.getDocument().getLength()) { + editor.setCaretPosition(h.startPos); } } }); @@ -468,17 +452,13 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene setSourceWorker = null; Main.stopWork(); - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - try { - get(); - } catch (CancellationException ex) { - setEditorText("; " + AppStrings.translate("work.canceled"), "text/flasm"); - } catch (Exception ex) { - setDecompiledText("// " + AppStrings.translate("decompilationError") + ": " + ex); - } + View.execInEventDispatch(() -> { + try { + get(); + } catch (CancellationException ex) { + setEditorText("; " + AppStrings.translate("work.canceled"), "text/flasm"); + } catch (Exception ex) { + setDecompiledText("// " + AppStrings.translate("decompilationError") + ": " + ex); } }); } @@ -839,12 +819,8 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene mainPanel.tagTree.scrollPathToVisible(tp); decompiledEditor.setCaretPosition(0); - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - searchPanel.showQuickFindDialog(decompiledEditor); - } + View.execInEventDispatchLater(() -> { + searchPanel.showQuickFindDialog(decompiledEditor); }); } } diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/loopoff16.png b/src/com/jpexs/decompiler/flash/gui/graphics/loopoff16.png new file mode 100644 index 000000000..1c4f57a16 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/loopoff16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/loopon16.png b/src/com/jpexs/decompiler/flash/gui/graphics/loopon16.png new file mode 100644 index 000000000..406ec333b Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/loopon16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index e18297b1a..e5dba47c1 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -344,3 +344,6 @@ config.description.gui.skin = Look and feel skin config.name.lastSessionData = Last session data config.description.lastSessionData = Contains the opened files from the last session + +config.name.loopMedia = Loop sounds and sprites +config.description.lastSessionData = Automatically restarts the playing of the sounds and sprites diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_hu.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_hu.properties index 0d87dfd36..4e53911cf 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_hu.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_hu.properties @@ -344,3 +344,6 @@ config.description.gui.skin = Kin\u00e9zet config.name.lastSessionData = Utols\u00f3 munkamenet adatai config.description.lastSessionData = Az legut\u00f3bbi munkamenetben megnyitott f\u00e1jlokat tartalmazza + +config.name.loopMedia = Zen\u00e9k \u00e9s szpr\u00e1jtok +config.description.lastSessionData = Aut\u00f3matikusan \u00fajraind\u00edtja a zen\u00e9k \u00e9s szpr\u00e1jtok lej\u00e1tsz\u00e1s\u00e1t diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 0f4cb1c26..cca6578b3 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -577,3 +577,6 @@ selectNextTag = Select next tag button.ignoreAll = Ignore All menu.file.import.symbolClass = Import Symbol-Class text.toggleCase = Toggle case + +#after version 5.0.2 +preview.loop = Loop diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties index 020325957..79bcadaec 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_hu.properties @@ -576,3 +576,6 @@ selectNextTag = K\u00f6vetkez\u0151 tag kiv\u00e1laszt\u00e1sa button.ignoreAll = Mell\u0151z mindet menu.file.import.symbolClass = Szimb\u00f3lum oszt\u00e1ly import\u00e1l\u00e1s text.toggleCase = Kis- nagybet\u0171 v\u00e1ltoztat\u00e1s + +#after version 5.0.2 +preview.loop = Ism\u00e9tl\u00e9s diff --git a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index 811246699..d36c7745b 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -56,6 +56,11 @@ public final class FlashPlayerPanel extends Panel implements Closeable, MediaDis private int frameRate; + @Override + public boolean loopAvailable() { + return false; + } + @Override public boolean screenAvailable() { return true; @@ -261,6 +266,15 @@ public final class FlashPlayerPanel extends Panel implements Closeable, MediaDis } } + @Override + public void stop() { + try { + flash.Stop(); + flash.Rewind(); + } catch (ActiveXException ex) { // Can be "Data not available yet exception" + } + } + @Override public void rewind() { try { @@ -286,6 +300,10 @@ public final class FlashPlayerPanel extends Panel implements Closeable, MediaDis } } + @Override + public void setLoop(boolean loop) { + } + @Override public void gotoFrame(int frame) { if (frame < 0) { diff --git a/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java b/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java index 4596ae4b2..1bca6866d 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java +++ b/src/com/jpexs/decompiler/flash/gui/player/MediaDisplay.java @@ -33,12 +33,16 @@ public interface MediaDisplay { public void pause(); + public void stop(); + public void play(); public void rewind(); public boolean isPlaying(); + public void setLoop(boolean loop); + public void gotoFrame(int frame); public void setBackground(Color color); @@ -49,6 +53,8 @@ public interface MediaDisplay { public BufferedImage printScreen(); + public boolean loopAvailable(); + public boolean screenAvailable(); public boolean zoomAvailable(); diff --git a/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java b/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java index 36bb36000..5c732140b 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java +++ b/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.gui.player; +import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.AppStrings; import com.jpexs.decompiler.flash.gui.MainPanel; import com.jpexs.decompiler.flash.gui.View; @@ -67,6 +68,8 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl private static final String ACTION_STOP = "STOP"; + private static final String ACTION_LOOP = "LOOP"; + private static final String ACTION_SELECT_BKCOLOR = "SELECTCOLOR"; private static final String ACTION_ZOOMIN = "ZOOMIN"; @@ -87,6 +90,8 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl private final JButton pauseButton; + private final JButton loopButton; + private boolean paused = false; private MediaDisplay display; @@ -105,6 +110,10 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl private static final Icon playIcon = View.getIcon("play16"); + private static final Icon loopIcon = View.getIcon("loopon16"); + + private static final Icon noLoopIcon = View.getIcon("loopoff16"); + private final JLabel percentLabel = new JLabel("100%"); private final JPanel zoomPanel; @@ -121,6 +130,8 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl private final JButton zoomFitButton; + private final JButton snapshotButton; + public static final int ZOOM_DECADE_STEPS = 10; public static final double ZOOM_MULTIPLIER = Math.pow(10, 1.0 / ZOOM_DECADE_STEPS); @@ -172,7 +183,7 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl zoomNoneButton.setActionCommand(ACTION_ZOOMNONE); zoomNoneButton.setToolTipText(AppStrings.translate("button.zoomnone.hint")); - JButton snapshotButton = new JButton(View.getIcon("snapshot16")); + snapshotButton = new JButton(View.getIcon("snapshot16")); snapshotButton.addActionListener(this); snapshotButton.setActionCommand(ACTION_SNAPSHOT); snapshotButton.setToolTipText(AppStrings.translate("button.snapshot.hint")); @@ -287,8 +298,16 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl stopButton.setMargin(new Insets(4, 2, 2, 2)); stopButton.setActionCommand(ACTION_STOP); stopButton.addActionListener(this); + loopButton = new JButton(pauseIcon); + loopButton.setToolTipText(AppStrings.translate("preview.loop")); + loopButton.setMargin(new Insets(4, 2, 2, 2)); + loopButton.setActionCommand(ACTION_LOOP); + loopButton.addActionListener(this); + boolean loop = Configuration.loopMedia.get(); + loopButton.setIcon(loop ? loopIcon : noLoopIcon); buttonsPanel.add(pauseButton); buttonsPanel.add(stopButton); + buttonsPanel.add(loopButton); controlPanel.add(buttonsPanel, BorderLayout.CENTER); progress = new JProgressBar(); @@ -339,6 +358,8 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl this.display = media; this.display.addEventListener(this); + + update(); } private void update() { @@ -346,53 +367,51 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl return; } - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - updateZoom(); - Zoom zoom = display.getZoom(); - zoomFitButton.setVisible(zoom != null); - percentLabel.setVisible(zoom != null); - zoomPanel.setVisible(display.zoomAvailable()); - boolean screenAvailable = display.screenAvailable(); - graphicControls.setVisible(screenAvailable); - totalFrameLabel.setVisible(screenAvailable); - frameLabel.setVisible(screenAvailable); - frameControls.setVisible(screenAvailable); - int totalFrames = display.getTotalFrames(); - int currentFrame = display.getCurrentFrame(); - if (currentFrame >= totalFrames) { - currentFrame = totalFrames - 1; - } - int frameRate = display.getFrameRate(); - if (totalFrames == 0) { - progress.setIndeterminate(true); - } else { - progress.setMaximum(totalFrames - 1); - progress.setMinimum(0); - progress.setValue(currentFrame); - progress.setIndeterminate(false); - } - frameLabel.setText(("" + (currentFrame + 1))); - totalFrameLabel.setText("" + totalFrames); - if (frameRate != 0) { - timeLabel.setText("(" + formatMs((currentFrame * 1000) / frameRate) + ")"); - totalTimeLabel.setText("(" + formatMs(((totalFrames - 1) * 1000) / frameRate) + ")"); - } - if (totalFrames <= 1 && playbackControls.isVisible()) { - playbackControls.setVisible(false); - } - if (totalFrames > 1 && !playbackControls.isVisible()) { - playbackControls.setVisible(true); - } - boolean paused = !display.isPlaying(); - if (paused) { - pauseButton.setToolTipText(AppStrings.translate("preview.play")); - pauseButton.setIcon(playIcon); - } else { - pauseButton.setToolTipText(AppStrings.translate("preview.pause")); - pauseButton.setIcon(pauseIcon); - } + View.execInEventDispatchLater(() -> { + updateZoom(); + Zoom zoom = display.getZoom(); + zoomFitButton.setVisible(zoom != null); + percentLabel.setVisible(zoom != null); + zoomPanel.setVisible(display.zoomAvailable()); + boolean screenAvailable = display.screenAvailable(); + snapshotButton.setVisible(screenAvailable); + graphicControls.setVisible(screenAvailable); + totalFrameLabel.setVisible(screenAvailable); + frameLabel.setVisible(screenAvailable); + frameControls.setVisible(screenAvailable); + int totalFrames = display.getTotalFrames(); + int currentFrame = display.getCurrentFrame(); + if (currentFrame >= totalFrames) { + currentFrame = totalFrames - 1; + } + int frameRate = display.getFrameRate(); + if (totalFrames == 0) { + progress.setIndeterminate(true); + } else { + progress.setMaximum(totalFrames - 1); + progress.setMinimum(0); + progress.setValue(currentFrame); + progress.setIndeterminate(false); + } + frameLabel.setText(("" + (currentFrame + 1))); + totalFrameLabel.setText("" + totalFrames); + if (frameRate != 0) { + timeLabel.setText("(" + formatMs((currentFrame * 1000) / frameRate) + ")"); + totalTimeLabel.setText("(" + formatMs(((totalFrames - 1) * 1000) / frameRate) + ")"); + } + if (totalFrames <= 1 && playbackControls.isVisible()) { + playbackControls.setVisible(false); + } + if (totalFrames > 1 && !playbackControls.isVisible()) { + playbackControls.setVisible(true); + } + boolean paused1 = !display.isPlaying(); + if (paused1) { + pauseButton.setToolTipText(AppStrings.translate("preview.play")); + pauseButton.setIcon(playIcon); + } else { + pauseButton.setToolTipText(AppStrings.translate("preview.pause")); + pauseButton.setIcon(pauseIcon); } }); @@ -441,6 +460,13 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl } break; + case ACTION_LOOP: + boolean loop = !Configuration.loopMedia.get(); + Configuration.loopMedia.set(loop); + loopButton.setIcon(loop ? loopIcon : noLoopIcon); + display.setLoop(loop); + break; + case ACTION_GOTOFRAME: final JPanel gotoPanel = new JPanel(new BorderLayout()); final JTextField frameField = new JTextField("" + display.getCurrentFrame()); @@ -451,15 +477,10 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl @Override public void ancestorAdded(AncestorEvent event) { final AncestorListener al = this; - View.execInEventDispatchLater(new Runnable() { - - @Override - public void run() { - frameField.selectAll(); - frameField.requestFocusInWindow(); - gotoPanel.removeAncestorListener(al); - - } + View.execInEventDispatchLater(() -> { + frameField.selectAll(); + frameField.requestFocusInWindow(); + gotoPanel.removeAncestorListener(al); }); } @@ -495,18 +516,14 @@ public class PlayerControls extends JPanel implements ActionListener, MediaDispl display.gotoFrame(display.getCurrentFrame() - 1); break; case ACTION_STOP: - display.pause(); - display.rewind(); + display.stop(); break; case ACTION_SELECT_BKCOLOR: - View.execInEventDispatch(new Runnable() { - @Override - public void run() { - Color newColor = JColorChooser.showDialog(null, AppStrings.translate("dialog.selectbkcolor.title"), View.getSwfBackgroundColor()); - if (newColor != null) { - View.setSwfBackgroundColor(newColor); - display.setBackground(newColor); - } + View.execInEventDispatch(() -> { + Color newColor = JColorChooser.showDialog(null, AppStrings.translate("dialog.selectbkcolor.title"), View.getSwfBackgroundColor()); + if (newColor != null) { + View.setSwfBackgroundColor(newColor); + display.setBackground(newColor); } }); break; diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java index 9ade6a7cf..ad31a8578 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java @@ -724,6 +724,29 @@ public class TagTreeModel implements TreeModel { throw new Error("Unsupported parent type: " + parentNode.getClass().getName()); } + public boolean treePathExists(TreePath treePath) { + TreeItem current = null; + for (Object o : treePath.getPath()) { + TreeItem item = (TreeItem) o; + if (current == null) { + if (item != getRoot()) { + return false; + } + + current = item; + } else { + int idx = getIndexOfChild(current, item); + if (idx == -1) { + return false; + } + + current = item; + } + } + + return true; + } + @Override public void addTreeModelListener(TreeModelListener l) { listeners.add(l);