更改 JSlider 的缩略图和颜色?
Change thumb and color of JSlider?
我正在创建一个音乐播放器程序。
我使用 JSlider
创建了搜索栏
代码:
JSlider seek = new JSlider(JProgressBar.HORIZONTAL);
seek.setOpaque(true);
seek.setMajorTickSpacing(0);
seek.setMinorTickSpacing(0);
seek.setBackground(Color.DARK_GRAY);
seek.setSize(100, 13);
seek.setLocation(6, 30);
目前,它看起来像这样:
我只能用setBackground()
方法改变JSlider
的背景。
我不知道如何更改拇指颜色、拇指形状、轨道颜色等
我希望我的搜索栏看起来像这样:
我怎样才能做到这一点?
如果 JSlider
做不到,是否可以创建一个具有可滑动拇指的 JProgressBar
?
正如评论中已经提到的,如果不扩展 SliderUI
的现有实现,您无法更改滑块的外观。这是一个示例实现,说明如何从您的演示图片中获得视觉效果。
请注意,对尺寸和颜色进行硬编码并不是最好的方法,对于真正的实施,应该通过设置和使用 UIManager
可用的值来处理。
class Scratch {
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
JPanel content = new JPanel(new BorderLayout());
content.setPreferredSize(new Dimension(300, 100));
JSlider slider = new JSlider() {
@Override
public void updateUI() {
setUI(new CustomSliderUI(this));
}
};
content.add(slider);
JFrame frame = new JFrame();
frame.setContentPane(content);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
private static class CustomSliderUI extends BasicSliderUI {
private static final int TRACK_HEIGHT = 8;
private static final int TRACK_WIDTH = 8;
private static final int TRACK_ARC = 5;
private static final Dimension THUMB_SIZE = new Dimension(20, 20);
private final RoundRectangle2D.Float trackShape = new RoundRectangle2D.Float();
public CustomSliderUI(final JSlider b) {
super(b);
}
@Override
protected void calculateTrackRect() {
super.calculateTrackRect();
if (isHorizontal()) {
trackRect.y = trackRect.y + (trackRect.height - TRACK_HEIGHT) / 2;
trackRect.height = TRACK_HEIGHT;
} else {
trackRect.x = trackRect.x + (trackRect.width - TRACK_WIDTH) / 2;
trackRect.width = TRACK_WIDTH;
}
trackShape.setRoundRect(trackRect.x, trackRect.y, trackRect.width, trackRect.height, TRACK_ARC, TRACK_ARC);
}
@Override
protected void calculateThumbLocation() {
super.calculateThumbLocation();
if (isHorizontal()) {
thumbRect.y = trackRect.y + (trackRect.height - thumbRect.height) / 2;
} else {
thumbRect.x = trackRect.x + (trackRect.width - thumbRect.width) / 2;
}
}
@Override
protected Dimension getThumbSize() {
return THUMB_SIZE;
}
private boolean isHorizontal() {
return slider.getOrientation() == JSlider.HORIZONTAL;
}
@Override
public void paint(final Graphics g, final JComponent c) {
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paint(g, c);
}
@Override
public void paintTrack(final Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Shape clip = g2.getClip();
boolean horizontal = isHorizontal();
boolean inverted = slider.getInverted();
// Paint shadow.
g2.setColor(new Color(170, 170 ,170));
g2.fill(trackShape);
// Paint track background.
g2.setColor(new Color(200, 200 ,200));
g2.setClip(trackShape);
trackShape.y += 1;
g2.fill(trackShape);
trackShape.y = trackRect.y;
g2.setClip(clip);
// Paint selected track.
if (horizontal) {
boolean ltr = slider.getComponentOrientation().isLeftToRight();
if (ltr) inverted = !inverted;
int thumbPos = thumbRect.x + thumbRect.width / 2;
if (inverted) {
g2.clipRect(0, 0, thumbPos, slider.getHeight());
} else {
g2.clipRect(thumbPos, 0, slider.getWidth() - thumbPos, slider.getHeight());
}
} else {
int thumbPos = thumbRect.y + thumbRect.height / 2;
if (inverted) {
g2.clipRect(0, 0, slider.getHeight(), thumbPos);
} else {
g2.clipRect(0, thumbPos, slider.getWidth(), slider.getHeight() - thumbPos);
}
}
g2.setColor(Color.ORANGE);
g2.fill(trackShape);
g2.setClip(clip);
}
@Override
public void paintThumb(final Graphics g) {
g.setColor(new Color(246, 146, 36));
g.fillOval(thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height);
}
@Override
public void paintFocus(final Graphics g) {}
}
}
结果:
我正在创建一个音乐播放器程序。
我使用 JSlider
代码:
JSlider seek = new JSlider(JProgressBar.HORIZONTAL);
seek.setOpaque(true);
seek.setMajorTickSpacing(0);
seek.setMinorTickSpacing(0);
seek.setBackground(Color.DARK_GRAY);
seek.setSize(100, 13);
seek.setLocation(6, 30);
目前,它看起来像这样:
我只能用setBackground()
方法改变JSlider
的背景。
我不知道如何更改拇指颜色、拇指形状、轨道颜色等
我希望我的搜索栏看起来像这样:
我怎样才能做到这一点?
如果 JSlider
做不到,是否可以创建一个具有可滑动拇指的 JProgressBar
?
正如评论中已经提到的,如果不扩展 SliderUI
的现有实现,您无法更改滑块的外观。这是一个示例实现,说明如何从您的演示图片中获得视觉效果。
请注意,对尺寸和颜色进行硬编码并不是最好的方法,对于真正的实施,应该通过设置和使用 UIManager
可用的值来处理。
class Scratch {
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
JPanel content = new JPanel(new BorderLayout());
content.setPreferredSize(new Dimension(300, 100));
JSlider slider = new JSlider() {
@Override
public void updateUI() {
setUI(new CustomSliderUI(this));
}
};
content.add(slider);
JFrame frame = new JFrame();
frame.setContentPane(content);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
private static class CustomSliderUI extends BasicSliderUI {
private static final int TRACK_HEIGHT = 8;
private static final int TRACK_WIDTH = 8;
private static final int TRACK_ARC = 5;
private static final Dimension THUMB_SIZE = new Dimension(20, 20);
private final RoundRectangle2D.Float trackShape = new RoundRectangle2D.Float();
public CustomSliderUI(final JSlider b) {
super(b);
}
@Override
protected void calculateTrackRect() {
super.calculateTrackRect();
if (isHorizontal()) {
trackRect.y = trackRect.y + (trackRect.height - TRACK_HEIGHT) / 2;
trackRect.height = TRACK_HEIGHT;
} else {
trackRect.x = trackRect.x + (trackRect.width - TRACK_WIDTH) / 2;
trackRect.width = TRACK_WIDTH;
}
trackShape.setRoundRect(trackRect.x, trackRect.y, trackRect.width, trackRect.height, TRACK_ARC, TRACK_ARC);
}
@Override
protected void calculateThumbLocation() {
super.calculateThumbLocation();
if (isHorizontal()) {
thumbRect.y = trackRect.y + (trackRect.height - thumbRect.height) / 2;
} else {
thumbRect.x = trackRect.x + (trackRect.width - thumbRect.width) / 2;
}
}
@Override
protected Dimension getThumbSize() {
return THUMB_SIZE;
}
private boolean isHorizontal() {
return slider.getOrientation() == JSlider.HORIZONTAL;
}
@Override
public void paint(final Graphics g, final JComponent c) {
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paint(g, c);
}
@Override
public void paintTrack(final Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Shape clip = g2.getClip();
boolean horizontal = isHorizontal();
boolean inverted = slider.getInverted();
// Paint shadow.
g2.setColor(new Color(170, 170 ,170));
g2.fill(trackShape);
// Paint track background.
g2.setColor(new Color(200, 200 ,200));
g2.setClip(trackShape);
trackShape.y += 1;
g2.fill(trackShape);
trackShape.y = trackRect.y;
g2.setClip(clip);
// Paint selected track.
if (horizontal) {
boolean ltr = slider.getComponentOrientation().isLeftToRight();
if (ltr) inverted = !inverted;
int thumbPos = thumbRect.x + thumbRect.width / 2;
if (inverted) {
g2.clipRect(0, 0, thumbPos, slider.getHeight());
} else {
g2.clipRect(thumbPos, 0, slider.getWidth() - thumbPos, slider.getHeight());
}
} else {
int thumbPos = thumbRect.y + thumbRect.height / 2;
if (inverted) {
g2.clipRect(0, 0, slider.getHeight(), thumbPos);
} else {
g2.clipRect(0, thumbPos, slider.getWidth(), slider.getHeight() - thumbPos);
}
}
g2.setColor(Color.ORANGE);
g2.fill(trackShape);
g2.setClip(clip);
}
@Override
public void paintThumb(final Graphics g) {
g.setColor(new Color(246, 146, 36));
g.fillOval(thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height);
}
@Override
public void paintFocus(final Graphics g) {}
}
}
结果: