/* * Beanfabrics Framework Copyright (C) by Michael Karneim, beanfabrics.org * Use is subject to license terms. See license.txt. */ // TODO javadoc - remove this comment only when the class and all non-public // methods and fields are documented package org.beanfabrics.swing; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.Point; import java.awt.image.ImageObserver; import java.io.Serializable; import java.net.URL; import javax.swing.ImageIcon; import javax.swing.SwingConstants; /** * The {@link ErrorIconPainter} is a helper class for painting an error icon on * top of any component. * * @author Michael Karneim */ public class ErrorIconPainter implements Serializable { private static final URL ERROR_ICON = ErrorIconPainter.class.getResource("error_overlay.gif"); // TODO configure via file private static final URL ERROR_ICON_FOCUSED = ErrorIconPainter.class.getResource("error_overlay.gif"); // TODO configure via file private ImageIcon errorIcon; private ImageIcon errorIconFocused; private Insets margin = new Insets(2, 4, 2, 4); private int horizontalAlignment = SwingConstants.RIGHT; private int verticalAlignment = SwingConstants.CENTER; private Point offset = new Point(0, 0); private Dimension dimension; /** * Creates a new {@link ErrorIconPainter} with the default settings. */ public ErrorIconPainter() { errorIcon = new ImageIcon(ERROR_ICON); errorIconFocused = new ImageIcon(ERROR_ICON_FOCUSED); updateDimension(); } /** * Returns the margin of the error icon. * * @return */ public Insets getMargin() { return margin; } /** * Sets the margin of the error icon. * * @param margin */ public void setMargin(Insets margin) { if (margin == null) { throw new IllegalArgumentException("margin==null"); } this.margin = margin; } /** * Returns the horizontal alignment of the icon. * * @return the horizontal alignment of the icon. */ public int getHorizontalAlignment() { return horizontalAlignment; } /** * Sets the horizontal alignment of the icon. * * @param horizontalAlignment */ public void setHorizontalAlignment(int horizontalAlignment) { checkHorizontalKey(horizontalAlignment); this.horizontalAlignment = horizontalAlignment; } /** * Checks if the given integer is a valid key for horizontal alignment and * throws an {@link IllegalArgumentException} if the key is invalid. * * @param key */ protected void checkHorizontalKey(int key) { if ((key == SwingConstants.LEFT) || (key == SwingConstants.CENTER) || (key == SwingConstants.RIGHT) || (key == SwingConstants.LEADING) || (key == SwingConstants.TRAILING)) { return; } else { throw new IllegalArgumentException("unknown value for horizontalAlignment: " + key); } } /** * Returns the vertical alignment of the icon. * * @return the vertical alignment of the icon */ public int getVerticalAlignment() { return verticalAlignment; } /** * Sets the vertical alignment of the icon. * * @param verticalAlignment */ public void setVerticalAlignment(int verticalAlignment) { checkVerticalKey(verticalAlignment); this.verticalAlignment = verticalAlignment; } /** * Checks if the given integer is a valid key for vertical alignment and * throws an {@link IllegalArgumentException} if the key is invalid. * * @param key */ protected void checkVerticalKey(int key) { if ((key == SwingConstants.TOP) || key == SwingConstants.BOTTOM || key == SwingConstants.CENTER) { return; } else { throw new IllegalArgumentException("unknown value for verticalAlignment: " + key); } } /** * Returns the icon's offset position. * * @return */ public Point getOffset() { return offset; } /** * Sets the icon's offset position. * * @param offset */ public void setOffset(Point offset) { if (offset == null) { throw new IllegalArgumentException("offset == null"); } this.offset = offset; } /** * Gets the size of the error icon. * * @return size of the error icon. */ public Dimension getDimension() { return this.dimension; } /** * Gets the error icon that is used when the component has no focus. * * @return the error icon that is used when the component has no focus */ public ImageIcon getErrorIcon() { return errorIcon; } /** * Sets the error icon that sould be rendered when the component has no * focus. * * @param aErrorIcon */ public void setErrorIcon(ImageIcon aErrorIcon) { if (aErrorIcon == null) { throw new IllegalArgumentException("aErrorIcon == null"); } this.errorIcon = aErrorIcon; updateDimension(); } /** * Returns the error icon that is used when the component has the focus. * * @return the error icon that is used when the component has the focus */ public ImageIcon getErrorIconFocused() { return errorIconFocused; } /** * Sets the error icon that sould be rendered when the component has the * focus. * * @param aErrorIconFocused */ public void setErrorIconFocused(ImageIcon aErrorIconFocused) { if (aErrorIconFocused == null) { throw new IllegalArgumentException("aErrorIconFocused == null"); } this.errorIconFocused = aErrorIconFocused; updateDimension(); } /** * Recalculates the size of the painting area. */ private void updateDimension() { this.dimension = new Dimension(Math.max(errorIcon.getIconWidth(), errorIconFocused.getIconWidth()), Math.max(errorIcon.getIconHeight(), errorIconFocused.getIconHeight())); } /** * Paints the error icon onto the given {@link Graphics} object by using the * given component to calculate the icons loacation. * * @param g * @param c */ public void paint(Graphics g, Component c) { int x; if (horizontalAlignment == SwingConstants.RIGHT || horizontalAlignment == SwingConstants.TRAILING) { x = c.getWidth() - (dimension.width + margin.right) + offset.x; } else if (horizontalAlignment == SwingConstants.LEFT || horizontalAlignment == SwingConstants.LEADING) { x = margin.left + offset.x; } else if (horizontalAlignment == SwingConstants.CENTER) { x = (c.getWidth() - (dimension.width + margin.left + margin.right)) / 2 + margin.left + offset.x; } else { throw new IllegalStateException("Unexpected value for horizontalAlignment: " + horizontalAlignment); } int y; if (verticalAlignment == SwingConstants.BOTTOM) { y = c.getHeight() - (dimension.height + margin.bottom) + offset.y; } else if (verticalAlignment == SwingConstants.TOP) { y = margin.top + offset.y; } else if (verticalAlignment == SwingConstants.CENTER) { y = (c.getHeight() - (dimension.height + margin.top + margin.bottom)) / 2 + margin.top + offset.y; } else { throw new IllegalStateException("Unexpected value for verticalAlignment: " + verticalAlignment); } boolean hasFocus = c.hasFocus(); paintErrorImage(g, x, y, hasFocus, c); } /** * Paints the error icon onto the given {@link Graphics} object. * * @param g graphics object to paint to * @param x horizontal position of the top left corner of the error icon in * {@link Graphics} <code>g</code> * @param y vertical position of the top left corner of the error icon in * {@link Graphics} <code>g</code> * @param hasFocus <code>true</code> if the component has the focus of which * the {@link Graphics} object <code>g</code> is from. If * <code>true</code> {@link #ERROR_ICON_FOCUSED} is painted, else * {@link #ERROR_ICON} * @param observer object to be notified as more of the image is converted */ private void paintErrorImage(Graphics g, int x, int y, boolean hasFocus, ImageObserver observer) { if (g == null) { return; } ImageIcon icon = hasFocus ? errorIconFocused : errorIcon; g.drawImage(icon.getImage(), x, y, observer); } }