All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.swingx.JXBusyLabel Maven / Gradle / Ivy

The newest version!
/*
 * $Id: JXBusyLabel.java 3502 2009-09-11 01:21:00Z kschaefe $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package org.jdesktop.swingx;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.plaf.LabelUI;

import org.jdesktop.swingx.icon.PainterIcon;
import org.jdesktop.swingx.painter.BusyPainter;
import org.jdesktop.swingx.plaf.BusyLabelAddon;
import org.jdesktop.swingx.plaf.BusyLabelUI;
import org.jdesktop.swingx.plaf.LookAndFeelAddons;

/**
 * 

A simple circular animation, useful for denoting an action is taking * place that may take an unknown length of time to complete. Similar to an * indeterminant JProgressBar, but with a different look.

* *

For example: *


 *     JXFrame frame = new JXFrame("test", true);
 *     JXBusyLabel label = new JXBusyLabel();
 *     frame.add(label);
 *     //...
 *     label.setBusy(true);
 * 

* Another more complicated example: *

 * JXBusyLabel label = new JXBusyLabel(new Dimension(100,84));
 * BusyPainter painter = new BusyPainter(
 * new Rectangle2D.Float(0, 0,13.500001f,1),
 * new RoundRectangle2D.Float(12.5f,12.5f,59.0f,59.0f,10,10));
 * painter.setTrailLength(5);
 * painter.setPoints(31);
 * painter.setFrame(1);
 * label.setPreferredSize(new Dimension(100,84));
 * label.setIcon(new EmptyIcon(100,84));
 * label.setBusyPainter(painter);
 *
* * Another example: *

 *     JXBusyLabel label = new MyBusyLabel(new Dimension(100, 84));
 * 
* * where MyBusyLabel is:
*

 * public class MyBusyLabel extends JXBusyLabel {
 *     public MyBusyLabel(Dimension prefSize) {
 *         super(prefSize);
 *     }
 *     
 *     protected BusyLabel createBusyLabel(Dimension dim) {
 *         BusyPainter painter = new BusyPainter(
 *         new Rectangle2D.Float(0, 0,13.500001f,1),
 *         new RoundRectangle2D.Float(12.5f,12.5f,59.0f,59.0f,10,10));
 *         painter.setTrailLength(5);
 *         painter.setPoints(31);
 *         painter.setFrame(1);
 *         
 *         return painter;
 *     }
 * }
 * 
* * @author rbair * @author joshy * @author rah003 * @author headw01 */ public class JXBusyLabel extends JLabel { private static final long serialVersionUID = 5979268460848257147L; private BusyPainter busyPainter; private Timer busy; private int delay; /** Status flag to save/restore status of timer when moving component between containers. */ private boolean wasBusyOnNotify = false; /** * UI Class ID */ public final static String uiClassID = "BusyLabelUI"; /** * Direction is used to set the initial direction in which the * animation starts. * * @see JXBusyLabel#setDirection(org.jdesktop.swingx.JXBusyLabel.Direction) */ public static enum Direction { /** * cycle proceeds forward */ RIGHT, /** cycle proceeds backward */ LEFT, }; /** * Sets direction of rotation. Direction.RIGHT is the default * value. Direction is taken from the very top point so Direction.RIGHT enables rotation clockwise. * @param dir Direction of rotation. */ public void setDirection(Direction dir) { direction = dir; getBusyPainter().setDirection(dir); } private Direction direction; /** * Creates a default JXLoginPane instance */ static { LookAndFeelAddons.contribute(new BusyLabelAddon()); } { // Initialize the delay from the UI class. BusyLabelUI ui = (BusyLabelUI)getUI(); if (ui != null) { delay = ui.getDelay(); } } /** Creates a new instance of JXBusyLabel initialized to circular shape in bounds of 26 by 26 points.*/ public JXBusyLabel() { this(null); } /** * Creates a new instance of JXBusyLabel initialized to the arbitrary size and using default circular progress indicator. * @param dim Preferred size of the label. */ public JXBusyLabel(Dimension dim) { super(); this.setPreferredSize(dim); // Initialize the BusyPainter. getBusyPainter(); } /** * Initialize the BusyPainter and (this) JXBusyLabel with the given * preferred size. This method is called automatically when the * BusyPainter is set/changed. * * @param dim The new Preferred Size for the BusyLabel. * * @see #getBusyPainter() * @see #setBusyPainter(BusyPainter) */ protected void initPainter(Dimension dim) { BusyPainter busyPainter = getBusyPainter(); // headw01 // TODO: Should we force the busyPainter to NOT be cached? // I think we probably should, otherwise the UI will never // be updated after the first paint. if (null != busyPainter) { busyPainter.setCacheable(false); } PainterIcon icon = new PainterIcon(dim); icon.setPainter(busyPainter); this.setIcon(icon); } /** * Create and return a BusyPpainter to use for the Label. This may * be overridden to return any painter you like. By default, this * method uses the UI (BusyLabelUI)to create a BusyPainter. * @param dim Painter size. * * @see #getUI() */ protected BusyPainter createBusyPainter(Dimension dim) { BusyPainter busyPainter = null; BusyLabelUI ui = (BusyLabelUI)getUI(); if (ui != null) { busyPainter = ui.getBusyPainter(dim); } return busyPainter; } /** *

Gets whether this JXBusyLabel is busy. If busy, then * the JXBusyLabel instance will indicate that it is busy, * generally by animating some state.

* * @return true if this instance is busy */ public boolean isBusy() { return busy != null; } /** *

Sets whether this JXBusyLabel instance should consider * itself busy. A busy component may indicate that it is busy via animation, * or some other means.

* * @param busy whether this JXBusyLabel instance should * consider itself busy */ public void setBusy(boolean busy) { boolean old = isBusy(); if (!old && busy) { startAnimation(); firePropertyChange("busy", old, isBusy()); } else if (old && !busy) { stopAnimation(); firePropertyChange("busy", old, isBusy()); } } private void startAnimation() { if(busy != null) { stopAnimation(); } busy = new Timer(delay, new ActionListener() { BusyPainter busyPainter = getBusyPainter(); int frame = busyPainter.getPoints(); public void actionPerformed(ActionEvent e) { frame = (frame+1)%busyPainter.getPoints(); busyPainter.setFrame(direction == Direction.LEFT ? busyPainter.getPoints() - frame : frame); frameChanged(); } }); busy.start(); } private void stopAnimation() { if (busy != null) { busy.stop(); getBusyPainter().setFrame(-1); repaint(); busy = null; } } @Override public void removeNotify() { // fix for #698 wasBusyOnNotify = isBusy(); // fix for #626 stopAnimation(); super.removeNotify(); } @Override public void addNotify() { super.addNotify(); // fix for #698 if (wasBusyOnNotify) { // fix for #626 startAnimation(); } } protected void frameChanged() { repaint(); } /** * Returns the current BusyPainter. If no BusyPainter is currently * set on this BusyLabel, the {@link #createBusyPainter(Dimension)} * method is called to create one. Afterwards, * {@link #initPainter(Dimension)} is called to update the BusyLabel * with the created BusyPainter. * * @return the busyPainter * * @see #createBusyPainter(Dimension) * @see #initPainter(Dimension) */ public final BusyPainter getBusyPainter() { if (null == busyPainter) { Dimension prefSize = getPreferredSize(); busyPainter = createBusyPainter((prefSize.width == 0 && prefSize.height == 0 && !isPreferredSizeSet()) ? null : prefSize); if (null != busyPainter) { if (!isPreferredSizeSet() && (null == prefSize || prefSize.width == 0 || prefSize.height == 0)) { Rectangle rt = busyPainter.getTrajectory().getBounds(); Rectangle rp = busyPainter.getPointShape().getBounds(); int max = Math.max(rp.width, rp.height); prefSize = new Dimension(rt.width + max, rt.height + max); } initPainter(prefSize); } } return busyPainter; } /** * @param busyPainter the busyPainter to set */ public final void setBusyPainter(BusyPainter busyPainter) { this.busyPainter = busyPainter; initPainter(new Dimension(getIcon().getIconWidth(), getIcon().getIconHeight())); } /** * @return the delay */ public int getDelay() { return delay; } /** * @param delay the delay to set */ public void setDelay(int delay) { int old = getDelay(); this.delay = delay; if (old != getDelay()) { if (busy != null && busy.isRunning()) { busy.setDelay(getDelay()); } firePropertyChange("delay", old, getDelay()); } } //------------------------------------------------------------- UI Logic /** * Notification from the UIManager that the L&F has changed. * Replaces the current UI object with the latest version from the * UIManager. * * @see javax.swing.JComponent#updateUI */ @Override public void updateUI() { setUI((LabelUI) LookAndFeelAddons.getUI(this, BusyLabelUI.class)); } /** * Returns the name of the L&F class that renders this component. * * @return the string {@link #uiClassID} * @see javax.swing.JComponent#getUIClassID * @see javax.swing.UIDefaults#getUI */ @Override public String getUIClassID() { return uiClassID; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy