package de.fuhagen.sttp.gui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
/**
* This class implements a flat toggle button.
*
* @author thomas
*
*/
public class FlatToggleButton extends JButton implements ActionListener,
MouseMotionListener, MouseListener {
/**
* Serial version UID.
*/
private static final long serialVersionUID = 7267985473616921408L;
/**
* Flag for button state.
*/
private boolean on = false;
/**
* This action is triggered if the button is switched on.
*/
private Action onAction;
/**
* This action is triggered if the button is switched off.
*/
private Action offAction;
/**
* Current drag point.
*/
private Point mousePoint = null;
/**
* Is the button dragged at the moment?
*/
private boolean dragmode = false;
/**
* This constructor builds a new {@link FlatToggleButton}
*
* @param onAction
* This action is triggered if the button is switched on.
* @param offAction
* This action is triggered if the button is switched off.
* @param buttonWidth
* Width of the button.
* @param buttonHeight
* Height of the button.
*/
public FlatToggleButton(Action onAction, Action offAction, int buttonWidth,
int buttonHeight) {
super(onAction);
this.onAction = onAction;
this.offAction = offAction;
setIcon(null);
Dimension size = new Dimension(buttonWidth, buttonHeight);
setSize(size);
setPreferredSize(size);
setMinimumSize(size);
setFocusPainted(false);
setContentAreaFilled(false);
Border line = new LineBorder(Color.BLACK, 3, true);
Border empty = new EmptyBorder(5, 5, 5, 5);
Border compound = new CompoundBorder(line, empty);
setBorder(compound);
on = false;
setToolTipText(onAction.getValue(Action.SHORT_DESCRIPTION).toString());
addMouseListener(this);
addMouseMotionListener(this);
addActionListener(this);
}
/**
* This method returns the on action.
*
* @return the onAction
* action
*/
public Action getOnAction() {
return onAction;
}
/**
* This method returns the off action.
*
* @return the offAction
* action
*/
public Action getOffAction() {
return offAction;
}
/**
* This method returns true if the button is on.
*
* @return the on
* button state
*/
public boolean isOn() {
return on;
}
/**
* This method toggles the button to the given state.
*
* @param on the on to set
* true to switch the button on
*/
public void setState(boolean on) {
this.on = on;
if (on) {
setAction(offAction);
setIcon(null);
setToolTipText(offAction.getValue(Action.SHORT_DESCRIPTION)
.toString());
} else {
setAction(onAction);
setIcon(null);
setToolTipText(onAction.getValue(Action.SHORT_DESCRIPTION)
.toString());
}
invalidate();
repaint();
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g2d);
g2d.setStroke(new BasicStroke(3));
int width = getWidth() - 10;
int min = 5;
int max = getHeight() - 5 - width;
int y = max;
if (dragmode) {
y = mousePoint.y - (width / 2);
if (y < min) {
y = min;
} else if (y > max) {
y = max;
}
} else if (on) {
y = min;
}
g2d.setColor(Color.BLACK);
g2d.fillRoundRect(5, y, width, width, 5, 5);
}
@Override
public void actionPerformed(ActionEvent e) {
setState(!isOn());
}
@Override
public void mouseDragged(MouseEvent e) {
dragmode = true;
setEnabled(false);
Point lastPoint = mousePoint;
mousePoint = e.getPoint();
if ((lastPoint.y <= getHeight() / 2 && mousePoint.y > getHeight() / 2)
|| (lastPoint.y > getHeight() / 2 && mousePoint.y <= getHeight() / 2)) {
if (e.getPoint().y <= getHeight() / 2) {
ActionEvent event = new ActionEvent(this, 0, "mouse dragged",
System.currentTimeMillis(), 0);
getAction().actionPerformed(event);
setState(true);
} else {
ActionEvent event = new ActionEvent(this, 0, "mouse dragged",
System.currentTimeMillis(), 0);
getAction().actionPerformed(event);
setState(false);
}
}
invalidate();
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
mousePoint = e.getPoint();
}
@Override
public void mouseReleased(MouseEvent e) {
if (dragmode) {
setEnabled(true);
}
mousePoint = null;
dragmode = false;
invalidate();
repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}