public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Slider Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 50);
slider.setUI(new BasicSliderUI() {
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
}
@Override
public void paintTrack(Graphics g) {
if(slider.getOrientation() == JSlider.HORIZONTAL) {
int y = (trackRect.height / 2) - 2;
int w = trackRect.width;
g.translate(trackRect.x, trackRect.y + y);
g.setColor(Color.white);
g.drawLine(0, -3, 0, 3);
g.drawLine(w -1, -3, w -1, 3);
g.drawLine(0, 0, w -2, 0); // Main Line
g.translate(-trackRect.x, -(trackRect.y + y));
}
}
@Override
public void paintThumb(Graphics g1) {
Rectangle knobBounds = thumbRect;
int x = knobBounds.x;
int y = knobBounds.y;
int w = knobBounds.width;
int h = knobBounds.height;
Graphics2D g = (Graphics2D) g1;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.white);
g.translate(x, y);
g.fillOval(0, 3, w, w);
}
@Override
protected void paintMajorTickForHorizSlider(Graphics g, Rectangle tickBounds, int x) {
g.setColor(Color.white);
g.drawLine(x, -5, x, tickBounds.height / 2 - 5);
}
@Override
protected void paintMinorTickForHorizSlider(Graphics g, Rectangle tickBounds, int x) {
g.setColor(Color.white);
g.drawLine(x, -5, x, tickBounds.height / 2 - 10);
}
});
slider.setMajorTickSpacing(10);
slider.setMinorTickSpacing(5);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
frame.getContentPane().add(slider);
slider.setBackground(Color.black);
frame.getContentPane().setBackground(Color.black);
frame.setSize(400, 150);
frame.setVisible(true);
});
}
}
我在代码片段中遇到了一个奇怪的行为,我为我的 UI 定制了 JSlider。令人费解的是,当我拖动滑块拇指时,刻度线神秘地消失了。然而,一旦我松开拇指,它们就会神奇地重新出现。有人可以帮助我解决这里可能发生的事情吗?我一直在寻找解决方案,但找不到来源。
还是找不到问题的根源,但是在
super.paint()
之前画勾就解决了问题。
public void paint(Graphics g1, JComponent c) {
paintTicks(g1);
super.paint(g1, c);
}
在正常的
JSlider
中,刻度不会因鼠标拖动而改变,因此tickRect
不会执行重画,如下所示。
// BasicSliderUI
public void paint( Graphics g, JComponent c ) {
//...
if ( slider.getPaintTicks() && clip.intersects( tickRect ) ) {
paintTicks( g ); }
}
建议覆盖
TrackListener#mouseDragged(...)
,以便在鼠标拖动时重绘整个JSlider
。
class CustomSliderUI extends BasicSliderUI {
@Override
protected void paintMajorTickForHorizSlider(Graphics g, Rectangle tickBounds, int x) {
// ...
}
@Override
protected void paintMinorTickForHorizSlider(Graphics g, Rectangle tickBounds, int x) {
// ...
}
@Override
protected BasicSliderUI.TrackListener createTrackListener(JSlider slider) {
return new TrackListener() {
@Override
public void mouseDragged(MouseEvent e) {
super.mouseDragged(e);
e.getComponent().repaint();
}
};
}
}
Main2.java
import java.awt.*;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.plaf.basic.BasicSliderUI;
public class Main2 {
public Component makeUI() {
JSlider slider2 = new JSlider(JSlider.HORIZONTAL, 0, 100, 50) {
@Override public void updateUI() {
super.updateUI();
setUI(new CustomSliderUI());
}
};
slider2.setMajorTickSpacing(10);
slider2.setMinorTickSpacing(5);
slider2.setPaintTicks(true);
slider2.setPaintLabels(true);
slider2.setBackground(Color.BLACK);
JPanel p = new JPanel(new BorderLayout());
p.setBackground(Color.BLACK);
p.add(slider2);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame("Slider Example");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new Main2().makeUI());
f.setSize(400, 150);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class CustomSliderUI extends BasicSliderUI {
@Override
public void paintTrack(Graphics g) {
if (slider.getOrientation() == JSlider.HORIZONTAL) {
int y = (trackRect.height / 2) - 2;
int w = trackRect.width;
g.translate(trackRect.x, trackRect.y + y);
g.setColor(Color.white);
g.drawLine(0, -3, 0, 3);
g.drawLine(w - 1, -3, w - 1, 3);
g.drawLine(0, 0, w - 2, 0); // Main Line
g.translate(-trackRect.x, -(trackRect.y + y));
}
}
@Override
public void paintThumb(Graphics g1) {
Rectangle knobBounds = thumbRect;
int x = knobBounds.x;
int y = knobBounds.y;
int w = knobBounds.width;
int h = knobBounds.height;
Graphics2D g = (Graphics2D) g1;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.white);
g.translate(x, y);
g.fillOval(0, 3, w, w);
}
@Override
protected void paintMajorTickForHorizSlider(Graphics g, Rectangle tickBounds, int x) {
g.setColor(Color.white);
g.drawLine(x, -5, x, tickBounds.height / 2 - 5);
}
@Override
protected void paintMinorTickForHorizSlider(Graphics g, Rectangle tickBounds, int x) {
g.setColor(Color.white);
g.drawLine(x, -5, x, tickBounds.height / 2 - 10);
}
@Override
protected BasicSliderUI.TrackListener createTrackListener(JSlider slider) {
return new TrackListener() {
@Override
public void mouseDragged(MouseEvent e) {
super.mouseDragged(e);
e.getComponent().repaint();
}
};
}
}