diff --git a/Growl.iml b/Growl.iml
index abdbaef..65470aa 100644
--- a/Growl.iml
+++ b/Growl.iml
@@ -4,12 +4,14 @@
*
* {@code * Growl.create() @@ -50,26 +51,14 @@ class Growl { public static final int FOREVER = 0; + /** + * Location of the dialog image resources. By default they must be in the 'resources' directory relative to the application + */ + public static String IMAGE_PATH = "resources"; + private static MapimageCache = new HashMap (4); private static Map imageIconCache = new HashMap (4); - String title; - String text; - Pos position = Pos.BOTTOM_RIGHT; - - int hideAfterDurationInMillis = 5000; - boolean hideCloseButton; - boolean isDark = false; - - int screenNumber = Short.MIN_VALUE; - - private Image graphic; - private ActionHandler onAction; - private GrowlPopup growlPopup; - private String name; - private int shakeDurationInMillis = 0; - private int shakeAmplitude = 0; - /** * Builder pattern to create the growl notification. */ @@ -78,6 +67,69 @@ class Growl { return new Growl(); } + /** + * Permits one to override the default images for the dialogs. This is NOT thread safe, and must be performed BEFORE using the GROWL + * system. + * + * The image names are as follows: + *
+ * 'dialog-confirm.png' 'dialog-error.png' 'dialog-information.png' 'dialog-warning.png' + * + * @param imageName the name of the image, either your own if you want want it cached, or one of the above. + * @param image the BufferedImage that you want to cache. + */ + public static + void setImagePath(String imageName, BufferedImage image) { + if (imageCache.containsKey(imageName)) { + throw new RuntimeException("Unable to set an image that already has been set. This action must be done as soon as possible."); + } + + imageCache.put(imageName, image); + } + + private static + BufferedImage getImage(String imageName) { + BufferedImage bufferedImage = imageCache.get(imageName); + InputStream resourceAsStream = null; + try { + if (bufferedImage == null) { + String name = IMAGE_PATH + File.separatorChar + imageName; + + resourceAsStream = LocationResolver.getResourceAsStream(name); + + bufferedImage = ImageIO.read(resourceAsStream); + imageCache.put(imageName, bufferedImage); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (resourceAsStream != null) { + try { + resourceAsStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return bufferedImage; + } + + + String title; + String text; + Pos position = Pos.BOTTOM_RIGHT; + int hideAfterDurationInMillis = 5000; + boolean hideCloseButton; + boolean isDark = false; + int screenNumber = Short.MIN_VALUE; + private Image graphic; + private ActionHandler
onAction; + private GrowlPopup growlPopup; + private String name; + private int shakeDurationInMillis = 0; + private int shakeAmplitude = 0; + private Growl() { } @@ -163,7 +215,7 @@ class Growl { */ public void showWarning() { - name = "/dorkbox/util/growl/dialog-warning.png"; + name = "dialog-warning.png"; graphic(getImage(name)); show(); } @@ -173,7 +225,7 @@ class Growl { */ public void showInformation() { - name = "/dorkbox/util/growl/dialog-information.png"; + name = "dialog-information.png"; graphic(getImage(name)); show(); } @@ -183,7 +235,7 @@ class Growl { */ public void showError() { - name = "/dorkbox/util/growl/dialog-error.png"; + name = "dialog-error.png"; graphic(getImage(name)); show(); } @@ -193,7 +245,7 @@ class Growl { */ public void showConfirm() { - name = "/dorkbox/util/growl/dialog-confirm.png"; + name = "dialog-confirm.png"; graphic(getImage(name)); show(); } @@ -282,7 +334,6 @@ class Growl { }); } - /** * Specifies which screen to display on. If <0, it will show on screen 0. If > max-screens, it will show on the last screen. */ @@ -300,20 +351,5 @@ class Growl { growlPopup = null; graphic = null; } - - private - BufferedImage getImage(String imageName) { - BufferedImage bufferedImage = imageCache.get(imageName); - try { - if (bufferedImage == null) { - bufferedImage = ImageIO.read(Growl.class.getResourceAsStream(imageName)); - imageCache.put(imageName, bufferedImage); - } - } catch (IOException e) { - e.printStackTrace(); - } - - return bufferedImage; - } } diff --git a/src/dorkbox/util/growl/GrowlPopup.java b/src/dorkbox/util/growl/GrowlPopup.java index 7dcc73b..cc2c550 100644 --- a/src/dorkbox/util/growl/GrowlPopup.java +++ b/src/dorkbox/util/growl/GrowlPopup.java @@ -364,7 +364,6 @@ class GrowlPopup extends JFrame { // popups at TOP grow down, popups at BOTTOM grow up int targetY; - if (isShowFromTop(position)) { targetY = anchorY + (popupIndex * (HEIGHT + 10)); } @@ -377,7 +376,7 @@ class GrowlPopup extends JFrame { if (notification.hideAfterDurationInMillis > 0 && hideTween == null) { // begin a timeline to get rid of the popup (default is 5 seconds) - hideTween = Tween.set(this, 0, accessor) + hideTween = Tween.set(this, GrowlPopupAccessor.OPACITY, accessor) .delay(FADE_DURATION + (notification.hideAfterDurationInMillis / 1000.0F)) .target(0) .addCallback(new TweenCallback() { @@ -388,10 +387,10 @@ class GrowlPopup extends JFrame { } }); tweenManager.add(hideTween); - } - if (!timer.isRunning()) { - timer.start(); + if (!timer.isRunning()) { + timer.start(); + } } } } @@ -407,8 +406,28 @@ class GrowlPopup extends JFrame { final int popupIndex = this.popupIndex; final ArrayList growlPopups = popups.get(idAndPosition); int length = growlPopups.size(); + final ArrayList copies = new ArrayList (length); + // if we are the LAST tween, don't adjust anything (since nothing will move anyways) + if (popupIndex == length - 1) { + growlPopups.remove(popupIndex); + + if (tween != null) { + tween.kill(); + } + if (hideTween != null) { + hideTween.kill(); + } + + // if there's nothing left, stop the timer. + if (copies.isEmpty()) { + timer.stop(); + } + return; + } + + int adjustedI = 0; for (int i = 0; i < length; i++) { final GrowlPopup popup = growlPopups.get(i); @@ -418,6 +437,7 @@ class GrowlPopup extends JFrame { } if (i != popupIndex) { + // move the others into the correct position int newPopupIndex = adjustedI++; popup.popupIndex = newPopupIndex; @@ -433,14 +453,15 @@ class GrowlPopup extends JFrame { copies.add(popup); // now animate that popup to it's new location - Tween tween = Tween.to(popup, 1, accessor, MOVE_DURATION) + Tween tween = Tween.to(popup, GrowlPopupAccessor.Y_POS, accessor, MOVE_DURATION) .target((float) changedY) .ease(TweenEquations.Linear); tweenManager.add(tween); popup.tween = tween; - } else { - if (this.hideTween != null) { + } + else { + if (hideTween != null) { hideTween.kill(); } } @@ -453,6 +474,10 @@ class GrowlPopup extends JFrame { if (copies.isEmpty()) { timer.stop(); } + else if (!timer.isRunning()) { + tweenManager.resetUpdateTime(); + timer.start(); + } } } @@ -483,7 +508,7 @@ class GrowlPopup extends JFrame { void shake(final int durationInMillis, final int amplitude) { System.err.println("shake"); - Tween tween = Tween.to(this, 2, accessor, 0.05F) + Tween tween = Tween.to(this, GrowlPopupAccessor.X_Y_POS, accessor, 0.05F) .targetRelative(amplitude, amplitude) .repeatAutoReverse(durationInMillis / 50, 0) .ease(TweenEquations.Linear); diff --git a/src/dorkbox/util/growl/GrowlPopupAccessor.java b/src/dorkbox/util/growl/GrowlPopupAccessor.java index 670d31a..e5c33eb 100644 --- a/src/dorkbox/util/growl/GrowlPopupAccessor.java +++ b/src/dorkbox/util/growl/GrowlPopupAccessor.java @@ -19,6 +19,11 @@ import dorkbox.util.tweenengine.TweenAccessor; class GrowlPopupAccessor implements TweenAccessor { + static final int OPACITY = 0; + static final int Y_POS = 1; + static final int X_Y_POS = 2; + + GrowlPopupAccessor() { } @@ -26,13 +31,13 @@ class GrowlPopupAccessor implements TweenAccessor { public int getValues(final GrowlPopup target, final int tweenType, final float[] returnValues) { switch (tweenType) { - case 0: + case OPACITY: returnValues[0] = target.getOpacity_Compat(); return 1; - case 1: + case Y_POS: returnValues[0] = (float) target.getY(); return 1; - case 2: + case X_Y_POS: returnValues[0] = (float) target.getX(); returnValues[1] = (float) target.getY(); return 2; @@ -44,13 +49,14 @@ class GrowlPopupAccessor implements TweenAccessor { public void setValues(final GrowlPopup target, final int tweenType, final float[] newValues) { switch (tweenType) { - case 0: + case OPACITY: target.setOpacity_Compat(newValues[0]); return; - case 1: + case Y_POS: //noinspection NumericCastThatLosesPrecision target.setY((int) newValues[0]); - case 2: + return; + case X_Y_POS: //noinspection NumericCastThatLosesPrecision target.setLocation((int) newValues[0], (int) newValues[1]); } diff --git a/src/dorkbox/util/growl/WindowUtil_Java7plus.java b/src/dorkbox/util/growl/WindowUtil_Java7plus.java index a99fb05..cc6ad04 100644 --- a/src/dorkbox/util/growl/WindowUtil_Java7plus.java +++ b/src/dorkbox/util/growl/WindowUtil_Java7plus.java @@ -4,9 +4,6 @@ import java.awt.Window; class WindowUtil_Java7plus implements WindowUtil { - String test = "asdasd"; - static String basdasdasd = "asdasdasdasdasd"; - @Override public float getOpacity(final Window window) { diff --git a/src/dorkbox/util/growl/dialog-confirm.png b/src/dorkbox/util/growl/dialog-confirm.png deleted file mode 100644 index adb569b..0000000 Binary files a/src/dorkbox/util/growl/dialog-confirm.png and /dev/null differ diff --git a/src/dorkbox/util/growl/dialog-error.png b/src/dorkbox/util/growl/dialog-error.png deleted file mode 100644 index 769d7df..0000000 Binary files a/src/dorkbox/util/growl/dialog-error.png and /dev/null differ diff --git a/src/dorkbox/util/growl/dialog-information.png b/src/dorkbox/util/growl/dialog-information.png deleted file mode 100644 index a220108..0000000 Binary files a/src/dorkbox/util/growl/dialog-information.png and /dev/null differ diff --git a/src/dorkbox/util/growl/dialog-warning.png b/src/dorkbox/util/growl/dialog-warning.png deleted file mode 100644 index a374f4f..0000000 Binary files a/src/dorkbox/util/growl/dialog-warning.png and /dev/null differ