Pergunta

Sempre que eu clicar em um JSlider fica posicionado um majorTick na direção do clique em vez de saltar para o lugar que eu realmente clicar. (Se cursor está no ponto 47 e clico 5 vai saltar para 37 em vez de 5). Existe alguma maneira de mudar isso enquanto estiver usando JSliders, ou eu tenho que usar uma outra estrutura de dados?

Foi útil?

Solução

Como bizarro que isso possa parecer, é realmente o olhar ea sensação que controla este comportamento. Dê uma olhada em BasicSliderUI, o método que você precisa de substituição é scrollDueToClickInTrack(int) .

Para definir o valor da JSlider para o valor mais próximo de onde o usuário clicou na pista, você precisa fazer alguma calças extravagantes tradução entre as coordenadas do mouse de getMousePosition() para um valor de trilha válido, tendo em conta a posição do Component, é orientação, tamanho e distância entre carrapatos etc . Felizmente, BasicSliderUI nos dá duas funções úteis para fazer isso: valueForXPosition(int xPos) e 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);
    }
});

Outras dicas

Esta questão é uma espécie de velho, mas eu só corri em toda esta problema sozinho. Esta é a minha solução:

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

Este comportamento é derivado de OS. Tem certeza de que deseja redefinir-lo e utilizadores confundem? Acho que não. ;)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top