JSlider вопрос: Позиция после левого клика - PullRequest
13 голосов
/ 06 февраля 2009

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

Ответы [ 3 ]

18 голосов
/ 06 февраля 2009

Как бы странно это не выглядело, на самом деле это поведение выглядит и чувствует, что контролирует это поведение. Взгляните на 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);
    }
});
4 голосов
/ 02 июня 2009

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

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);
    }
};
0 голосов
/ 09 февраля 2009

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

...