/* * Copyright (C) 2006 Sun Microsystems, Inc. All rights reserved. * Copyright (C) 2011 Peransin Nicolas. * Use is subject to license terms. */ package org.mypsycho.swing.app.beans; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JSeparator; import javax.swing.Timer; import org.mypsycho.swing.app.Application; import org.mypsycho.swing.app.beans.TaskMonitor; import org.mypsycho.swing.app.task.Task; /** * A StatusBar panel that tracks a TaskMonitor. * </p> * Although one could certainly create a more elaborate StatusBar class, * this one is sufficient for the examples that need one. * </p> */ @SuppressWarnings("serial") public class StatusBar extends JPanel implements PropertyChangeListener { private static final Insets ZERO_INSET = new Insets(0,0,0,0); private final JLabel messageLabel = new JLabel() ; private final JProgressBar progressBar = new JProgressBar(0, 100); private final JLabel statusAnimationLabel = new JLabel(); private final Timer messageTimer = new Timer(5000, new ClearOldMessage()); private final Timer busyIconTimer = new Timer(50, new UpdateBusyIcon()); private Icon idleIcon; private final Icon[] busyIcons = new Icon[15]; // private int busyAnimationRate; private int busyIconIndex = 0; /** * Constructs a panel that displays messages/progress/state * properties of the {@code taskMonitor's} foreground task. * * @param taskMonitor the {@code TaskMonitor} whose * {@code PropertyChangeEvents} {@code this StatusBar} will track. */ public StatusBar(Application app, TaskMonitor taskMonitor) { super(new GridBagLayout()); messageTimer.setRepeats(false); progressBar.setEnabled(false); statusAnimationLabel.setIcon(idleIcon); GridBagConstraints c = new GridBagConstraints(); initGridBagConstraints(c); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; add(new JSeparator(), c); initGridBagConstraints(c); c.insets = new Insets(6, 6, 0, 3); // top, left, bottom, right; c.weightx = 1.0; c.fill = GridBagConstraints.HORIZONTAL; add(messageLabel, c); initGridBagConstraints(c); c.insets = new Insets(6, 3, 0, 3); // top, left, bottom, right; add(progressBar, c); initGridBagConstraints(c); c.insets = new Insets(6, 3, 0, 6); // top, left, bottom, right; add(statusAnimationLabel, c); taskMonitor.addPropertyChangeListener(this); } /** * Returns the idleIcon. * * @return the idleIcon */ public Icon getIdleIcon() { return idleIcon; } /** * Sets the idleIcon. * * @param idleIcon the idleIcon to set */ public void setIdleIcon(Icon idleIcon) { this.idleIcon = idleIcon; if (statusAnimationLabel.getIcon() == null) { statusAnimationLabel.setIcon(idleIcon); } } public void setMessage(String s) { messageLabel.setText((s == null) ? "" : s); messageTimer.restart(); } public String getMessage() { return messageLabel.getText(); } private void initGridBagConstraints(GridBagConstraints c) { c.anchor = GridBagConstraints.CENTER; c.fill = GridBagConstraints.NONE; c.gridwidth = 1; c.gridheight = 1; c.gridx = GridBagConstraints.RELATIVE; c.gridy = GridBagConstraints.RELATIVE; c.insets = ZERO_INSET; c.ipadx = 0; c.ipady = 0; c.weightx = 0.0; c.weighty = 0.0; } private class ClearOldMessage implements ActionListener { public void actionPerformed(ActionEvent e) { messageLabel.setText(""); } } private class UpdateBusyIcon implements ActionListener { public void actionPerformed(ActionEvent e) { busyIconIndex = (busyIconIndex + 1) % busyIcons.length; statusAnimationLabel.setIcon(busyIcons[busyIconIndex]); } } public void showBusyAnimation() { if (!busyIconTimer.isRunning()) { statusAnimationLabel.setIcon(busyIcons[0]); busyIconIndex = 0; busyIconTimer.start(); } } public void stopBusyAnimation() { busyIconTimer.stop(); statusAnimationLabel.setIcon(idleIcon); } /** * The TaskMonitor (constructor arg) tracks a "foreground" task; * this method is called each time a foreground task property * changes. */ public void propertyChange(PropertyChangeEvent e) { String propertyName = e.getPropertyName(); if (Task.StateValue.STARTED.name().equalsIgnoreCase(propertyName)) { showBusyAnimation(); progressBar.setEnabled(true); progressBar.setIndeterminate(true); } else if (Task.StateValue.DONE.name().equalsIgnoreCase(propertyName)) { stopBusyAnimation(); progressBar.setIndeterminate(false); progressBar.setEnabled(false); progressBar.setValue(0); } else if (Task.MESSAGE_PROP.equals(propertyName)) { String text = (String)(e.getNewValue()); setMessage(text); } else if (Task.PROGRESS_PROP.equals(propertyName)) { int value = (Integer)(e.getNewValue()); progressBar.setEnabled(true); progressBar.setIndeterminate(false); progressBar.setValue(value); } } /** * Returns the busyIcons. * * @return the busyIcons */ public Icon[] getBusyIcons() { return busyIcons; } /** * Returns the busyAnimationRate. * * @return the busyAnimationRate */ public int getBusyAnimationRate() { return busyIconTimer.getDelay(); } /** * Sets the busyAnimationRate. * * @param busyAnimationRate the busyAnimationRate to set */ public void setBusyAnimationRate(int busyAnimationRate) { this.busyIconTimer.setDelay(busyAnimationRate); } /** * Returns the messageTimeout. * * @return the messageTimeout */ public int getMessageTimeout() { return messageTimer.getDelay(); } /** * Sets the messageTimeout. * * @param messageTimeout the messageTimeout to set */ public void setMessageTimeout(int messageTimeout) { messageTimer.setDelay(messageTimeout); } }