Is there a standard GUI toggle switch in Java?
-
22-04-2021 - |
質問
Is there a standard implementation or library that provides a GUI toggle switch in Swing? I know Swing provides a toggle button, but the UX leaves a bit to be desired. I'm looking for this:
Also, is there a canonical term for this type of control? The Apple HIG refer to it as a UISwitch. I also tried searching for "toggle switch", but I didn't have much luck. (Plenty of JavaScript results, but nothing native.)
解決
You might mimic it by using two icons to represent on & off, then set those to a JToggleButton
.
As an aside, users want to see logical and consistent GUIs that represent the 'path of least surprise', it's developers that think users want a 'beautiful, clever' GUI (and that they can design one). Why on earth would they want such a control over a standard toggle-button?
他のヒント
I don't know of a standard one, but Gerrit Grunwald who creates the Steel Series components created an implementation of this that he calls a Steel Checkbox
Swing doesn't have a standard switch like the one you described. Your best bet if you can't find a third party one would be to simply write one. The way I'd approach it would be a simple structure like this:
• JLabel
• Override paintComponent
• Check for state with something like isOn()
• Add a MouseListener
to toggle state.
• Custom painting would take into account label values and sizes.
I could send you one that I wrote some time ago, but you probably have a very specific idea of what you want so might be worth the half an hour constructing it.
Guess I am 6 years late, but nevertheless for those who still search for a simple solution:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.Cursor;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class ToggleSwitch extends JPanel {
private boolean activated = false;
private Color switchColor = new Color(200, 200, 200), buttonColor = new Color(255, 255, 255), borderColor = new Color(50, 50, 50);
private Color activeSwitch = new Color(0, 125, 255);
private BufferedImage puffer;
private int borderRadius = 10;
private Graphics2D g;
public ToggleSwitch() {
super();
setVisible(true);
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent arg0) {
activated = !activated;
repaint();
}
});
setCursor(new Cursor(Cursor.HAND_CURSOR));
setBounds(0, 0, 41, 21);
}
@Override
public void paint(Graphics gr) {
if(g == null || puffer.getWidth() != getWidth() || puffer.getHeight() != getHeight()) {
puffer = (BufferedImage) createImage(getWidth(), getHeight());
g = (Graphics2D)puffer.getGraphics();
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHints(rh);
}
g.setColor(activated?activeSwitch:switchColor);
g.fillRoundRect(0, 0, this.getWidth()-1,getHeight()-1, 5, borderRadius);
g.setColor(borderColor);
g.drawRoundRect(0, 0, getWidth()-1, getHeight()-1, 5, borderRadius);
g.setColor(buttonColor);
if(activated) {
g.fillRoundRect(getWidth()/2, 1, (getWidth()-1)/2 -2, (getHeight()-1) - 2, borderRadius, borderRadius);
g.setColor(borderColor);
g.drawRoundRect((getWidth()-1)/2, 0, (getWidth()-1)/2, (getHeight()-1), borderRadius, borderRadius);
}
else {
g.fillRoundRect(1, 1, (getWidth()-1)/2 -2, (getHeight()-1) - 2, borderRadius, borderRadius);
g.setColor(borderColor);
g.drawRoundRect(0, 0, (getWidth()-1)/2, (getHeight()-1), borderRadius, borderRadius);
}
gr.drawImage(puffer, 0, 0, null);
}
public boolean isActivated() {
return activated;
}
public void setActivated(boolean activated) {
this.activated = activated;
}
public Color getSwitchColor() {
return switchColor;
}
/**
* Unactivated Background Color of switch
*/
public void setSwitchColor(Color switchColor) {
this.switchColor = switchColor;
}
public Color getButtonColor() {
return buttonColor;
}
/**
* Switch-Button color
*/
public void setButtonColor(Color buttonColor) {
this.buttonColor = buttonColor;
}
public Color getBorderColor() {
return borderColor;
}
/**
* Border-color of whole switch and switch-button
*/
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
public Color getActiveSwitch() {
return activeSwitch;
}
public void setActiveSwitch(Color activeSwitch) {
this.activeSwitch = activeSwitch;
}
/**
* @return the borderRadius
*/
public int getBorderRadius() {
return borderRadius;
}
/**
* @param borderRadius the borderRadius to set
*/
public void setBorderRadius(int borderRadius) {
this.borderRadius = borderRadius;
}
}
Just copy it in a ToggleSwitch.java. You can add it to your JFrame like this:
ToggleSwitch ts = new ToggleSwitch();
ts.setLocation(5, 135);
frame.add(ts);