Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Dynamic JSlider tick spacing

843806Jun 3 2009 — edited Jun 3 2009
I run several times into the situation where I needed to hardcode a JSlider tick spacing into my program. I always found it difficult to define the tick spacing because a good looking tick spacing depends on the current size of the JSlider on screen and its maximum value.
For my purposes I created a short function that automatically sets a "good looking" tick spacing (labels do not cover more than half of the slider width and use familiar spacing values like 1,2,5,10,20,50,...).
I wanted to share this little piece of code with you, maybe it helps someone...

Here it is:
    private void setMajorTickSpacing(JSlider slider, int maxValue) {
        Graphics graphics = slider.getGraphics();
        FontMetrics fontMetrics = graphics.getFontMetrics();
        int width = slider.getWidth();
        // try with the following values:
        // 1,2,5,10,20,50,100,200,500,...
        int tickSpacing = 1;
        for (int i = 0, tmpWidthSum = width + 1; tmpWidthSum > (width / 2);
                i++) {
            tickSpacing = (int) Math.pow(10, (i / 3));
            switch (i % 3) {
                case 1:
                    tickSpacing *= 2;
                    break;
                case 2:
                    tickSpacing *= 5;
            }
            tmpWidthSum = 0;
            for (int j = 0; j < maxValue; j += tickSpacing) {
                Rectangle2D stringBounds = fontMetrics.getStringBounds(
                        String.valueOf(j), graphics);
                tmpWidthSum += (int) stringBounds.getWidth();
                if (tmpWidthSum > (width / 2)) {
                    // the labels are longer than the slider
                    break;
                }
            }
        }
        slider.setMajorTickSpacing(tickSpacing);
        slider.setLabelTable(createLabels(slider, tickSpacing));
    }
To have your tick spacing dynamically adopted when the user resizes the window, you should use a code snippet similar to the following one:
        jSlider.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                setMajorTickSpacing(jSlider, maxValue);
            }
        });
There is still room for improvement, like handling minimum values etc.
Feel free to improve the code. And please share it with us! :-)
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jul 1 2009
Added on Jun 3 2009
2 comments
275 views