简体   繁体   English

JSlider问题:在leftclick之后的位置

[英]JSlider question: Position after leftclick

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. 每当我点击一个JSlider时,它会在点击方向上找到一个majorTick而不是跳到我实际点击的位置。 (If slider is at point 47 and I click 5 it'll jump to 37 instead of 5). (如果滑块位于第47点,我点击5,它将跳转到37而不是5)。 Is there any way to change this while using JSliders, or do I have to use another datastructure? 有没有办法在使用JSliders时改变这个,或者我是否必须使用另一个数据结构?

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) . 看一下BasicSliderUI ,你需要覆盖的方法是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 . 为了将JSlider的值设置为用户在轨道上单击的最近值,您需要在getMousePosition()的鼠标坐标到有效的轨道值之间进行一些花哨的裤子转换,同时考虑到Component位置,它的方向,大小和刻度之间的距离 Luckily, BasicSliderUI gives us two handy functions to do this: valueForXPosition(int xPos) and valueForYPosition(int yPos) : 幸运的是, 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);
    }
});

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

This behavior is derived from OS. 此行为源自OS。 Are you sure you want to redefine it and confuse users? 您确定要重新定义并混淆用户吗? I don't think so. 我不这么认为。 ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM