Use JSlider to create switch buttons that can be toggled on and off by clicking the mouse or dragging the knob
Code
UIDefaults d = new UIDefaults();
d.put("Slider.thumbHeight", 40);
d.put("Slider.thumbWidth", 40);
d.put("Slider:SliderTrack[Enabled].backgroundPainter", (Painter) (g, c, w, h) -> {
int arc = 40;
int fillLeft = 2;
int fillTop = 2;
int trackWidth = w - fillLeft - fillLeft;
int trackHeight = h - fillTop - fillTop;
int baseline = trackHeight - fillTop - fillTop; // c.getBaseline(w, h);
String off = "Off";
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.GRAY);
g.fillRoundRect(fillLeft, fillTop, trackWidth, trackHeight, arc, arc);
g.setPaint(Color.WHITE);
g.drawString(off, w - g.getFontMetrics().stringWidth(off) - fillLeft * 5, baseline);
int fillRight = getXPositionForValue(c, new Rectangle(fillLeft, fillTop, trackWidth, trackHeight));
g.setColor(Color.ORANGE);
g.fillRoundRect(fillLeft + 1, fillTop, fillRight - fillLeft, trackHeight, arc, arc);
g.setPaint(Color.WHITE);
if (fillRight - fillLeft > 0) {
g.drawString("On", fillLeft * 5, baseline);
}
g.setStroke(new BasicStroke(2.5f));
g.drawRoundRect(fillLeft, fillTop, trackWidth, trackHeight, arc, arc);
});
Painter thumbPainter = (g, c, w, h) -> {
int fillLeft = 8;
int fillTop = 8;
int trackWidth = w - fillLeft - fillLeft;
int trackHeight = h - fillTop - fillTop;
g.setPaint(Color.WHITE);
g.fillOval(fillLeft, fillTop, trackWidth, trackHeight);
};
d.put("Slider:SliderThumb[Disabled].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Enabled].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Focused+MouseOver].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Focused+Pressed].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Focused].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[MouseOver].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Pressed].backgroundPainter", thumbPainter);
JSlider slider = new JSlider(0, 1, 0) {
@Override public Dimension getPreferredSize() {
return new Dimension(100, 40);
}
};
slider.setFont(slider.getFont().deriveFont(Font.BOLD, 32f));
slider.putClientProperty("Nimbus.Overrides", d);
Explanation
Default
- Set
JSlider
to Min0
, Max1
- Change component size by overriding
getPreferredSize()
- Set
Thumb size
- Resize knobs by setting
Slider.thumbWidth
,Slider.thumbHeight
- Resize knobs by setting
SliderTrack
- Create a
Painter
to draw the track background and change the background color, border, andOn/Off
text - Pressing a track turns
On/Off
- Change the drawing of the knob by setting
Painter
- Add
MouseMotionListener
to redraw the whole thing while dragging, since some afterimages may appear when you drag the knob - Pressing or clicking the knob does not cause the `On/Off 'toggle
- Create a
JSlider + JLayer
- The drawing of the track and knob is identical to the above
SliderTrack
- Use
JLayer
to setJSlider
to switchOn/Off
regardless of track or knob - Redraw while dragging the knob is also done in
LayerUI#processMouseMotionEvent(...)
- The drawing of the track and knob is identical to the above
class ToggleSwitchLayerUI extends LayerUI {
@Override public void installUI(JComponent c) {
super.installUI(c);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
}
@Override public void uninstallUI(JComponent c) {
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
@Override protected void processMouseEvent(MouseEvent e, JLayer l) {
if (e.getID() == MouseEvent.MOUSE_PRESSED && SwingUtilities.isLeftMouseButton(e)) {
e.getComponent().dispatchEvent(new MouseEvent(
e.getComponent(),
e.getID(), e.getWhen(),
InputEvent.BUTTON3_DOWN_MASK, // e.getModifiers(),
e.getX(), e.getY(),
e.getXOnScreen(), e.getYOnScreen(),
e.getClickCount(),
e.isPopupTrigger(),
MouseEvent.BUTTON3)); // e.getButton());
e.consume();
} else if (e.getID() == MouseEvent.MOUSE_CLICKED && SwingUtilities.isLeftMouseButton(e)) {
JSlider slider = l.getView();
int v = slider.getValue();
if (slider.getMinimum() == v) {
slider.setValue(slider.getMaximum());
} else if (slider.getMaximum() == v) {
slider.setValue(slider.getMinimum());
}
}
}
@Override protected void processMouseMotionEvent(MouseEvent e, JLayer l) {
l.getView().repaint();
}
}
No comments:
Post a Comment