/* * @(#)NavitaionTreeIcon.java 11/3/2011 * * Copyright 2002 - 2011 JIDE Software Inc. All rights reserved. */ package com.jidesoft.icons; import com.jidesoft.swing.JideSwingUtilities; import javax.swing.*; import java.awt.*; import java.awt.geom.GeneralPath; /** * <code>RolloverIcon</code> provides the expanded and collapsed tree icons that has rollover and fade effect. However * it can be used to implement icon for any other purpose, not just the tree icons. * * @since 3.3.0 */ public class RolloverIcon implements Icon { /** * All colors used by the default icons. You can change them to fit your L&F. */ public static Color COLOR_COLLAPSED_FILL_ROLLOVER = new Color(199, 235, 250); public static Color COLOR_COLLAPSED_FILL = Color.WHITE; public static Color COLOR_COLLAPSED_ROLLOVER = new Color(28, 196, 247); public static Color COLOR_COLLAPSED = new Color(165, 165, 165); public static Color COLOR_EXPANDED_FILL_ROLLOVER = new Color(130, 223, 251); public static Color COLOR_EXPANDED_FILL = new Color(89, 89, 89); public static Color COLOR_EXPANDED_ROLLOVER = new Color(28, 196, 247); public static Color COLOR_EXPANDED = new Color(35, 35, 35); public final static int ICON_EXPANDED = 0; public final static int ICON_COLLAPSED = 1; private Icon _normalIcon; private Icon _rolloverIcon; private IconRolloverSupport _rolloverSupport; /** * An interface that should be implemented on a component if you want to use an icon that supports rollover and fade * (fade in or fade out) effect. */ public static interface IconRolloverSupport { /** * Checks if the mouse is over an icon. In the implementation, you can use a MouseMotionListener to detect the * mouse position and see if it is over the icon. * * @param x x of the icon * @param y y of the icon * @param width icon width * @param height icon height * @return true if the mouse is over the icon. False if not. */ boolean isIconRollover(int x, int y, int width, int height); /** * Checks if the icon should be faded. Because the fade is an animation, we will call {@link #getIconAlpha()} * immediately to find out the alpha value of the fade. In your implementation, you can use an Animator or any * other animation frameworks to change the iconAlpha value and ask the icon to repaint itself again. * * @return true of the icon should be faded. If it returns true, {@link #getIconAlpha()} will be called to find * out the alpha value. */ boolean isIconFade(); /** * Gets the icon alpha value. We will paint the icon using the provided alpha value to create the fade effect. * * @return the icon alpha value. */ float getIconAlpha(); } /** * The default collapsed tree icon. */ public static class DefaultCollapsedIcon implements Icon { private IconRolloverSupport _rolloverSupport; public DefaultCollapsedIcon(IconRolloverSupport rolloverSupport) { _rolloverSupport = rolloverSupport; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D) g; Color orgColor = g2.getColor(); Object o = JideSwingUtilities.setupShapeAntialiasing(g); GeneralPath path = new GeneralPath(); if (c.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) { path.moveTo(x + 4, y); path.lineTo(x, y + 4); path.lineTo(x + 4, y + 8); } else { path.moveTo(x, y); path.lineTo(x + 4, y + 4); path.lineTo(x, y + 8); } path.closePath(); boolean rollover = _rolloverSupport.isIconRollover(x, y, getIconWidth(), getIconHeight()); g2.setColor(rollover ? COLOR_COLLAPSED_FILL_ROLLOVER : COLOR_COLLAPSED_FILL); g2.fill(path); g2.setColor(rollover ? COLOR_COLLAPSED_ROLLOVER : COLOR_COLLAPSED); g2.draw(path); g2.setColor(orgColor); JideSwingUtilities.restoreShapeAntialiasing(g, o); } @Override public int getIconWidth() { return 6; } @Override public int getIconHeight() { return 9; } } /** * The default expanded tree icon. */ public static class DefaultExpandedIcon implements Icon { private IconRolloverSupport _rolloverSupport; public DefaultExpandedIcon(IconRolloverSupport rolloverSupport) { _rolloverSupport = rolloverSupport; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D) g; Color orgColor = g2.getColor(); Object o = JideSwingUtilities.setupShapeAntialiasing(g); GeneralPath path = new GeneralPath(); if (c.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) { path.moveTo(x, y); path.lineTo(x, y + 5); path.lineTo(x + 5, y + 5); } else { path.moveTo(x + 5, y); path.lineTo(x + 5, y + 5); path.lineTo(x, y + 5); } path.closePath(); boolean rollover = _rolloverSupport.isIconRollover(x, y, getIconWidth(), getIconHeight()); g2.setColor(rollover ? COLOR_EXPANDED_FILL_ROLLOVER : COLOR_EXPANDED_FILL); g2.fill(path); g2.setColor(rollover ? COLOR_EXPANDED_ROLLOVER : COLOR_EXPANDED); g2.draw(path); g2.setColor(orgColor); JideSwingUtilities.restoreShapeAntialiasing(g, o); } @Override public int getIconWidth() { return 6; } @Override public int getIconHeight() { return 6; } } /** * Creates an RolloverIcon. * * @param rolloverSupport the IconRolloverSupport interface that should be implemented on a component. * @param iconType the icon type. It could be either {@link #ICON_EXPANDED} or {@link #ICON_COLLAPSED}. */ public RolloverIcon(IconRolloverSupport rolloverSupport, int iconType) { _rolloverSupport = rolloverSupport; switch (iconType) { case ICON_EXPANDED: _normalIcon = new DefaultExpandedIcon(rolloverSupport); break; case ICON_COLLAPSED: _normalIcon = new DefaultCollapsedIcon(rolloverSupport); break; } _rolloverIcon = null; } /** * Creates an RolloverIcon. * * @param rolloverSupport the IconRolloverSupport interface that should be implemented on a component. * @param normalIcon the normal icon */ public RolloverIcon(IconRolloverSupport rolloverSupport, Icon normalIcon) { _rolloverSupport = rolloverSupport; _normalIcon = normalIcon; _rolloverIcon = null; } /** * Creates an RolloverIcon. * * @param rolloverSupport the IconRolloverSupport interface that should be implemented on a component. * @param normalIcon the normal icon. This icon will be used to determine the icon size. The size of the * rollover icon is ignored so you should make sure the two icons have the same size. * @param rolloverIcon the rollover icon */ public RolloverIcon(IconRolloverSupport rolloverSupport, Icon normalIcon, Icon rolloverIcon) { _rolloverSupport = rolloverSupport; _normalIcon = normalIcon; _rolloverIcon = rolloverIcon; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2 = (Graphics2D) g; Composite orgComposite = g2.getComposite(); if (_rolloverSupport.isIconFade()) { g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, _rolloverSupport.getIconAlpha())); } boolean rollover = _rolloverIcon != null && _rolloverIcon != _normalIcon && _rolloverSupport.isIconRollover(x, y, getIconWidth(), getIconHeight()); if (rollover) { _rolloverIcon.paintIcon(c, g2, x, y); } else { _normalIcon.paintIcon(c, g2, x, y); } g2.setComposite(orgComposite); } @Override public int getIconWidth() { return _normalIcon.getIconWidth(); } @Override public int getIconHeight() { return _normalIcon.getIconHeight(); } }