【问题标题】:Change thumb and color of JSlider?更改 JSlider 的拇指和颜色?
【发布时间】:2020-06-27 12:05:30
【问题描述】:

我正在创建一个音乐播放器程序。

我使用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

【问题讨论】:

  • 我不知道如何更改拇指颜色、拇指形状、轨道颜色等。 - 这是由 LAF 控制的。您需要为 JSlider 自定义 U。请参阅您正在使用的类的 getUI() 方法。
  • @camickr 我不明白。 getUI() 方法返回 SliderUI。但是如何使用它来更改拇指颜色、形状和轨迹颜色?
  • 您查看 SliderUI 的方法,看看是否有任何方法可以让您自定义这些属性。如果没有,那么您需要扩展类并覆盖适当的方法并进行自己的自定义绘画。或者您可以查看UIManager Defaults。它将显示一些您可以更改的 UI 直接使用的属性,但这会更改应用程序中所有滑块的属性。
  • 除此之外,是否可以创建一个具有可滑动拇指的JProgressBar
  • @camickr 您继续尝试以非设计用途的方式使用 Swing。 这会激励我还是让我失去动力?

标签: java swing look-and-feel jslider


【解决方案1】:

正如 cmets 中已经提到的,如果不扩展 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) {}
    }
}

结果:

【讨论】:

  • 完美。谢谢!
猜你喜欢
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 2021-03-30
  • 1970-01-01
  • 2022-08-11
  • 2018-01-26
  • 1970-01-01
相关资源
最近更新 更多