Метки ползунка Java Swing не обновляются в соответствии с минимальными/максимальными значениями ползунка

Таблица меток на моем JSlider не обновляется в соответствии с минимальными и максимальными значениями ползунка при изменении этих значений. Минимальные/максимальные значения обновляются правильно, так как методы getMinimum() и getMaximum() возвращают правильные значения. Автоматические метки под ползунком показывают неверные значения.

Ниже приведен отдельный пример с этой проблемой. Код в основном автоматически генерируется построителем окон Eclipse/конструктором Swing.

Нажатие кнопок по бокам ползунка изменяет максимальное значение ползунка.

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JSlider;
import javax.swing.JLabel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class SliderTrouble implements ActionListener
{

    private JFrame frame;
    private JSlider slider;
    private JLabel lblMin;
    private JLabel lblMax;
    private JLabel lblCurrent;
    private int sliderMax = 100;
    private int sliderMajorSpacing = sliderMax / 4;

    /**
     * Launch the application.
     */
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    SliderTrouble window = new SliderTrouble();
                    window.frame.setVisible(true);
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public SliderTrouble()
    {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize()
    {
        frame = new JFrame();
        frame.setTitle("Slider problems");
        frame.setBounds(100, 100, 481, 122);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new BorderLayout(0, 0));

        JPanel panel = new JPanel();
        frame.getContentPane().add(panel, BorderLayout.CENTER);

        JButton btnNewButton = new JButton("100");
        btnNewButton.setBounds(10, 22, 64, 23);
        btnNewButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                System.out.println("Pressed 100. Since this is the default value, everything is ok.");
                sliderMax = 100;
                sliderMajorSpacing = sliderMax / 4;
                changeSlider(sliderMax, sliderMajorSpacing);
            }
        });
        panel.setLayout(null);
        panel.add(btnNewButton);

        class SliderListener implements ChangeListener
        {
            public void stateChanged(ChangeEvent e)
            {
                JSlider slider = (JSlider) e.getSource();
                if (slider.getValueIsAdjusting())
                {
                    updateCurrent(slider.getValue());
                }
            }
        }

        slider = new JSlider();
        slider.setBounds(79, 11, 300, 45);
        slider.setMajorTickSpacing(sliderMajorSpacing);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        slider.setMaximum(sliderMax);
        slider.addChangeListener(new SliderListener());
        panel.add(slider);

        JButton btnNewButton_1 = new JButton("196");
        btnNewButton_1.setBounds(389, 22, 62, 23);
        btnNewButton_1.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                System.out.println("Pressed 196. The actual minimum and maximum values are updated correctly. getValue gets the correct value. The little gray tick lines are not updated accordingly. The text labels are done according to the default (button '100') settings, showing a max at 175 instead of 196. 175 is the closest multiple of 25 (which is the default major tick space).");
                sliderMax = 196;
                sliderMajorSpacing = sliderMax / 4;
                changeSlider(sliderMax, sliderMajorSpacing);
            }
        });

        panel.add(btnNewButton_1);

        JPanel panel_1 = new JPanel();
        frame.getContentPane().add(panel_1, BorderLayout.SOUTH);

        JLabel lblSliderMin = new JLabel("Slider min:");
        panel_1.add(lblSliderMin);

        lblMin = new JLabel();
        lblMin.setText(String.valueOf(slider.getMinimum()));
        panel_1.add(lblMin);

        JLabel lblMax_1 = new JLabel("max:");
        panel_1.add(lblMax_1);

        lblMax = new JLabel();
        lblMax.setText(String.valueOf(slider.getMaximum()));
        panel_1.add(lblMax);

        JLabel lblCur = new JLabel("current:");
        panel_1.add(lblCur);

        lblCurrent = new JLabel();
        lblCurrent.setText(String.valueOf(slider.getValue()));
        panel_1.add(lblCurrent);

        //frame.pack();
    }

    private void changeSlider(int max, int majspace)
    {
        slider.setMajorTickSpacing(majspace);
        slider.setMaximum(max);

        System.out.println("max: " + max + " major: " + sliderMajorSpacing);

        updateText(slider.getMinimum(), slider.getMaximum(), slider.getValue());
    }

    private void updateText(int minimum, int maximum, int value)
    {
        lblMin.setText(String.valueOf(minimum));
        lblMax.setText(String.valueOf(maximum));
        lblCurrent.setText(String.valueOf(value));
    }

    private void updateCurrent(int value)
    {
        lblCurrent.setText(String.valueOf(value));
    }

    public void actionPerformed(ActionEvent arg0)
    {   
    }
}

person Demian Wright    schedule 02.05.2015    source источник
comment
Что вы ожидаете от ярлыков? Расстояние между делениями составляет 25, поэтому максимальное значение, которое может быть показано, равно 175 для большого диапазона 196.   -  person kiheru    schedule 02.05.2015
comment
Расстояние между основными тиками изменяется в методе changeSlider, который вызывается при нажатии одной из кнопок. Я ожидаю, что метки изменятся при изменении расстояния между галочками.   -  person Demian Wright    schedule 02.05.2015


Ответы (1)


Похоже, что setMajorTickSpacing() на самом деле ничего не обновляет при вызове ползунка с предыдущим набором меток. Это можно обойти, позвонив

slider.setLabelTable(null);

перед установкой нового интервала деления, чтобы принудительно воссоздать метки.

person kiheru    schedule 02.05.2015
comment
Я мог бы поклясться, что пробовал это. Это решает проблему. Спасибо. - person Demian Wright; 03.05.2015