java - 如何使用 Nimubs L&F 将 JSlider 轨道填充到当前拇指值的点?

标签 java swing look-and-feel jslider

我正在开发音量 slider ,并希望更改 Nimbus JSlider 的默认外观。

我希望我的 JSlider 自动填充轨道直至当前拇指值的点。这种方法的想法如下(见图)

The second jSlider fills its background to the point of thumb value.

我尝试扩展 BasicSliderUI 并重写 paintTrack() 方法,但没有成功。我还尝试过对 JSlider 进行换肤(请参阅示例 http://www.jasperpotts.com/blog/2008/08/skinning-a-slider-with-nimbus/ ),但似乎此方法仅更改 JSlider 的外观。

有人知道如何解决这个问题吗?

最佳答案

此示例仅支持水平 JSlider:

enter image description here

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);
    });
  }
}

关于java - 如何使用 Nimubs L&F 将 JSlider 轨道填充到当前拇指值的点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37126097/

相关文章:

java - Jpanel 中的动画组件

java - 如何阻止框架调整大小 JFrame swing SeaGlass L&F

java - Safari Activity 窗口 java applet 类未找到

java - 为什么 Throwable.getMessage() 偶尔会返回 null?

java - 最大化和防止调整 JFrame 的大小?

java - GUI 未正确更新

java - 字符串键在 L&F 中的位置

java - 将 UIManager 中的 FileChooserUI 属性设置为系统的

java - 使用 YourKit 分析应用程序,仍然无法识别 CPU 占用

java - 单例类的优势是什么?