/*
* Copyright 2011 Luke Usherwood.
*
* This program 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 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.bettyluke.swing;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class StatusWidget {
public class HalfSizeIcon implements Icon {
private Icon original;
public HalfSizeIcon(Icon icon) {
original = icon;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D gfx = (Graphics2D) g.create();
gfx.scale(0.5, 0.5);
gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
gfx.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
original.paintIcon(c, gfx, x*2, y);
}
@Override
public int getIconWidth() {
return original.getIconWidth() / 2;
}
@Override
public int getIconHeight() {
return original.getIconWidth() / 2;
}
}
public static final Icon BUSY_IMAGE = new ImageIcon(
StatusWidget.class.getResource("res/animated-wait.gif"));
private JLabel label = new JLabel();
private boolean isErrorDisplayed;
public StatusWidget() {
label.setVisible(false);
label.setHorizontalTextPosition(SwingConstants.LEFT);
}
public JComponent getComponent() {
return label;
}
public void hide() {
label.setToolTipText(null);
label.setIcon(null);
clearActions();
label.setVisible(false);
}
public void clearActions() {
isErrorDisplayed = false;
label.setCursor(null);
Arrays.stream(label.getMouseListeners()).forEach(label::removeMouseListener);
}
public void showBusy(String labelText, String toolTipText) {
label.setText(labelText);
label.setToolTipText(toolTipText);
label.setIcon(BUSY_IMAGE);
clearActions();
label.setVisible(true);
label.repaint();
}
public void showRetryError(String labelText, String toolTipText, Runnable task) {
showError(labelText, toolTipText);
label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
label.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
SwingUtilities.invokeLater(task);
}
});
}
public void showError(String labelText, String toolTipText) {
clearActions();
isErrorDisplayed = true;
label.setText(labelText);
label.setToolTipText(toolTipText);
label.setIcon(new HalfSizeIcon(UIManager.getIcon("OptionPane.errorIcon")));
label.setVisible(true);
}
public void showWarning(String labelText, String toolTipText) {
// DIRTY HACK!! Avoid overriding an error with a warning.
// TODO: Implement proper 'model / view' for the status. Perhaps in SiteData?
if (!isErrorDisplayed) {
clearActions();
label.setText(labelText);
label.setToolTipText(toolTipText);
label.setIcon(new HalfSizeIcon(UIManager.getIcon("OptionPane.warningIcon")));
label.setVisible(true);
}
}
}