Weird issue updating a JLabel on JSlider change

60 Views Asked by At

Huy guys, I have a weird problem. I'm kinda new to swing and java applications.
I'm trying to make a custom UI jslider that changes a jlabel text when you move the thumb.
My problem is: when I use the addChangeListener(), it creates a weird glitch when moving the thumb.
If I don't use it, it works perfectly fine.
How can I update the JLabel without using the change listener or how can I fix this graphic bug?

Most of this code comes from stackoverflow since I don't know much about painting components.

See pictures at the button to better understand the problem

Thanks!

The code in my jpanel

JSlider slider = new JSlider(SwingConstants.HORIZONTAL, 1, 10, 1) {
            @Override
            public void updateUI() {
                setUI(new CustomSliderUI(this));
            }
        };
    // If I comment this line the visual glitch is gone when moving the thumb, but the value doesnt update
        slider.addChangeListener((event) -> RAM_LABEL.setText(slider.getValue() + " Gb"));
        slider.setMinorTickSpacing(1);
        slider.setMajorTickSpacing(10);
        slider.setSnapToTicks(true);
        slider.setBounds(96, 317, 300, 35);
        slider.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        slider.setOpaque(false);
        this.add(slider);

The custom slider ui class

private static class CustomSliderUI extends BasicSliderUI
    {
        private static final int TRACK_HEIGHT = 8;
        private static final int TRACK_ARC = 5;
        private static final Dimension THUMB_SIZE = new Dimension(22, 20);
        private final RoundRectangle2D.Float trackShape = new RoundRectangle2D.Float();
        private final Image knob;

        public CustomSliderUI(final JSlider b)
        {
            super(b);
            knob = Swinger.getResource("knob.png");
        }

        @Override
        protected void calculateTrackRect() {
            super.calculateTrackRect();
            trackRect.y = trackRect.y + (trackRect.height - TRACK_HEIGHT) / 2;
            trackRect.height = TRACK_HEIGHT;
            trackShape.setRoundRect(trackRect.x, trackRect.y, trackRect.width, trackRect.height, TRACK_ARC, TRACK_ARC);
        }

        @Override
        protected void calculateThumbLocation() {
            super.calculateThumbLocation();
            thumbRect.y = trackRect.y + (trackRect.height - thumbRect.height) / 2;
        }

        @Override
        protected Dimension getThumbSize() {
            return THUMB_SIZE;
        }

        @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 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.
            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());
            }
            g2.setColor(Swinger.getTransparentWhite(0));
            g2.fill(trackShape);
            g2.setClip(clip);
        }

        @Override
        public void paintThumb(final Graphics g)
        {
            g.drawImage(knob, thumbRect.x, thumbRect.y, null);
        }

        @Override
        public void paintFocus(final Graphics g) {}
    }

Visual glitch when you are moving the cursor, as soon as you stop pressing the mouse it goes back to normal

Regular cursor / when I move it without the change listener

1

There are 1 best solutions below

0
Max On

Solved. I went with drawing my own background it was simplier.

private static class CustomSliderUI extends BasicSliderUI
    {
        private static final Dimension THUMB_SIZE = new Dimension(22, 20);
        private final Image thumb, background;
        private final JSlider slider;

        public CustomSliderUI(final JSlider b)
        {
            super(b);
            slider = b;
            thumb = Swinger.getResource("thumb.png");
            background = Swinger.getResource("slider.png");
        }

        @Override
        protected Dimension getThumbSize() {
            return THUMB_SIZE;
        }

        @Override
        public void paintTrack(final Graphics g) {
            g.drawImage(background, 10, 11, 280, 10, null);
        }

        @Override
        public void paintThumb(final Graphics g)
        {
            g.drawImage(thumb, thumbRect.x, thumbRect.y, null);
            slider.repaint();
        }

        @Override
        public void paintFocus(final Graphics g) {}
    }
JSlider slider = new JSlider(SwingConstants.HORIZONTAL, 1, 10, 1) {
            @Override
            public void updateUI() {
                setUI(new CustomSliderUI(this));
            }
        };
        slider.addChangeListener((event) -> RAM_LABEL.setText(slider.getValue() + " Gb"));
        slider.setBounds(96, 317, 300, 35);
        slider.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        slider.setOpaque(false);
        this.add(slider);