diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java index 570af36b8..ef42c8ad8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java @@ -109,7 +109,7 @@ public class BEVELFILTER extends FILTER { } else if (!innerShadow) { type = Filtering.OUTER; } - return Filtering.bevel(src, (int) blurX, (int) blurY, strength, type, highlightColor.toColor(), shadowColor.toColor(), (int) (angle * 180 / Math.PI), (float) distance, knockout, passes); + return Filtering.bevel(src, (int) blurX, (int) blurY, strength, type, highlightColor.toInt(), shadowColor.toInt(), (int) (angle * 180 / Math.PI), (float) distance, knockout, passes); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java index 2f6473370..fefcac350 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.types.filters; +import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.helpers.SerializableImage; import java.awt.AlphaComposite; import java.awt.Color; @@ -43,9 +44,20 @@ public class Filtering { public static final int FULL = 3; - private static void boxBlurHorizontal(int[] pixels, int[] mask, int w, int h, int radius) { + private static final Color ALPHA = new Color(0, 0, 0, 0); + + private static final Point POINT_0_0 = new Point(0, 0); + + private static final Point POINT_255_0 = new Point(255, 0); + + private static final Point POINT_511_0 = new Point(511, 0); + + private static final Rectangle RECTANGLE_256_1 = new Rectangle(256, 1); + + private static final Rectangle RECTANGLE_512_1 = new Rectangle(256, 1); + + private static void boxBlurHorizontal(int[] pixels, int[] mask, int[] newColors, int w, int h, int radius) { int index = 0; - int[] newColors = new int[w]; for (int y = 0; y < h; y++) { int hits = 0; @@ -89,7 +101,7 @@ public class Filtering { if (hits == 0) { newColors[x] = 0; } else { - newColors[x] = new Color((int) (r / hits) & 0xff, (int) (g / hits) & 0xff, (int) (b / hits) & 0xff, (int) (a / hits)).getRGB(); + newColors[x] = RGBA.toInt((int) (r / hits) & 0xff, (int) (g / hits) & 0xff, (int) (b / hits) & 0xff, (int) (a / hits)); } } else { @@ -97,14 +109,14 @@ public class Filtering { } } } + System.arraycopy(newColors, 0, pixels, index, w); index += w; } } - private static void boxBlurVertical(int[] pixels, int[] mask, int w, int h, int radius) { - int[] newColors = new int[h]; + private static void boxBlurVertical(int[] pixels, int[] mask, int[] newColors, int w, int h, int radius) { int oldPixelOffset = -(radius + 1) * w; int newPixelOffset = (radius) * w; @@ -152,7 +164,7 @@ public class Filtering { if (hits == 0) { newColors[y] = 0; } else { - newColors[y] = new Color((int) (r / hits) & 0xff, (int) (g / hits) & 0xff, (int) (b / hits) & 0xff, (int) (a / hits) & 0xff).getRGB(); + newColors[y] = RGBA.toInt((int) (r / hits) & 0xff, (int) (g / hits) & 0xff, (int) (b / hits) & 0xff, (int) (a / hits) & 0xff); } } else { newColors[y] = 0; @@ -230,19 +242,21 @@ public class Filtering { int[] inPixels = src; premultiply(inPixels); + int[] tempRow = new int[width]; + int[] tempColumn = new int[height]; for (int i = 0; i < iterations; i++) { - boxBlurHorizontal(inPixels, mask, width, height, hRadius / 2); - boxBlurVertical(inPixels, mask, width, height, vRadius / 2); + boxBlurHorizontal(inPixels, mask, tempRow, width, height, hRadius / 2); + boxBlurVertical(inPixels, mask, tempColumn, width, height, vRadius / 2); } unpremultiply(inPixels); } - public static SerializableImage bevel(SerializableImage src, int blurX, int blurY, float strength, int type, Color highlightColor, Color shadowColor, float angle, float distance, boolean knockout, int iterations) { + public static SerializableImage bevel(SerializableImage src, int blurX, int blurY, float strength, int type, int highlightColor, int shadowColor, float angle, float distance, boolean knockout, int iterations) { return new SerializableImage(gradientBevel(src.getBufferedImage(), new Color[]{ - shadowColor, - new Color(shadowColor.getRed(), shadowColor.getGreen(), shadowColor.getBlue(), 0), - new Color(highlightColor.getRed(), highlightColor.getGreen(), highlightColor.getBlue(), 0), - highlightColor + new Color(shadowColor, true), + new Color(shadowColor & 0x00ffffff, true), + new Color(highlightColor & 0x00ffffff, true), + new Color(highlightColor, true) }, new float[]{0, 127f / 255f, 128f / 255f, 1}, blurX, blurY, strength, type, angle, distance, knockout, iterations)); } @@ -264,10 +278,10 @@ public class Filtering { BufferedImage gradient = new BufferedImage(512, 1, src.getType()); Graphics2D gg = gradient.createGraphics(); - Point p1 = new Point(0, 0); - Point p2 = new Point(511, 0); + Point p1 = POINT_0_0; + Point p2 = POINT_511_0; gg.setPaint(new LinearGradientPaint(p1, p2, ratios, colors)); - gg.fill(new Rectangle(512, 1)); + gg.fill(RECTANGLE_512_1); int[] gradientPixels = getRGB(gradient); BufferedImage shadowInner = null; @@ -352,8 +366,8 @@ public class Filtering { blur(ret, width, height, blurX, blurY, iterations, mask); for (int i = 0; i < srcPixels.length; i++) { - int ah = (int) (new Color(ret[i]).getRed() * strength); - int as = (int) (new Color(ret[i]).getBlue() * strength); + int ah = (int) (((ret[i] >> 16) & 0xFF) * strength); + int as = (int) ((ret[i] & 0xFF) * strength); int ra = cut(ah - as, -255, 255); ret[i] = gradientPixels[255 + ra]; } @@ -396,11 +410,12 @@ public class Filtering { if (inner) { alpha = 255 - alpha; } - shadow[i] = new Color(color.getRed(), color.getGreen(), color.getBlue(), cut(color.getAlpha() * alpha / 255 * strength)).getRGB(); + + shadow[i] = RGBA.toInt(color.getRed(), color.getGreen(), color.getBlue(), cut(color.getAlpha() * alpha / 255 * strength)); } Color colorFirst = Color.BLACK; - Color colorAlpha = new Color(0, 0, 0, 0); + Color colorAlpha = ALPHA; double angleRad = angle / 180 * Math.PI; double moveX = (distance * Math.cos(angleRad)); double moveY = (distance * Math.sin(angleRad)); @@ -441,10 +456,10 @@ public class Filtering { BufferedImage gradCanvas = new BufferedImage(256, 1, src.getType()); Graphics2D gg = gradCanvas.createGraphics(); - Point p1 = new Point(0, 0); - Point p2 = new Point(255, 0); + Point p1 = POINT_0_0; + Point p2 = POINT_255_0; gg.setPaint(new LinearGradientPaint(p1, p2, ratios, colors)); - gg.fill(new Rectangle(256, 1)); + gg.fill(RECTANGLE_256_1); int[] gradientPixels = getRGB(gradCanvas); double angleRad = angle / 180 * Math.PI; @@ -461,7 +476,7 @@ public class Filtering { shadow[i] = 0 + ((cut(strength * ((srcPixels[i] >> 24) & 0xff))) << 24); } - Color colorAlpha = new Color(0, 0, 0, 0); + Color colorAlpha = ALPHA; shadow = moveRGB(width, height, shadow, moveX, moveY, colorAlpha); int[] mask = null; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java index af23ea9c1..b859675c0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java @@ -114,10 +114,11 @@ public class GRADIENTBEVELFILTER extends FILTER { colors.add(gradientColors[i].toColor()); ratios.add(gradientRatio[i] / 255f); } - float[] ratiosAr = new float[ratios.size()]; + float[] ratiosArr = new float[ratios.size()]; for (int i = 0; i < ratios.size(); i++) { - ratiosAr[i] = ratios.get(i); + ratiosArr[i] = ratios.get(i); } + Color[] colorsArr = colors.toArray(new Color[colors.size()]); int type = Filtering.INNER; if (onTop && !innerShadow) { @@ -126,7 +127,7 @@ public class GRADIENTBEVELFILTER extends FILTER { type = Filtering.OUTER; } - return Filtering.gradientBevel(src, colorsArr, ratiosAr, (int) blurX, (int) blurY, strength, type, (int) (angle * 180 / Math.PI), (float) distance, knockout, passes); + return Filtering.gradientBevel(src, colorsArr, ratiosArr, (int) blurX, (int) blurY, strength, type, (int) (angle * 180 / Math.PI), (float) distance, knockout, passes); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index 87e0c60ef..511e0a636 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -1,346 +1,347 @@ -/* - * Copyright (C) 2010-2015 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.gui.player; - -import com.jpexs.decompiler.flash.gui.FlashUnsupportedException; -import com.jpexs.decompiler.flash.gui.Main; -import com.jpexs.javactivex.ActiveX; -import com.jpexs.javactivex.ActiveXEvent; -import com.jpexs.javactivex.ActiveXException; -import com.jpexs.javactivex.example.controls.flash.ShockwaveFlash; -import com.sun.jna.Platform; -import java.awt.AWTException; -import java.awt.Color; -import java.awt.Component; -import java.awt.Panel; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Robot; -import java.awt.image.BufferedImage; -import java.io.Closeable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * - * @author JPEXS - */ -public final class FlashPlayerPanel extends Panel implements Closeable, MediaDisplay { - - private final List listeners = new ArrayList<>(); - - private final ShockwaveFlash flash; - - private final Timer timer; - - private boolean stopped = true; - - private int frameRate; - - @Override - public boolean loopAvailable() { - return false; - } - - @Override - public boolean screenAvailable() { - return true; - } - - @Override - public boolean zoomAvailable() { - return true; - } - - @Override - public double getZoomToFit() { - //TODO - return 1; - } - - @Override - public Zoom getZoom() { - return null; - } - - private double zoom = 1.0; - - @Override - public synchronized void zoom(Zoom zoom) { - double zoomDouble = zoom.fit ? getZoomToFit() : zoom.value; - int zoomint = (int) Math.round(100 / (zoomDouble / this.zoom)); - if (zoomint == 0) { - zoomint = 1; - } - if (zoomint > 32767) { - zoomint = 32767; - } - if (zoomint == 100) { - zoomint = 0; - } - flash.Zoom(0); // hack, but this call is needed otherwise unzoom will fail for larger zoom values - flash.Zoom(zoomint); - } - - public synchronized String getVariable(String name) throws IOException { - return flash.GetVariable(name); - } - - public synchronized void setVariable(String name, String value) throws IOException { - flash.SetVariable(name, value); - } - - public synchronized String call(String callString) throws IOException { - - return flash.CallFunction(callString); - } - - @Override - public synchronized int getCurrentFrame() { - if (flash == null) { - return 0; - } - try { - return flash.getFrameNum(); - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - } - return 0; - } - - @Override - public synchronized int getTotalFrames() { - if (flash == null) { - return 0; - } - try { - if (flash.getReadyState() == 4) { - return flash.getTotalFrames(); - } - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - } - return 0; - } - - @Override - public synchronized void setBackground(Color color) { - try { - flash.setBackgroundColor((color.getRed() << 16) + (color.getGreen() << 8) + color.getBlue()); - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - } - } - - public FlashPlayerPanel(Component frame) { - if (!Platform.isWindows()) { - throw new FlashUnsupportedException(); - } - - try { - flash = ActiveX.createObject(ShockwaveFlash.class, this); - } catch (ActiveXException ex) { - throw new FlashUnsupportedException(); - } - - flash.setAllowScriptAccess("always"); - flash.setAllowNetworking("all"); - flash.addOnReadyStateChangeListener((ActiveXEvent axe) -> { - fireMediaDisplayStateChanged(); - }); - - flash.addFlashCallListener((ActiveXEvent axe) -> { - String req = (String) axe.args.get("request"); - Matcher m = Pattern.compile("(.*)").matcher(req); - if (m.matches()) { - String funname = m.group(1); - String msg = m.group(2); - if (funname.equals("alert") || funname.equals("console.log")) { - if (Main.debugDialog != null) { - Main.debugDialog.log(funname + ":" + msg); - } - } - } - }); - - timer = new Timer(); - timer.schedule(new TimerTask() { - - private boolean isPlaying = false; - - private int currentFrame = 0; - - @Override - public void run() { - - try { - ShockwaveFlash flash1 = flash; - - boolean changed = false; - - boolean isPlaying = flash1.IsPlaying(); - if (this.isPlaying != isPlaying) { - this.isPlaying = isPlaying; - } - - int currentFrame = flash1.CurrentFrame(); - if (this.currentFrame != currentFrame) { - this.currentFrame = currentFrame; - changed = true; - } - - if (changed) { - fireMediaDisplayStateChanged(); - } - } catch (Exception ex) { - // ignore - cancel(); - } - } - }, 100, 100); - } - - public synchronized void stopSWF() { - displaySWF("-", null, 1); - stopped = true; - fireMediaDisplayStateChanged(); - } - - public synchronized boolean isStopped() { - return stopped; - } - - @Override - public BufferedImage printScreen() { - Point screenloc = getLocationOnScreen(); - try { - return new Robot().createScreenCapture(new Rectangle(screenloc.x, screenloc.y, getWidth(), getHeight())); - } catch (AWTException ex) { - return null; - } - } - - public synchronized void displaySWF(String flashName, Color bgColor, int frameRate) { - - zoom = 1.0; - this.frameRate = frameRate; - if (bgColor != null) { - setBackground(bgColor); - } - flash.setMovie(flashName); - //play - stopped = false; - fireMediaDisplayStateChanged(); - } - - @Override - public void close() throws IOException { - - } - - public void unload() { - timer.cancel(); - } - - @Override - public void pause() { - try { - flash.Stop(); - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - } - } - - @Override - public void stop() { - try { - flash.Stop(); - flash.Rewind(); - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - } - } - - @Override - public void rewind() { - try { - flash.Rewind(); - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - } - } - - @Override - public void play() { - try { - flash.Play(); - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - } - } - - @Override - public boolean isPlaying() { - try { - return flash.IsPlaying(); - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - return false; - } - } - - @Override - public void setLoop(boolean loop) { - } - - @Override - public void gotoFrame(int frame) { - if (frame < 0) { - return; - } - if (frame >= getTotalFrames()) { - return; - } - try { - flash.GotoFrame(frame); - } catch (ActiveXException ex) { // Can be "Data not available yet exception" - } - } - - @Override - public int getFrameRate() { - return frameRate; - } - - @Override - public boolean isLoaded() { - return !isStopped(); - } - - public void fireMediaDisplayStateChanged() { - for (MediaDisplayListener l : listeners) { - l.mediaDisplayStateChanged(this); - } - } - - @Override - public void addEventListener(MediaDisplayListener listener) { - listeners.add(listener); - } - - @Override - public void removeEventListener(MediaDisplayListener listener) { - listeners.remove(listener); - } -} +/* + * Copyright (C) 2010-2015 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui.player; + +import com.jpexs.decompiler.flash.gui.FlashUnsupportedException; +import com.jpexs.decompiler.flash.gui.Main; +import com.jpexs.javactivex.ActiveX; +import com.jpexs.javactivex.ActiveXEvent; +import com.jpexs.javactivex.ActiveXException; +import com.jpexs.javactivex.example.controls.flash.ShockwaveFlash; +import com.sun.jna.Platform; +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Component; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author JPEXS + */ +public final class FlashPlayerPanel extends Panel implements Closeable, MediaDisplay { + + private final List listeners = new ArrayList<>(); + + private final ShockwaveFlash flash; + + private final Timer timer; + + private boolean stopped = true; + + private int frameRate; + + @Override + public boolean loopAvailable() { + return false; + } + + @Override + public boolean screenAvailable() { + return true; + } + + @Override + public boolean zoomAvailable() { + return true; + } + + @Override + public double getZoomToFit() { + //TODO + return 1; + } + + @Override + public Zoom getZoom() { + return null; + } + + private double zoom = 1.0; + + @Override + public synchronized void zoom(Zoom zoom) { + double zoomDouble = zoom.fit ? getZoomToFit() : zoom.value; + int zoomint = (int) Math.round(100 / (zoomDouble / this.zoom)); + if (zoomint == 0) { + zoomint = 1; + } + if (zoomint > 32767) { + zoomint = 32767; + } + if (zoomint == 100) { + zoomint = 0; + } + + flash.Zoom(0); // hack, but this call is needed otherwise unzoom will fail for larger zoom values + flash.Zoom(zoomint); + } + + public synchronized String getVariable(String name) throws IOException { + return flash.GetVariable(name); + } + + public synchronized void setVariable(String name, String value) throws IOException { + flash.SetVariable(name, value); + } + + public synchronized String call(String callString) throws IOException { + + return flash.CallFunction(callString); + } + + @Override + public synchronized int getCurrentFrame() { + if (flash == null) { + return 0; + } + try { + return flash.getFrameNum(); + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + } + return 0; + } + + @Override + public synchronized int getTotalFrames() { + if (flash == null) { + return 0; + } + try { + if (flash.getReadyState() == 4) { + return flash.getTotalFrames(); + } + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + } + return 0; + } + + @Override + public synchronized void setBackground(Color color) { + try { + flash.setBackgroundColor((color.getRed() << 16) + (color.getGreen() << 8) + color.getBlue()); + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + } + } + + public FlashPlayerPanel(Component frame) { + if (!Platform.isWindows()) { + throw new FlashUnsupportedException(); + } + + try { + flash = ActiveX.createObject(ShockwaveFlash.class, this); + } catch (ActiveXException ex) { + throw new FlashUnsupportedException(); + } + + flash.setAllowScriptAccess("always"); + flash.setAllowNetworking("all"); + flash.addOnReadyStateChangeListener((ActiveXEvent axe) -> { + fireMediaDisplayStateChanged(); + }); + + flash.addFlashCallListener((ActiveXEvent axe) -> { + String req = (String) axe.args.get("request"); + Matcher m = Pattern.compile("(.*)").matcher(req); + if (m.matches()) { + String funname = m.group(1); + String msg = m.group(2); + if (funname.equals("alert") || funname.equals("console.log")) { + if (Main.debugDialog != null) { + Main.debugDialog.log(funname + ":" + msg); + } + } + } + }); + + timer = new Timer(); + timer.schedule(new TimerTask() { + + private boolean isPlaying = false; + + private int currentFrame = 0; + + @Override + public void run() { + + try { + ShockwaveFlash flash1 = flash; + + boolean changed = false; + + boolean isPlaying = flash1.IsPlaying(); + if (this.isPlaying != isPlaying) { + this.isPlaying = isPlaying; + } + + int currentFrame = flash1.CurrentFrame(); + if (this.currentFrame != currentFrame) { + this.currentFrame = currentFrame; + changed = true; + } + + if (changed) { + fireMediaDisplayStateChanged(); + } + } catch (Exception ex) { + // ignore + cancel(); + } + } + }, 100, 100); + } + + public synchronized void stopSWF() { + displaySWF("-", null, 1); + stopped = true; + fireMediaDisplayStateChanged(); + } + + public synchronized boolean isStopped() { + return stopped; + } + + @Override + public BufferedImage printScreen() { + Point screenloc = getLocationOnScreen(); + try { + return new Robot().createScreenCapture(new Rectangle(screenloc.x, screenloc.y, getWidth(), getHeight())); + } catch (AWTException ex) { + return null; + } + } + + public synchronized void displaySWF(String flashName, Color bgColor, int frameRate) { + + zoom = 1.0; + this.frameRate = frameRate; + if (bgColor != null) { + setBackground(bgColor); + } + flash.setMovie(flashName); + //play + stopped = false; + fireMediaDisplayStateChanged(); + } + + @Override + public void close() throws IOException { + + } + + public void unload() { + timer.cancel(); + } + + @Override + public void pause() { + try { + flash.Stop(); + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + } + } + + @Override + public void stop() { + try { + flash.Stop(); + flash.Rewind(); + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + } + } + + @Override + public void rewind() { + try { + flash.Rewind(); + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + } + } + + @Override + public void play() { + try { + flash.Play(); + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + } + } + + @Override + public boolean isPlaying() { + try { + return flash.IsPlaying(); + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + return false; + } + } + + @Override + public void setLoop(boolean loop) { + } + + @Override + public void gotoFrame(int frame) { + if (frame < 0) { + return; + } + if (frame >= getTotalFrames()) { + return; + } + try { + flash.GotoFrame(frame); + } catch (ActiveXException | NullPointerException ex) { // Can be "Data not available yet exception" + } + } + + @Override + public int getFrameRate() { + return frameRate; + } + + @Override + public boolean isLoaded() { + return !isStopped(); + } + + public void fireMediaDisplayStateChanged() { + for (MediaDisplayListener l : listeners) { + l.mediaDisplayStateChanged(this); + } + } + + @Override + public void addEventListener(MediaDisplayListener listener) { + listeners.add(listener); + } + + @Override + public void removeEventListener(MediaDisplayListener listener) { + listeners.remove(listener); + } +}