/*! Copyright (C) 2009 Apertus, All Rights Reserved
*! Author : Apertus Team
-----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*!
-----------------------------------------------------------------------------**/
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import net.java.balloontip.BalloonTip;
import net.java.balloontip.BalloonTip.AttachLocation;
import net.java.balloontip.BalloonTip.Orientation;
import net.java.balloontip.styles.BalloonTipStyle;
import net.java.balloontip.styles.MinimalBalloonStyle;
public class EButton extends JButton implements java.io.Serializable {
//private static final long serialVersionUID = 21L;
private ElphelVision Parent;
private Color DefaultBorderColor = new Color(70, 70, 70);
private Color DefaultBorderColorChecked = new Color(255, 255, 255);
private Color DefaultBorderColorDisabled = new Color(30, 30, 30);
private Color DefaultBorderColorHighlighted = new Color(20, 80, 130);
private Color DefaultTextColor = new Color(255, 255, 255);
private Color DefaultTextColorChecked = new Color(0, 0, 0);
private Color DefaultTextColorHighlighted = new Color(200, 200, 255);
private Color DefaultTextColorDisabled = new Color(100, 100, 100);
private Color DefaultBackgroundColorGradientStart = new Color(40, 40, 40);
private Color DefaultBackgroundColorGradientEnd = new Color(0, 0, 0);
private Color DefaultBackgroundColorCheckedGradientStart = new Color(200, 200, 200);
private Color DefaultBackgroundColorCheckedGradientEnd = new Color(255, 255, 255);
private Color DefaultBackgroundColorDisabledGradientStart = new Color(20, 20, 20);
private Color DefaultBackgroundColorDisabledGradientEnd = new Color(0, 0, 0);
private Color DefaultBackgroundColorHighlightedGradientStart = new Color(50, 60, 100);
private Color DefaultBackgroundColorHighlightedGradientEnd = new Color(0, 0, 0);
private int BorderWidth = 2;
private int CornerRadius = 12;
private int FontSize = 11;
private int FontWeight = Font.PLAIN;
private boolean Checked = false;
private boolean Highlighted = false;
private String ParameterName = "";
private String AdditionalValue;
private BalloonTip BalloonToolTip = null;
private Timer ToolTipDelayTimer;
private float ToolTipDelayLength = 1; //seconds
private String ToolTipText = null;
public EButton() {
this.setPreferredSize(new Dimension(80, 35));
// This constructor is just to maintain compatibility, use EButton(ElphelVision parent) instead.
// To get rid of these implementations
System.out.println("Warning: called EButton Constructor without parent parameter - use new EButton(Parent); instead - " + this.getClass());
}
public EButton(ElphelVision parent) {
final EButton me = this;
Parent = parent;
this.setRolloverEnabled(false);
this.setPreferredSize(new Dimension(80, 35));
this.setContentAreaFilled(false);
this.setFocusPainted(false);
this.setMargin(new Insets(0, 0, 0, 0));
this.setBorderPainted(false);
this.DefaultBorderColor = Parent.Settings.GetButtonBorderColor();
this.DefaultBorderColorChecked = Parent.Settings.GetButtonBorderColorChecked();
this.DefaultTextColor = Parent.Settings.GetButtonTextColor();
this.DefaultTextColorChecked = Parent.Settings.GetButtonTextColorChecked();
this.setForeground(DefaultTextColor);
this.DefaultBackgroundColorGradientStart = Parent.Settings.GetButtonBackgroundColorGradientStart();
this.DefaultBackgroundColorGradientEnd = Parent.Settings.GetButtonBackgroundColorGradientEnd();
this.DefaultBackgroundColorCheckedGradientStart = Parent.Settings.GetButtonBackgroundColorCheckedGradientStart();
this.DefaultBackgroundColorCheckedGradientEnd = Parent.Settings.GetButtonBackgroundColorCheckedGradientEnd();
this.DefaultBorderColorDisabled = Parent.Settings.getButtonBorderColorDisabled();
this.DefaultBorderColorHighlighted = Parent.Settings.getButtonBorderColorHighlighted();
this.DefaultTextColorHighlighted = Parent.Settings.getButtonTextColorHighlighted();
this.DefaultTextColorDisabled = Parent.Settings.getButtonTextColorDisabled();
this.DefaultBackgroundColorDisabledGradientStart = Parent.Settings.getButtonBackgroundColorDisabledGradientStart();
this.DefaultBackgroundColorDisabledGradientEnd = Parent.Settings.getButtonBackgroundColorDisabledGradientEnd();
this.DefaultBackgroundColorHighlightedGradientStart = Parent.Settings.getButtonBackgroundColorHighlightedGradientStart();
this.DefaultBackgroundColorHighlightedGradientEnd = Parent.Settings.getButtonBackgroundColorHighlightedGradientEnd();
this.CornerRadius = Parent.Settings.GetButtonCornerRadius();
this.BorderWidth = Parent.Settings.GetButtonBorderWidth();
this.FontSize = Parent.Settings.GetButtonFontSize();
this.FontWeight = Parent.Settings.GetButtonFontWeight();
this.setFont(new Font(Parent.Settings.GetButtonFontName(), this.FontWeight, this.FontSize));
addMouseListener(new java.awt.event.MouseAdapter() {
@Override
public void mousePressed(java.awt.event.MouseEvent evt) {
setHighlighted(true);
ToolTipDelayTimer = new Timer();
ToolTipDelayTimer.schedule(new ToolTipTask(me), (int) (ToolTipDelayLength * 1000.0f));
SetToolTipVisible(false);
}
@Override
public void mouseReleased(java.awt.event.MouseEvent evt) {
setHighlighted(false);
SetToolTipVisible(false);
ToolTipDelayTimer.cancel();
}
@Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
setHighlighted(false);
SetToolTipVisible(false);
ToolTipDelayTimer.cancel();
repaint();
super.mouseClicked(evt);
}
});
}
public float getToolTipDelayLength() {
return ToolTipDelayLength;
}
public void setToolTipDelayLength(float ToolTipDelayLength) {
this.ToolTipDelayLength = ToolTipDelayLength;
}
class ToolTipTask extends TimerTask {
EButton Parent = null;
public ToolTipTask(EButton parent) {
Parent = parent;
}
public void run() {
if ((!"".equals(Parent.getToolTipText())) && (Parent.getToolTipText() != null)) {
Parent.SetToolTipVisible(true);
}
ToolTipDelayTimer.cancel();
}
}
public void SetToolTipVisible(boolean showtooltip) {
if (BalloonToolTip != null) {
BalloonToolTip.setVisible(showtooltip);
}
}
@Override
public void setToolTipText(String text) {
this.ToolTipText = text;
JLabel Tooltiptext = new JLabel(text);
Tooltiptext.setFont(new Font(Parent.Settings.GetButtonFontName(), this.FontWeight, 10));
BalloonTipStyle style = new MinimalBalloonStyle(new Color(210, 210, 210), 4);
BalloonToolTip = new BalloonTip(this, Tooltiptext, style, Orientation.LEFT_ABOVE, AttachLocation.NORTH, 20, 8, false);
BalloonToolTip.setOpaque(true);
BalloonToolTip.setPadding(5);
BalloonToolTip.setDoubleBuffered(true);
BalloonToolTip.setVisible(false);
BalloonToolTip.setBackground(Color.black);
}
@Override
public String getToolTipText() {
return this.ToolTipText;
}
public void ToggleChecked() {
if (this.Checked) {
setChecked(false);
} else {
setChecked(true);
}
this.repaint();
}
public void setParameterName(String name) {
this.ParameterName = name;
}
public String getParameterName() {
return this.ParameterName;
}
public void setValue(String val) {
this.AdditionalValue = val;
this.repaint();
}
public String getValue() {
return this.AdditionalValue;
}
public void setCornerRadius(int newradius) {
this.CornerRadius = newradius;
this.repaint();
}
public void setChecked(boolean checked) {
this.Checked = checked;
this.repaint();
}
public boolean isChecked() {
return this.Checked;
}
@Override
public void setForeground(java.awt.Color newcolor) {
if (newcolor != null) { // Evil hack to override default colors but maintain custom color settings
if ((newcolor.getRed() == 51) && (newcolor.getBlue() == 51) && (newcolor.getGreen() == 51)) {
newcolor = DefaultTextColor;
}
}
super.setForeground(newcolor);
}
@Override
public void paint(Graphics g) {
setBackground(Color.BLACK);
Graphics2D g2 = (Graphics2D) g;
Paint oldPaint = g2.getPaint();
g2.setPaint(oldPaint);
g2.setStroke(new BasicStroke(2));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
int x = this.getWidth();
int y = this.getHeight();
// Gradients
GradientPaint DarkGradient = new GradientPaint(0, 0, DefaultBackgroundColorGradientStart, 0, 25, DefaultBackgroundColorGradientEnd, false);
GradientPaint CheckedGradient = new GradientPaint(0, 0, DefaultBackgroundColorCheckedGradientStart, 0, 25, DefaultBackgroundColorCheckedGradientEnd, true);
GradientPaint DisabledGradient = new GradientPaint(0, 0, DefaultBackgroundColorDisabledGradientStart, 0, 25, DefaultBackgroundColorDisabledGradientEnd, true);
GradientPaint HighlightGradient = new GradientPaint(0, 0, DefaultBackgroundColorHighlightedGradientStart, 0, 25, DefaultBackgroundColorHighlightedGradientEnd, true);
if (this.isEnabled() == false) {
// Button Fill
g2.setPaint(DisabledGradient);
g2.fillRoundRect(1, 1, x - 2, y - 2, this.CornerRadius - 2, this.CornerRadius - 2);
// Button Border
g2.setPaint(DefaultBorderColorDisabled);
g2.setStroke(new BasicStroke(1));
g2.drawRoundRect(BorderWidth - 1, BorderWidth - 1, x - 2 * (BorderWidth - 1), y - 2 * (BorderWidth - 1), this.CornerRadius, this.CornerRadius);
} else if (this.isHighlighted()) {
// Button Fill
g2.setPaint(HighlightGradient);
g2.fillRoundRect(BorderWidth * 2, BorderWidth * 2, x - BorderWidth * 4, y - BorderWidth * 4, this.CornerRadius - BorderWidth * 2, this.CornerRadius - BorderWidth * 2);
// Button Border
g2.setPaint(DefaultBorderColorHighlighted);
g2.setStroke(new BasicStroke(BorderWidth));
g2.drawRoundRect(BorderWidth, BorderWidth, x - 2 * BorderWidth, y - 2 * BorderWidth, this.CornerRadius, this.CornerRadius);
} else if (this.Checked) {
// Button Fill
g2.setPaint(CheckedGradient);
g2.fillRoundRect(BorderWidth * 2, BorderWidth * 2, x - BorderWidth * 4, y - BorderWidth * 4, this.CornerRadius - BorderWidth * 2, this.CornerRadius - BorderWidth * 2);
// Button Border
g2.setPaint(DefaultBorderColorChecked);
g2.setStroke(new BasicStroke(BorderWidth));
g2.drawRoundRect(BorderWidth, BorderWidth, x - 2 * BorderWidth, y - 2 * BorderWidth, this.CornerRadius, this.CornerRadius);
} else {
// Button Fill
g2.setPaint(DarkGradient);
g2.fillRoundRect(1, 1, x - 2, y - 2, this.CornerRadius - 2, this.CornerRadius - 2);
// Button Border
g2.setPaint(DefaultBorderColor);
g2.setStroke(new BasicStroke(1));
g2.drawRoundRect(BorderWidth - 1, BorderWidth - 1, x - 2 * (BorderWidth - 1), y - 2 * (BorderWidth - 1), this.CornerRadius, this.CornerRadius);
}
// Button Text
if (this.isEnabled() == false) {
g2.setPaint(DefaultTextColorDisabled);
} else if (this.isHighlighted()) {
g2.setPaint(DefaultTextColorHighlighted);
} else if (this.Checked) {
g2.setPaint(DefaultTextColorChecked);
} else {
g2.setPaint(this.getForeground());
}
//Draw Text
FontMetrics fm = g2.getFontMetrics();
boolean multiline = false;
if (this.getText().contains("\\n")) {
multiline = true;
}
if (multiline) {
String linecontent[] = this.getText().split("\\\\n");
int lines = linecontent.length;
for (int i = 0; i < lines; i++) {
Rectangle2D area = fm.getStringBounds(linecontent[i], g2);
int textx = 0, texty = 0;
int totalmulitlineheight = (int) area.getHeight() * lines;
if (this.getHorizontalAlignment() == 0) { // center
textx = (int) (getWidth() / 2 - area.getWidth() / 2);
texty = (int) (getHeight() / 2 - totalmulitlineheight / 2 + area.getHeight() - 2 + i * (int) area.getHeight());
} else if (this.getHorizontalAlignment() == 2) { // left
textx = this.getMargin().left;
texty = (int) (getHeight() / 2 - totalmulitlineheight / 2 + area.getHeight() - 2 + i * (int) area.getHeight());
}
g2.drawString(linecontent[i], textx, texty);
}
} else {
Rectangle2D area = fm.getStringBounds(this.getText(), g2);
int textx = 0, texty = 0;
if (this.getHorizontalAlignment() == 0) { // center
textx = (int) (getWidth() / 2 - area.getWidth() / 2);
texty = (int) (getHeight() / 2 + area.getHeight() / 2 - 2);
} else if (this.getHorizontalAlignment() == 2) { // left
textx = this.getMargin().left;
texty = (int) (getHeight() / 2 + area.getHeight() / 2 - 2);
}
g2.drawString(this.getText(), textx, texty);
}
// Draw the Icon Image
if (this.getIconImage() != null) {
//this.getIcon().paintIcon(this, g2, (int) (getWidth() / 2 - this.getIcon().getIconWidth() / 2), (int) (getHeight() / 2 - this.getIcon().getIconHeight() / 2));
//setIcon(new javax.swing.ImageIcon(getClass().getResource("/media/rgb.png")));
BufferedImage img = null;
try {
img = ImageIO.read(this.getIconImage());
int w = img.getWidth(null);
int h = img.getHeight(null);
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics gbi = bi.getGraphics();
gbi.drawImage(img, 0, 0, null);
float[] scales = {1f, 1f, 1f, 1f};
float[] scales_highlighted = {1f, 1f, 1f, 1f};
DefaultBorderColorHighlighted.getComponents(scales_highlighted);
float[] scales_checked = {0f, 0f, 0f, 1f};
float[] offsets = {0f, 0f, 0f, 0f};
RescaleOp rop = null;
// tint image depending on state
if (this.isHighlighted()) {
rop = new RescaleOp(scales_highlighted, offsets, null);
} else if (this.isChecked()) {
rop = new RescaleOp(scales_checked, offsets, null);
}
// draw at center (hardcoded for now)
g2.drawImage(bi, rop, this.getWidth() / 2 - w / 2, this.getHeight() / 2 - h / 2);
} catch (IOException ex) {
Parent.WriteErrortoConsole(this.getIconImage().getPath() + " not found!");
Logger.getLogger(EButton.class.getName()).log(Level.SEVERE, null, ex);
}
}
//Draw Additional Value
if (this.AdditionalValue != null) {
Rectangle2D area2 = fm.getStringBounds(this.AdditionalValue, g2);
g2.drawString(this.AdditionalValue, (int) (getWidth() - area2.getWidth() - 6), (int) (getHeight() / 2 + area2.getHeight() / 2 - 2));
}
// We do this all ourselves now so no need to call:
//super.paint(g);
}
URL IconPath = null;
public void setIconImage(URL icon) {
this.IconPath = icon;
}
public URL getIconImage() {
return this.IconPath;
}
public boolean isHighlighted() {
return Highlighted;
}
public void setHighlighted(boolean Highlighted) {
this.Highlighted = Highlighted;
this.repaint();
}
}