/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. */ package net.java.sip.communicator.plugin.desktoputil; import java.awt.*; import java.awt.event.*; import javax.swing.*; import org.jvnet.lafwidget.animation.*; /** * The SIPCommButton is a very flexible JButton that allows * to configure its background, its icon, the look when a mouse is over it, etc. * * @author Yana Stamcheva * @author Adam Netocny */ public class SIPCommButton extends JButton implements OrderedComponent { /** * Serial version UID. */ private static final long serialVersionUID = 0L; private Image bgImage; private Image pressedBgImage; private Image rolloverBgImage; private Image rolloverIconImage; private Image pressedIconImage; private Image iconImage; /** * Custom tooltip to be used with this button. */ private ExtendedTooltip extendedTooltip; /** * The index of the button, used when we want to order our buttons. */ private int index = -1; /** * Creates a button. */ public SIPCommButton() { this(null); } /** * Creates a button with custom background image and icon image. * * @param bgImage The background image. * @param rolloverImage The rollover background image. * @param pressedImage The pressed image. * @param iconImage The icon. * @param rolloverIconImage The rollover icon image. * @param pressedIconImage The pressed icon image. */ public SIPCommButton( Image bgImage, Image rolloverImage, Image pressedImage, Image iconImage, Image rolloverIconImage, Image pressedIconImage) { MouseRolloverHandler mouseHandler = new MouseRolloverHandler(); this.addMouseListener(mouseHandler); this.addMouseMotionListener(mouseHandler); /* * Explicitly remove all borders that may be set from the current look * and feel. */ this.setContentAreaFilled(false); this.setBorder(null); this.bgImage = bgImage; this.rolloverBgImage = rolloverImage; this.pressedBgImage = pressedImage; this.rolloverIconImage = rolloverIconImage; this.pressedIconImage = pressedIconImage; this.iconImage = iconImage; if (bgImage != null) { this.setPreferredSize(new Dimension(bgImage.getWidth(null), bgImage.getHeight(null))); this.setIcon(new ImageIcon(this.bgImage)); } } /** * Creates a button with custom background image and icon image. * * @param bgImage The background image. * @param pressedImage The pressed image. * @param iconImage The icon. */ public SIPCommButton( Image bgImage, Image pressedImage, Image iconImage) { this(bgImage, null, pressedImage, iconImage, null, null); } /** * Creates a button with custom background image. * * @param bgImage the background button image * @param iconImage the icon of this button */ public SIPCommButton( Image bgImage, Image iconImage) { this(bgImage, null, iconImage); } /** * Creates a button with custom background image. * * @param bgImage The background button image. */ public SIPCommButton(Image bgImage) { this(bgImage, null); } /** * Resets the background image for this button. * * @param bgImage the new image to set. */ public void setImage(Image bgImage) { this.bgImage = bgImage; this.repaint(); } /** * Overrides the paintComponent method of JButton to * paint the button background and icon, and all additional effects of this * configurable button. * * @param g The Graphics object. */ @Override protected void paintComponent(Graphics g) { g = g.create(); try { internalPaintComponent(g); } finally { g.dispose(); } } /** * Paints this button. * @param g the Graphics object used for painting */ private void internalPaintComponent(Graphics g) { AntialiasingManager.activateAntialiasing(g); /* * As JComponent#paintComponent says, if you do not invoke super's * implementation you must honor the opaque property, that is if this * component is opaque, you must completely fill in the background in a * non-opaque color. If you do not honor the opaque property you will * likely see visual artifacts. */ if (isOpaque()) { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); } // Paint pressed state. Image paintBgImage = null; if (this.getModel().isPressed() && this.pressedBgImage != null) { paintBgImage = this.pressedBgImage; } else if (this.getModel().isRollover() && this.rolloverBgImage != null) { paintBgImage = this.rolloverBgImage; } else if (this.bgImage != null) { // If there's no icon, we make grey the backgroundImage // when disabled. if (this.iconImage == null && !isEnabled()) { paintBgImage = new ImageIcon(LightGrayFilter .createDisabledImage(bgImage)).getImage(); } else paintBgImage = bgImage; } if (paintBgImage != null) { g.drawImage(paintBgImage, this.getWidth()/2 - paintBgImage.getWidth(null)/2, this.getHeight()/2 - paintBgImage.getHeight(null)/2, this); } // Paint a roll over fade out. if (rolloverBgImage == null) { FadeTracker fadeTracker = FadeTracker.getInstance(); float visibility = this.getModel().isRollover() ? 1.0f : 0.0f; if (fadeTracker.isTracked(this, FadeKind.ROLLOVER)) { visibility = fadeTracker.getFade(this, FadeKind.ROLLOVER); } visibility /= 2; g.setColor(new Color(1.0f, 1.0f, 1.0f, visibility)); if (this.bgImage == null && (isContentAreaFilled() || (visibility != 0.0f))) { g.fillRoundRect( 0, 0, this.getWidth(), this.getHeight(), 8, 8); } } Image paintIconImage = null; if (getModel().isPressed() && pressedIconImage != null) { paintIconImage = pressedIconImage; } else if (this.getModel().isRollover() && rolloverIconImage != null) { paintIconImage = rolloverIconImage; } else if (this.iconImage != null) { if (!isEnabled()) { paintIconImage = new ImageIcon(LightGrayFilter .createDisabledImage(iconImage)).getImage(); } else paintIconImage = iconImage; } if (paintIconImage != null) g.drawImage(paintIconImage, this.getWidth()/2 - paintIconImage.getWidth(null)/2, this.getHeight()/2 - paintIconImage.getHeight(null)/2, this); } /** * Returns the background image of this button. * * @return the background image of this button. */ public Image getBackgroundImage() { return bgImage; } /** * Sets the background image of this button. * * @param bgImage the background image of this button. */ public void setBackgroundImage(Image bgImage) { this.bgImage = bgImage; if (bgImage != null) { this.setPreferredSize(new Dimension(bgImage.getWidth(null), bgImage.getHeight(null))); this.setIcon(new ImageIcon(this.bgImage)); } } /** * Sets the rollover background image of this button. * * @param rolloverImage the rollover background image of this button. */ public void setRolloverImage(Image rolloverImage) { this.rolloverBgImage = rolloverImage; } /** * Sets the pressed background image of this button. * * @param pressedImage the pressed background image of this button. */ public void setPressedImage(Image pressedImage) { this.pressedBgImage = pressedImage; } /** * Sets the rollover icon image of this button. * * @param rolloverIconImage the rollover icon image of this button. */ public void setRolloverIcon(Image rolloverIconImage) { this.rolloverIconImage = rolloverIconImage; } /** * Sets the pressed icon image of this button. * * @param pressedIconImage the pressed icon image of this button. */ public void setPressedIcon(Image pressedIconImage) { this.pressedIconImage = pressedIconImage; } /** * Sets the icon image of this button. * * @param iconImage the icon image of this button. */ public void setIconImage(Image iconImage) { this.iconImage = iconImage; } /** * Change buttons index when we want to order it. * @param index the button index. */ public void setIndex(int index) { this.index = index; } /** * Returns the current button index we have set, or -1 if none used. * @return */ public int getIndex() { return this.index; } /** * Changes the custom tooltip for this button. By default no custom tip. * @param extendedTooltip the new tooltip to use. */ public void setTooltip(ExtendedTooltip extendedTooltip) { this.extendedTooltip = extendedTooltip; } /** * Returns the custom tooltip. * @returns the custom tooltip. */ public ExtendedTooltip getTooltip() { return extendedTooltip; } /** * The ButtonRepaintCallback is charged to repaint this button * when the fade animation is performed. */ private class ButtonRepaintCallback implements FadeTrackerCallback { public void fadeEnded(FadeKind arg0) { repaintLater(); } public void fadePerformed(FadeKind arg0, float arg1) { repaintLater(); } private void repaintLater() { SwingUtilities.invokeLater(new Runnable() { public void run() { SIPCommButton.this.repaint(); } }); } public void fadeReversed(FadeKind arg0, boolean arg1, float arg2) { } } /** * Perform a fade animation on mouse over. */ private class MouseRolloverHandler implements MouseListener, MouseMotionListener { public void mouseMoved(MouseEvent e) { } public void mouseExited(MouseEvent e) { if (isEnabled()) { getModel().setRollover(false); FadeTracker fadeTracker = FadeTracker.getInstance(); fadeTracker.trackFadeOut(FadeKind.ROLLOVER, SIPCommButton.this, true, new ButtonRepaintCallback()); } } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { if (isEnabled()) { getModel().setRollover(true); FadeTracker fadeTracker = FadeTracker.getInstance(); fadeTracker.trackFadeIn(FadeKind.ROLLOVER, SIPCommButton.this, true, new ButtonRepaintCallback()); } } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseDragged(MouseEvent e) { } } }