pergunta JSlider: Posição após leftclick
-
21-08-2019 - |
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?
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. ;)