/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.plugin.desktoputil; import java.awt.*; import java.awt.event.*; import javax.swing.*; import org.jvnet.lafwidget.animation.*; /** * The <tt>SIPCommToggleButton</tt> is a flexible <tt>JToggleButton</tt> that * allows to configure its background, its icon, the look when a mouse is over * it, etc. * * @author Yana Stamcheva */ public class SIPCommToggleButton extends JToggleButton implements OrderedComponent { /** * Serial version UID. */ private static final long serialVersionUID = 0L; /** * The background image shown in normal button state. */ private Image bgImage; /** * The background image shown in rollover button state. */ private Image bgRolloverImage; /** * The icon image shown in normal (non-pressed) button state. */ private Image iconImage; /** * The background image shown in pressed button state. */ private Image pressedImage; /** * The icon image shown in pressed button state. */ private Image pressedIconImage; /** * The index of the button, used when we want to order our buttons. */ private int index = -1; /** * Creates an instance of <tt>SIPCommToggleButton</tt>. */ public SIPCommToggleButton() { // Explicitly remove all borders that may be set from the current // look and feel. this.setBorder(null); MouseRolloverHandler mouseHandler = new MouseRolloverHandler(); this.addMouseListener(mouseHandler); this.addMouseMotionListener(mouseHandler); } /** * Creates a button with custom background image and rollover image. * * @param bgImage the background button image * @param rolloverImage the rollover button image */ public SIPCommToggleButton(Image bgImage, Image rolloverImage) { this(bgImage, rolloverImage, null, null); } /** * Creates a button with custom background image, rollover image and * icon image. * * @param bgImage The background image. * @param rolloverImage The roll over image. * @param iconImage The icon. * @param pressedImage The image used to paint the pressed state. */ public SIPCommToggleButton( Image bgImage, Image rolloverImage, Image iconImage, Image pressedImage) { this(bgImage, rolloverImage, iconImage, pressedImage, null); } /** * Creates a button with custom background image, rollover image and * icon image. * * @param bgImage the background image * @param rolloverImage the roll over image * @param iconImage the icon * @param pressedImage the image used to paint the pressed state * @param pressedIconImage the icon image in a pressed state */ public SIPCommToggleButton( Image bgImage, Image rolloverImage, Image iconImage, Image pressedImage, Image pressedIconImage) { this(); this.bgImage = bgImage; this.bgRolloverImage = rolloverImage; this.iconImage = iconImage; this.pressedImage = pressedImage; this.pressedIconImage = pressedIconImage; this.setPreferredSize( new Dimension( this.bgImage.getWidth(null), this.bgImage.getHeight(null))); if (iconImage != null) this.setIcon(new ImageIcon(this.iconImage)); } /** * Overrides the <code>paintComponent</code> method of <tt>JButton</tt> * to paint the button background and icon, and all additional effects * of this configurable button. * * @param g the Graphics object */ @Override public void paintComponent(Graphics g) { g = g.create(); try { internalPaintComponent(g); } finally { g.dispose(); } } /** * Paints this button. * * @param g the Graphics object */ private void internalPaintComponent(Graphics g) { AntialiasingManager.activateAntialiasing(g); if (this.bgImage != null) { // If there's no icon, we make grey the backgroundImage // when disabled. if (!isEnabled()) { Image disabledImage = new ImageIcon(LightGrayFilter .createDisabledImage(bgImage)).getImage(); g.drawImage(disabledImage, 0, 0, this); } else { g.drawImage(this.bgImage, 0, 0, this); } } // Paint the roll over image. if (getModel().isRollover() && bgRolloverImage != null) { g.drawImage(bgRolloverImage, 0, 0, this); } // Paint the pressed image. if (getModel().isSelected() && pressedImage != null) { g.drawImage(pressedImage, 0, 0, this); } // Paint a roll over fade out. FadeTracker fadeTracker = FadeTracker.getInstance(); float visibility = 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 (bgImage != null) { g.fillRoundRect(this.getWidth() / 2 - this.bgImage.getWidth(null) / 2, this.getHeight() / 2 - this.bgImage.getHeight(null) / 2, bgImage.getWidth(null), bgImage.getHeight(null), 10, 10); } else if (isContentAreaFilled() || (visibility != 0.0f)) { g.fillRoundRect(0, 0, this.getWidth(), this.getHeight(), 10, 10); } // Paint the icon image. Image iconImageFinal = null; if (getModel().isSelected() && pressedIconImage != null) { iconImageFinal = pressedIconImage; } else if (iconImage != null) { if (!isEnabled()) { iconImageFinal = new ImageIcon(LightGrayFilter .createDisabledImage(iconImage)).getImage(); } else { iconImageFinal = iconImage; } } int bgWidth = (bgImage != null) ? bgImage.getWidth(null) : getWidth(); int bgHeight = (bgImage != null) ? bgImage.getHeight(null) : getHeight(); if (iconImageFinal != null) g.drawImage(iconImageFinal, (bgWidth - iconImageFinal.getWidth(null)) / 2, (bgHeight - iconImageFinal.getHeight(null)) / 2, this); } /** * Returns the background image of this button. * * @return the background image of this button */ public Image getBgImage() { return bgImage; } /** * Sets the background image to this button. * * @param bgImage the background image to set */ public void setBgImage(Image bgImage) { this.bgImage = bgImage; this.setPreferredSize(new Dimension(this.bgImage.getWidth(null), this.bgImage.getHeight(null))); } /** * Returns the background rollover image of this button. * * @return the background rollover image of this button */ public Image getBgRolloverImage() { return bgRolloverImage; } /** * Sets the background rollover image to this button. * * @param bgRolloverImage the background rollover image to set */ public void setBgRolloverImage(Image bgRolloverImage) { this.bgRolloverImage = bgRolloverImage; } /** * Returns the icon image of this button. * * @return the icon image of this button */ public Image getIconImage() { return iconImage; } /** * Sets the icon image to this button. * * @param iconImage the icon image to set */ public void setIconImage(Image iconImage) { this.iconImage = iconImage; this.repaint(); } /** * Sets the icon image for the pressed state of this button. * * @param iconImage the icon image to set */ public void setPressedIconImage(Image iconImage) { this.pressedIconImage = iconImage; this.repaint(); } /** * Sets the image representing the pressed state of this button. * * @param pressedImage the image representing the pressed state of this * button */ public void setPressedImage(Image pressedImage) { this.pressedImage = pressedImage; this.repaint(); } /** * 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; } /** * The <tt>ButtonRepaintCallback</tt> 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() { SIPCommToggleButton.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, SIPCommToggleButton.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, SIPCommToggleButton.this, true, new ButtonRepaintCallback()); } } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseDragged(MouseEvent e) { } } }