/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * 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 2 * of the License, or 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.ui.views; import com.jgoodies.animation.Animation; import com.jgoodies.animation.Animations; import com.jgoodies.animation.Animator; import com.jgoodies.animation.animations.BasicTextAnimation; import com.jgoodies.animation.components.BasicTextLabel; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.event.ComponentEvent; import java.awt.event.MouseEvent; import java.util.HashSet; import java.util.Set; import javax.swing.SwingUtilities; import net.miginfocom.swing.MigLayout; import org.jajuk.base.File; import org.jajuk.events.JajukEvent; import org.jajuk.events.JajukEvents; import org.jajuk.events.ObservationManager; import org.jajuk.services.players.QueueModel; import org.jajuk.services.webradio.WebRadio; import org.jajuk.ui.helpers.JajukMouseAdapter; import org.jajuk.ui.windows.JajukMainWindow; import org.jajuk.util.Conf; import org.jajuk.util.Const; import org.jajuk.util.Messages; import org.jajuk.util.UtilFeatures; import org.jajuk.util.UtilString; import org.jajuk.util.error.JajukException; import org.jajuk.util.log.Log; /** * Animation-based view. */ public class AnimationView extends ViewAdapter { /** Generated serialVersionUID. */ private static final long serialVersionUID = 1L; /** The Constant DEFAULT_FRAME_RATE. */ private static final int DEFAULT_FRAME_RATE = 25; /** The Constant DEFAULT_DURATION. */ private static final int DEFAULT_DURATION = 5000; /** The Constant DEFAULT_PAUSE. */ private static final int DEFAULT_PAUSE = 500; /** Current panel width*. */ private int iSize; private BasicTextLabel btl1; private Animator animator; private boolean paused = false; /** * Instantiates a new animation view. */ public AnimationView() { } /* * (non-Javadoc) * * @see org.jajuk.ui.views.IView#getDesc() */ @Override public String getDesc() { return Messages.getString("AnimationView.0"); } /* * (non-Javadoc) * * @see org.jajuk.ui.views.IView#populate() */ @Override public void initUI() { setLayout(new MigLayout("", "[cente,grow]", "[center,grow]")); btl1 = new BasicTextLabel(" "); // Allow to stop animation by left clicking on it btl1.addMouseListener(new JajukMouseAdapter() { @Override public void handleAction(final MouseEvent e) { if (animator != null) { if (paused) { animator.start(); paused = false; } else { animator.stop(); paused = true; } } } }); add(btl1, "grow,center"); // Force initial message refresh UtilFeatures.updateStatus(this); addComponentListener(this); ObservationManager.register(this); } /* (non-Javadoc) * @see org.jajuk.events.Observer#getRegistrationKeys() */ @Override public Set<JajukEvents> getRegistrationKeys() { Set<JajukEvents> eventSubjectSet = new HashSet<JajukEvents>(); eventSubjectSet.add(JajukEvents.FILE_LAUNCHED); eventSubjectSet.add(JajukEvents.WEBRADIO_LAUNCHED); eventSubjectSet.add(JajukEvents.WEBRADIO_INFO_UPDATED); eventSubjectSet.add(JajukEvents.ZERO); eventSubjectSet.add(JajukEvents.PLAYER_STOP); return eventSubjectSet; } /** * Set the text to be displayed*. * * @param sText */ public void setText(final String sText) { SwingUtilities.invokeLater(new Runnable() { // This is mandatory to get actual getWitdth @Override public void run() { // Make sure to stop any animation if (animator != null) { animator.stop(); } btl1.setText(""); iSize = AnimationView.this.getWidth(); Font font = null; // Find optimal target font size boolean bOk = false; int i = 40; while (!bOk) { font = new Font("verdana", Font.BOLD, i); FontMetrics fontMetrics = JajukMainWindow.getInstance().getFontMetrics(font); int iFontSize = SwingUtilities.computeStringWidth(fontMetrics, sText); if (iFontSize <= iSize - 150) { bOk = true; } else { i--; } } btl1.setFont(font); Animation animPause = Animations.pause(DEFAULT_PAUSE); Animation anim = null; // Select a random animation or fade animation if no animation (because // we want to make sure that long labels are not cut after animation stop) if (!Conf.getBoolean(Const.CONF_TITLE_ANIMATION)) { anim = BasicTextAnimation.defaultFade(btl1, DEFAULT_DURATION, sText, Color.darkGray); } else { int iShuffle = (int) (Math.random() * 3); //NOSONAR switch (iShuffle) { case 0: anim = BasicTextAnimation.defaultScale(btl1, DEFAULT_DURATION, sText, Color.darkGray); break; case 1: anim = BasicTextAnimation.defaultSpace(btl1, DEFAULT_DURATION, sText, Color.darkGray); break; case 2: anim = BasicTextAnimation.defaultFade(btl1, DEFAULT_DURATION, sText, Color.darkGray); break; } } Animation animAll = Animations.sequential(anim, animPause); anim = Animations.repeat(Float.POSITIVE_INFINITY, animAll); animator = new Animator(anim, DEFAULT_FRAME_RATE); animator.start(); if (!Conf.getBoolean(Const.CONF_TITLE_ANIMATION)) { // Stop animation after few seconds if still the same label new Thread() { @Override public void run() { String title = sText; try { Thread.sleep(3000); } catch (InterruptedException e) { Log.error(e); } if (btl1.getText().equals(title) && animator != null) { animator.stop(); } } }.start(); } } }); } /* * (non-Javadoc) * * @see org.jajuk.ui.Observer#update(java.lang.String) */ @Override public void update(JajukEvent event) { JajukEvents subject = event.getSubject(); if (subject.equals(JajukEvents.FILE_LAUNCHED)) { File file = QueueModel.getPlayingFile(); if (file != null) { String s = ""; try { s = UtilString.applyPattern(file, Conf.getString(Const.CONF_PATTERN_ANIMATION), false, false); } catch (JajukException e) { Log.error(e); } setText(s); } } else if (subject.equals(JajukEvents.ZERO) || subject.equals(JajukEvents.PLAYER_STOP)) { setText(Messages.getString("JajukWindow.18")); } else if (subject.equals(JajukEvents.WEBRADIO_LAUNCHED)) { WebRadio radio = (WebRadio) event.getDetails().get(Const.DETAIL_CONTENT); if (radio != null) { setText(radio.getName()); } } else if (subject.equals(JajukEvents.WEBRADIO_INFO_UPDATED)) { String webradioInfo = (String) event.getDetails().get(Const.CURRENT_RADIO_TRACK); if (webradioInfo != null) { setText(webradioInfo); } } } /* * (non-Javadoc) * * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent) */ @Override public void componentResized(ComponentEvent e) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { iSize = SwingUtilities.getRootPane(AnimationView.this).getWidth(); UtilFeatures.updateStatus(AnimationView.this); } }); } /* (non-Javadoc) * @see org.jajuk.ui.views.ViewAdapter#cleanup() */ @Override public void cleanup() { // make sure animation is stopped if (animator != null) { animator.stop(); animator = null; } super.cleanup(); } }