如何使用 Nimubs L&F 将 JSlider 轨道填充到当前拇指值的点?
How to fill JSlider track up to the point of the current thumb value with Nimubs L&F?
我正在研究音量滑块,想更改 Nimbus 的默认外观 JSlider
。
我希望我的 JSlider
自动填充曲目直到当前拇指值的点。这种方法的一个想法就像(见图)
我曾尝试扩展 BasicSliderUI
并重写 paintTrack()
方法,但没有成功。我也试过为 JSlider
设置皮肤(参见示例 http://www.jasperpotts.com/blog/2008/08/skinning-a-slider-with-nimbus/),但似乎这种方法只改变了 JSlider
.
的外观
有人知道如何解决这个问题吗?
此示例仅支持水平 JSlider
:
import java.awt.*;
import javax.swing.*;
public class SliderSkinDemo2 {
public JComponent makeUI() {
UIDefaults d = new UIDefaults();
d.put("Slider:SliderTrack[Enabled].backgroundPainter", new Painter<JSlider>() {
@Override public void paint(Graphics2D g, JSlider c, int w, int h) {
int arc = 10;
int trackHeight = 8;
int trackWidth = w - 2;
int fillTop = 4;
int fillLeft = 1;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(1.5f));
g.setColor(Color.GRAY);
g.fillRoundRect(fillLeft, fillTop, trackWidth, trackHeight, arc, arc);
int fillBottom = fillTop + trackHeight;
int fillRight = xPositionForValue(
c.getValue(), c,
new Rectangle(fillLeft, fillTop, trackWidth, fillBottom - fillTop));
g.setColor(Color.ORANGE);
g.fillRect(fillLeft + 1, fillTop + 1, fillRight - fillLeft, fillBottom - fillTop);
g.setColor(Color.WHITE);
g.drawRoundRect(fillLeft, fillTop, trackWidth, trackHeight, arc, arc);
}
//@see javax/swing/plaf/basic/BasicSliderUI#xPositionForValue(int value)
protected int xPositionForValue(int value, JSlider slider, Rectangle trackRect) {
int min = slider.getMinimum();
int max = slider.getMaximum();
int trackLength = trackRect.width;
double valueRange = (double) max - (double) min;
double pixelsPerValue = (double) trackLength / valueRange;
int trackLeft = trackRect.x;
int trackRight = trackRect.x + (trackRect.width - 1);
int xPosition;
xPosition = trackLeft;
xPosition += Math.round(pixelsPerValue * ((double) value - min));
xPosition = Math.max(trackLeft, xPosition);
xPosition = Math.min(trackRight, xPosition);
return xPosition;
}
});
JSlider slider = new JSlider();
slider.putClientProperty("Nimbus.Overrides", d);
JPanel p = new JPanel();
p.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
p.setBackground(Color.DARK_GRAY);
p.add(new JSlider());
p.add(Box.createRigidArea(new Dimension(200, 20)));
p.add(slider);
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
try {
for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(laf.getName())) {
UIManager.setLookAndFeel(laf.getClassName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new SliderSkinDemo2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
我正在研究音量滑块,想更改 Nimbus 的默认外观 JSlider
。
我希望我的 JSlider
自动填充曲目直到当前拇指值的点。这种方法的一个想法就像(见图)
我曾尝试扩展 BasicSliderUI
并重写 paintTrack()
方法,但没有成功。我也试过为 JSlider
设置皮肤(参见示例 http://www.jasperpotts.com/blog/2008/08/skinning-a-slider-with-nimbus/),但似乎这种方法只改变了 JSlider
.
有人知道如何解决这个问题吗?
此示例仅支持水平 JSlider
:
import java.awt.*;
import javax.swing.*;
public class SliderSkinDemo2 {
public JComponent makeUI() {
UIDefaults d = new UIDefaults();
d.put("Slider:SliderTrack[Enabled].backgroundPainter", new Painter<JSlider>() {
@Override public void paint(Graphics2D g, JSlider c, int w, int h) {
int arc = 10;
int trackHeight = 8;
int trackWidth = w - 2;
int fillTop = 4;
int fillLeft = 1;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(1.5f));
g.setColor(Color.GRAY);
g.fillRoundRect(fillLeft, fillTop, trackWidth, trackHeight, arc, arc);
int fillBottom = fillTop + trackHeight;
int fillRight = xPositionForValue(
c.getValue(), c,
new Rectangle(fillLeft, fillTop, trackWidth, fillBottom - fillTop));
g.setColor(Color.ORANGE);
g.fillRect(fillLeft + 1, fillTop + 1, fillRight - fillLeft, fillBottom - fillTop);
g.setColor(Color.WHITE);
g.drawRoundRect(fillLeft, fillTop, trackWidth, trackHeight, arc, arc);
}
//@see javax/swing/plaf/basic/BasicSliderUI#xPositionForValue(int value)
protected int xPositionForValue(int value, JSlider slider, Rectangle trackRect) {
int min = slider.getMinimum();
int max = slider.getMaximum();
int trackLength = trackRect.width;
double valueRange = (double) max - (double) min;
double pixelsPerValue = (double) trackLength / valueRange;
int trackLeft = trackRect.x;
int trackRight = trackRect.x + (trackRect.width - 1);
int xPosition;
xPosition = trackLeft;
xPosition += Math.round(pixelsPerValue * ((double) value - min));
xPosition = Math.max(trackLeft, xPosition);
xPosition = Math.min(trackRight, xPosition);
return xPosition;
}
});
JSlider slider = new JSlider();
slider.putClientProperty("Nimbus.Overrides", d);
JPanel p = new JPanel();
p.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
p.setBackground(Color.DARK_GRAY);
p.add(new JSlider());
p.add(Box.createRigidArea(new Dimension(200, 20)));
p.add(slider);
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
try {
for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(laf.getName())) {
UIManager.setLookAndFeel(laf.getClassName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new SliderSkinDemo2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}