Всякий раз, когда я нажимаю JSlider, он позиционирует один majorTick в направлении щелчка, а не прыгает на место, которое я на самом деле нажимаю. (Если ползунок находится в точке 47, и я нажимаю 5, он будет прыгать до 37 вместо 5). Есть ли способ изменить это при использовании JSliders, или мне нужно использовать другую структуру данных?
Вопрос JSlider: позиция после левого щелчка
Ответ 1
Как ни странно, это может выглядеть как Look and Feel, который контролирует это поведение. Взгляните на 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 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
Этот вопрос старый, но я сам столкнулся с этой проблемой. Это мое решение:
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
Это поведение происходит от ОС. Вы уверены, что хотите переопределить его и запутать пользователей? Я так не думаю.;)