Is this a bug in JSlider?
Asked Answered
L

1

9

I've been having some problems using the JSlider class - specifically with tick labels.

The first time I use setMajorTickSpacing and setMinorTickSpacing everything works as expected. However, subsequent calls to setMajorTickSpacing update the ticks, but not the labels. I've written a simple example to demonstrate this behaviour:

import java.awt.event.*;
import javax.swing.*;

public class SliderTest {
    public static void main(String args[]) {
        JFrame frame = new JFrame();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        });
        frame.setSize(300, 250);

        JSlider slider = new JSlider(0, 100, 0);
        slider.setMajorTickSpacing(10);
        slider.setMinorTickSpacing(1);
        slider.setPaintLabels(true);
        slider.setPaintTicks(true);

        slider.setMajorTickSpacing(25);
        slider.setMinorTickSpacing(5);

        frame.add(slider);
        frame.pack();
        frame.setVisible(true);
    }
}

Two simple work-arounds seem to fix the problem - either using slider.setLabelTable(null) or slider.setLabelTable(slider.createStandardLabels(25)) before the second call to setMajorTickSpacing. Given this, it would seem that the label table is not being updated correctly.

I'm not sure if this is the intended behaviour or not. My first instinct is that updating the tick spacing should also update the labels, but there are also arguments for separating the two.

So I'd like to know which it is - is this a bug in JSlider or the intended behaviour? If it is the intended behaviour, what would be the standout reasons for making that choice?

Lagoon answered 24/9, 2012 at 9:59 Comment(2)
looks like a bug to me - good catch :-)Eileen
Thanks for sharing about this short-coming.Necking
C
5

You can easily see the cause of this problem by looking into setMajorTickSpacing source code:

public void setMajorTickSpacing(int n) {
    int oldValue = majorTickSpacing;
    majorTickSpacing = n;
    if ( labelTable == null && getMajorTickSpacing() > 0 && getPaintLabels() ) {
        setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
    }
    firePropertyChange("majorTickSpacing", oldValue, majorTickSpacing);
    if (majorTickSpacing != oldValue && getPaintTicks()) {
        repaint();
    }
}

If you call this method twice - labelTable value won't be null anymore and it won't be updated. It might be an intended behavior according to method's comment:

 * This method will also set up a label table for you.
 * If there is not already a label table, and the major tick spacing is
 * {@code > 0}, and {@code getPaintLabels} returns
 * {@code true}, a standard label table will be generated (by calling
 * {@code createStandardLabels}) with labels at the major tick marks.

So you have to update labels manually each time you want them to be updated (unless you override this method with your own that does the update).

Centrifugate answered 24/9, 2012 at 10:53 Comment(1)
Thanks, I came to the same conclusion when I looked at the source. I'd still argue that the documentation could be better.Lagoon

© 2022 - 2024 — McMap. All rights reserved.