Вопрос JSlider:Позиция после щелчка левой кнопкой мыши

StackOverflow https://stackoverflow.com/questions/518471

Вопрос

Всякий раз, когда я нажимаю на JSlider, он перемещается на одну большую точку в направлении щелчка вместо того, чтобы переходить к тому месту, которое я на самом деле нажимаю.(Если ползунок находится в точке 47, и я нажимаю 5, он перейдет к 37 вместо 5).Есть ли какой-нибудь способ изменить это при использовании JSliders, или я должен использовать другую структуру данных?

Это было полезно?

Решение

Каким бы странным это ни казалось, на самом деле такое поведение контролируется внешним видом.Взгляните на BasicSliderUI, метод , который вам нужно переопределить , является scrollDueToClickInTrack(int).

Для того, чтобы установить значение JSlider для получения ближайшего значения к тому месту, где пользователь нажал на дорожку, вам нужно было бы выполнить какой-нибудь необычный перевод между координатами мыши из getMousePosition() к действительному значению трека, принимая во внимание положение Component, это ориентация, размер и расстояние между галочками и т.д..К счастью, BasicSliderUI предоставляет нам две удобные функции для этого: valueForXPosition(int xPos) и valueForYPosition(int yPos):

JSlider slider = new JSlider(JSlider.HORIZONTAL);
slider.setUI(new MetalSliderUI() {
    protected void scrollDueToClickInTrack(int direction) {
        // this is the default behaviour, let's comment that out
        //scrollByBlock(direction);

        int value = slider.getValue(); 

        if (slider.getOrientation() == JSlider.HORIZONTAL) {
            value = this.valueForXPosition(slider.getMousePosition().x);
        } else if (slider.getOrientation() == JSlider.VERTICAL) {
            value = this.valueForYPosition(slider.getMousePosition().y);
        }
        slider.setValue(value);
    }
});

Другие советы

Этот вопрос довольно старый, но я только что сам столкнулся с этой проблемой.Это мое решение:

JSlider slider = new JSlider(/* your options here if desired */) {
    {
        MouseListener[] listeners = getMouseListeners();
        for (MouseListener l : listeners)
            removeMouseListener(l); // remove UI-installed TrackListener
        final BasicSliderUI ui = (BasicSliderUI) getUI();
        BasicSliderUI.TrackListener tl = ui.new TrackListener() {
            // this is where we jump to absolute value of click
            @Override public void mouseClicked(MouseEvent e) {
                Point p = e.getPoint();
                int value = ui.valueForXPosition(p.x);

                setValue(value);
            }
            // disable check that will invoke scrollDueToClickInTrack
            @Override public boolean shouldScroll(int dir) {
                return false;
            }
        };
        addMouseListener(tl);
    }
};

Это поведение является производным от операционной системы.Вы уверены, что хотите переопределить его и запутать пользователей?Я так не думаю.;)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top