i'm facing a graphic paint problem that I don't know what is happening.
Here's the problem:
I have 2 buttons:
- Each button have it's own class.
- Each class have it's own hover effect.
- I'm using TimingFramework library to make the hover effect
- I'm using easing functions in hover event, each button use this class.
Left button hover:
Right button hover:
Whenever I hover the left button and fast change to the right button (before hover ends), the right button becomes this:
I can see that the right button renders the left button graphic, but I don't know why, I've tried to override each paintComponent method but nothing seems to work, if anybody can help me, please, help me.
The codes that I used to:
Right button: Label_Round.java
package com.sm.component;
import com.sm.easings.EasingsFunctions;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.TimingTarget;
import org.jdesktop.animation.timing.TimingTargetAdapter;
import org.jdesktop.animation.timing.interpolation.Interpolator;
public class Label_Round extends JLabel {
private ImageIcon selectedIcon;
private ImageIcon lblIcon;
private Color LR_colorCircleAroundBackground = new Color(255, 255, 255);
private boolean LR_circleAroundBackground = false;
private boolean LR_fitIcon = true;
private boolean LR_hoverEffect = false;
private int LR_fitIconSizeDiff = 10;
private Color LR_background = new Color(255, 255, 255);
private Color LR_backgroundHover = new Color(255, 255, 255);
// Animation
Animator animatorInBackground;
Animator animatorOutBackground;
public Label_Round() {
super.setOpaque(false);
super.setFocusable(false);
super.setHorizontalTextPosition(SwingConstants.CENTER);
super.setHorizontalAlignment(SwingConstants.CENTER);
super.setVerticalAlignment(SwingConstants.CENTER);
super.setVerticalTextPosition(SwingConstants.CENTER);
super.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
initAnimations();
initEvents();
}
private void initEvents() {
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
if (LR_hoverEffect) {
if (animatorInBackground.isRunning()) {
animatorInBackground.stop();
}
if (animatorOutBackground.isRunning()) {
animatorOutBackground.stop();
}
animatorInBackground.start();
}
}
@Override
public void mouseExited(MouseEvent e) {
if (LR_hoverEffect) {
if (animatorInBackground.isRunning()) {
animatorInBackground.stop();
}
if (animatorOutBackground.isRunning()) {
animatorOutBackground.stop();
}
animatorOutBackground.start();
}
}
});
}
private void initAnimations() {
TimingTarget targetBackground = new TimingTargetAdapter() {
@Override
public void timingEvent(float fraction) {
if (animatorInBackground.isRunning()) {
int rgbColor1 [] = new int [] {getBackground().getRed(), getBackground().getGreen(), getBackground().getBlue()};
int rgbColor2 [] = new int [] {getLR_backgroundHover().getRed(), getLR_backgroundHover().getGreen(), getLR_backgroundHover().getBlue()};
int rgbFinal [] = new int [3];
boolean factorCalculos [] = new boolean [3]; // True = Resta - False = Suma
for (int i = 0; i < rgbFinal.length; i++) {
if (rgbColor1 [i] > rgbColor2 [i]) {
rgbFinal [i] = (int) (rgbColor1 [i] - ((rgbColor1 [i] - rgbColor2 [i]) * fraction));
factorCalculos [i] = true;
} else {
rgbFinal [i] = (int) (rgbColor1 [i] + ((rgbColor2 [i] - rgbColor1 [i]) * fraction));
factorCalculos [i] = false;
}
}
Color finalColor = new Color(rgbFinal [0], rgbFinal [1], rgbFinal [2]);
setBackground(finalColor);
if (getLR_backgroundHover().equals(finalColor)) {
animatorInBackground.stop();
}
} else if (animatorOutBackground.isRunning()) {
int rgbColor1 [] = new int [] {getBackground().getRed(), getBackground().getGreen(), getBackground().getBlue()};
int rgbColor2 [] = new int [] {getLR_background().getRed(), getLR_background().getGreen(), getLR_background().getBlue()};
int rgbFinal [] = new int [3];
boolean factorCalculos [] = new boolean [3]; // True = Resta - False = Suma
for (int i = 0; i < rgbFinal.length; i++) {
if (rgbColor1 [i] > rgbColor2 [i]) {
rgbFinal [i] = (int) (rgbColor1 [i] - ((rgbColor1 [i] - rgbColor2 [i]) * fraction));
factorCalculos [i] = true;
} else {
rgbFinal [i] = (int) (rgbColor1 [i] + ((rgbColor2 [i] - rgbColor1 [i]) * fraction));
factorCalculos [i] = false;
}
}
Color finalColor = new Color(rgbFinal [0], rgbFinal [1], rgbFinal [2]);
setBackground(finalColor);
if (getLR_background().equals(finalColor)) {
animatorOutBackground.stop();
}
}
repaint();
}
};
animatorInBackground = new Animator(500, targetBackground);
animatorInBackground.setInterpolator(new Interpolator() {
@Override
public float interpolate(float f) {
return EasingsFunctions.easeInOutSine(f);
}
});
animatorOutBackground = new Animator(500, targetBackground);
animatorOutBackground.setInterpolator(new Interpolator() {
@Override
public float interpolate(float f) {
return EasingsFunctions.easeInOutSine(f);
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getBackground());
if (LR_circleAroundBackground) {
g2d.fillOval(0, 0, getWidth(), getHeight());
g2d.fillOval(0, 0, getWidth(), getHeight());
} else {
g2d.fillOval(0, 0, getWidth(), getHeight());
}
// Icon
if (selectedIcon != null) {
if (LR_fitIcon) {
lblIcon = new ImageIcon(((ImageIcon) selectedIcon).getImage().getScaledInstance(getWidth() - LR_fitIconSizeDiff, getHeight() - LR_fitIconSizeDiff, Image.SCALE_SMOOTH));
} else {
lblIcon = (ImageIcon) selectedIcon;
}
g2d.drawImage(lblIcon.getImage(), ((getWidth() / 2) - (lblIcon.getIconWidth() / 2)), ((getHeight()/ 2) - (lblIcon.getIconHeight()/ 2)), this);
}
}
// Para no dejar que el usuario diseñe el botón
@Override
public void setBackground(Color bg) {
super.setBackground(bg);
}
@Override
public Color getBackground() {
return super.getBackground();
}
@Override
public void setCursor(Cursor cursor) {
super.setCursor(cursor);
}
@Override
public void setIcon(Icon icon) {
super.setIcon(icon);
selectedIcon = (ImageIcon) icon;
}
@Override
public Icon getIcon() {
return null;
}
@Override
public void setOpaque(boolean isOpaque) {
super.setOpaque(false);
}
@Override
public void setFocusable(boolean focusable) {
super.setFocusable(false);
}
@Override
public void setHorizontalTextPosition(int textPosition) {
super.setHorizontalTextPosition(SwingConstants.CENTER);
}
@Override
public void setHorizontalAlignment(int alignment) {
super.setHorizontalAlignment(SwingConstants.CENTER);
}
@Override
public void setVerticalAlignment(int alignment) {
super.setVerticalAlignment(SwingConstants.CENTER);
}
@Override
public void setVerticalTextPosition(int textPosition) {
super.setVerticalTextPosition(SwingConstants.CENTER);
}
@Override
public void setBorder(Border border) {
super.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
public Color getLR_colorCircleAroundBackground() {
return LR_colorCircleAroundBackground;
}
public void setLR_colorCircleAroundBackground(Color LR_colorCircleAroundBackground) {
this.LR_colorCircleAroundBackground = LR_colorCircleAroundBackground;
}
public boolean isLR_circleAroundBackground() {
return LR_circleAroundBackground;
}
public void setLR_circleAroundBackground(boolean LR_circleAroundBackground) {
this.LR_circleAroundBackground = LR_circleAroundBackground;
}
public boolean isLR_fitIcon() {
return LR_fitIcon;
}
public void setLR_fitIcon(boolean LR_fitIcon) {
this.LR_fitIcon = LR_fitIcon;
}
public int getLR_fitIconSizeDiff() {
return LR_fitIconSizeDiff;
}
public void setLR_fitIconSizeDiff(int LR_fitIconSizeDiff) {
this.LR_fitIconSizeDiff = LR_fitIconSizeDiff;
}
public Color getLR_backgroundHover() {
return LR_backgroundHover;
}
public void setLR_backgroundHover(Color LR_backgroundHover) {
this.LR_backgroundHover = LR_backgroundHover;
}
public Color getLR_background() {
return LR_background;
}
public void setLR_background(Color LR_background) {
setBackground(LR_background);
this.LR_background = LR_background;
}
public boolean isLR_hoverEffect() {
return LR_hoverEffect;
}
public void setLR_hoverEffect(boolean LR_hoverEffect) {
this.LR_hoverEffect = LR_hoverEffect;
}
}
Left button: LabelButton_Round.java
package com.sm.component;
import com.sm.easings.EasingsFunctions;
import java.awt.Color;
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 javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.TimingTarget;
import org.jdesktop.animation.timing.TimingTargetAdapter;
import org.jdesktop.animation.timing.interpolation.Interpolator;
public class LabelButton_Round extends JLabel {
private int LBR_arcValue = 10;
private boolean LBR_hoverEffect = false;
private Color LBR_background = new Color(255, 255, 255);
private Color LBR_backgroundHover = new Color(255, 255, 255);
// Animation
Animator animatorInBackground;
Animator animatorOutBackground;
public LabelButton_Round() {
super.setOpaque(false);
super.setFocusable(false);
super.setHorizontalTextPosition(SwingConstants.CENTER);
super.setHorizontalAlignment(SwingConstants.CENTER);
super.setVerticalAlignment(SwingConstants.CENTER);
super.setVerticalTextPosition(SwingConstants.CENTER);
super.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
initAnimations();
initEvents();
}
private void initEvents() {
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
if (LBR_hoverEffect) {
if (animatorInBackground.isRunning()) {
animatorInBackground.stop();
}
if (animatorOutBackground.isRunning()) {
animatorOutBackground.stop();
}
animatorInBackground.start();
}
}
@Override
public void mouseExited(MouseEvent e) {
if (LBR_hoverEffect) {
if (animatorInBackground.isRunning()) {
animatorInBackground.stop();
}
if (animatorOutBackground.isRunning()) {
animatorOutBackground.stop();
}
animatorOutBackground.start();
}
}
});
}
private void initAnimations() {
TimingTarget targetBackground = new TimingTargetAdapter() {
@Override
public void timingEvent(float fraction) {
if (animatorInBackground.isRunning()) {
int rgbColor1 [] = new int [] {getBackground().getRed(), getBackground().getGreen(), getBackground().getBlue()};
int rgbColor2 [] = new int [] {getLBR_backgroundHover().getRed(), getLBR_backgroundHover().getGreen(), getLBR_backgroundHover().getBlue()};
int rgbFinal [] = new int [3];
boolean factorCalculos [] = new boolean [3]; // True = Resta - False = Suma
for (int i = 0; i < rgbFinal.length; i++) {
if (rgbColor1 [i] > rgbColor2 [i]) {
rgbFinal [i] = (int) (rgbColor1 [i] - ((rgbColor1 [i] - rgbColor2 [i]) * fraction));
factorCalculos [i] = true;
} else {
rgbFinal [i] = (int) (rgbColor1 [i] + ((rgbColor2 [i] - rgbColor1 [i]) * fraction));
factorCalculos [i] = false;
}
}
Color finalColor = new Color(rgbFinal [0], rgbFinal [1], rgbFinal [2]);
setBackground(finalColor);
if (getLBR_backgroundHover().equals(finalColor)) {
animatorInBackground.stop();
}
} else if (animatorOutBackground.isRunning()) {
int rgbColor1 [] = new int [] {getBackground().getRed(), getBackground().getGreen(), getBackground().getBlue()};
int rgbColor2 [] = new int [] {getLBR_background().getRed(), getLBR_background().getGreen(), getLBR_background().getBlue()};
int rgbFinal [] = new int [3];
boolean factorCalculos [] = new boolean [3]; // True = Resta - False = Suma
for (int i = 0; i < rgbFinal.length; i++) {
if (rgbColor1 [i] > rgbColor2 [i]) {
rgbFinal [i] = (int) (rgbColor1 [i] - ((rgbColor1 [i] - rgbColor2 [i]) * fraction));
factorCalculos [i] = true;
} else {
rgbFinal [i] = (int) (rgbColor1 [i] + ((rgbColor2 [i] - rgbColor1 [i]) * fraction));
factorCalculos [i] = false;
}
}
Color finalColor = new Color(rgbFinal [0], rgbFinal [1], rgbFinal [2]);
setBackground(finalColor);
if (getLBR_background().equals(finalColor)) {
animatorOutBackground.stop();
}
}
repaint();
}
};
animatorInBackground = new Animator(500, targetBackground);
animatorInBackground.setInterpolator(new Interpolator() {
@Override
public float interpolate(float f) {
return EasingsFunctions.easeInOutSine(f);
}
});
animatorOutBackground = new Animator(500, targetBackground);
animatorOutBackground.setInterpolator(new Interpolator() {
@Override
public float interpolate(float f) {
return EasingsFunctions.easeInOutSine(f);
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getBackground().darker());
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), LBR_arcValue, LBR_arcValue);
g2d.setColor(getBackground());
g2d.fillRoundRect(0, 0, getWidth(), getHeight() - 5, LBR_arcValue, LBR_arcValue);
}
// Para no dejar que el usuario diseñe el botón
@Override
public void setBackground(Color bg) {
super.setBackground(bg);
}
@Override
public Color getBackground() {
return super.getBackground();
}
@Override
public void setCursor(Cursor cursor) {
super.setCursor(cursor);
}
@Override
public void setOpaque(boolean isOpaque) {
super.setOpaque(false);
}
@Override
public void setFocusable(boolean focusable) {
super.setFocusable(false);
}
@Override
public void setHorizontalTextPosition(int textPosition) {
super.setHorizontalTextPosition(SwingConstants.CENTER);
}
@Override
public void setHorizontalAlignment(int alignment) {
super.setHorizontalAlignment(SwingConstants.CENTER);
}
@Override
public void setVerticalAlignment(int alignment) {
super.setVerticalAlignment(SwingConstants.CENTER);
}
@Override
public void setVerticalTextPosition(int textPosition) {
super.setVerticalTextPosition(SwingConstants.CENTER);
}
@Override
public void setBorder(Border border) {
super.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
}
public Color getLBR_backgroundHover() {
return LBR_backgroundHover;
}
public void setLBR_backgroundHover(Color LBR_backgroundHover) {
this.LBR_backgroundHover = LBR_backgroundHover;
}
public Color getLBR_background() {
return LBR_background;
}
public void setLBR_background(Color LBR_background) {
setBackground(LBR_background);
this.LBR_background = LBR_background;
}
public boolean isLBR_hoverEffect() {
return LBR_hoverEffect;
}
public void setLBR_hoverEffect(boolean LBR_hoverEffect) {
this.LBR_hoverEffect = LBR_hoverEffect;
}
public int getLBR_arcValue() {
return LBR_arcValue;
}
public void setLBR_arcValue(int LBR_arcValue) {
this.LBR_arcValue = LBR_arcValue;
}
}
Easings:
package com.sm.easings;
public interface Easings {
public float easing(float f);
}
EasingsFunctions:
package com.sm.easings;
public class EasingsFunctions {
public static float easeOutBounce(float x) {
float n1 = 7.5625f;
float d1 = 2.75f;
double v;
if (x < 1 / d1) {
v = n1 * x * x;
} else if (x < 2 / d1) {
v = n1 * (x -= 1.5 / d1) * x + 0.75;
} else if (x < 2.5 / d1) {
v = n1 * (x -= 2.25 / d1) * x + 0.9375;
} else {
v = n1 * (x -= 2.625 / d1) * x + 0.984375;
}
return (float) v;
}
public static float easeOutQuint(float x) {
return (float) (1 - Math.pow(1 - x, 5));
}
public static float easeOutSine(float x) {
return (float) (Math.sin((x * Math.PI) / 2));
}
public static float easeInOutSine(float x) {
return (float) (-(Math.cos(Math.PI * x) - 1) / 2);
}
}