void (boolean forward, final JLayeredPane layeredPane, final @Nullable Runnable onDone) { if (myAnimator != null) { Disposer.dispose(myAnimator); } myAnimator = new Animator("Balloon", 8, isAnimationEnabled() ? myAnimationCycle : 0, false, forward) { @Override public void paintNow(final int frame, final int totalFrames, final int cycle) { if (component == null || component.getParent() == null || !isAnimationEnabled()) return; component.setAlpha((float)frame / totalFrames); } @Override protected void paintCycleEnd() { if (component == null || component.getParent() == null) return; if (isForward()) { component.clear(); component.repaint(); myFadedIn = true; if (!myFadeoutAlarm.isDisposed()) { startFadeoutTimer((int)myFadeoutTime); } } else { layeredPane.remove(component); layeredPane.revalidate(); layeredPane.repaint(); } Disposer.dispose(this); } @Override public void dispose() { super.dispose(); myAnimator = null; if (onDone != null) { onDone.run(); } } }; myAnimator.resume(); }