JSlider question: Position after leftclick

柔情痞子 提交于 2019-11-27 03:17:58

问题


Whenever I click a JSlider it gets positioned one majorTick in the direction of the click instead of jumping to the spot I actually click. (If slider is at point 47 and I click 5 it'll jump to 37 instead of 5). Is there any way to change this while using JSliders, or do I have to use another datastructure?


回答1:


As bizarre as this might seem, it's actually the Look and Feel which controls this behaviour. Take a look at BasicSliderUI, the method that you need to override is scrollDueToClickInTrack(int).

In order to set the value of the JSlider to the nearest value to where the user clicked on the track, you'd need to do some fancy pants translation between the mouse coordinates from getMousePosition() to a valid track value, taking into account the position of the Component, it's orientation, size and distance between ticks etc. Luckily, BasicSliderUI gives us two handy functions to do this: valueForXPosition(int xPos) and 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);
    }
});



回答2:


This question is kind of old, but I just ran across this problem myself. This is my solution:

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);
    }
};



回答3:


This behavior is derived from OS. Are you sure you want to redefine it and confuse users? I don't think so. ;)



来源:https://stackoverflow.com/questions/518471/jslider-question-position-after-leftclick

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!