JSlider - щелчок заставляет точку двигаться в этом направлении

У меня есть JSlider с минимальным значением 0 и максимальным значением 100. Когда JSlider запускается впервые, значение равно 0.

Теперь, когда я нажимаю мышью на 50, или даже на 20 или 100, JSlider не перемещается в то место, куда я нажимаю. Он просто прыгает немного вправо.

Как мне сделать так, чтобы значение переходило к тому, что я нажимаю?


person CodeGuy    schedule 17.08.2011    source источник
comment
почему вы хотите реализовать нестандартное поведение? Высокий потенциал запутать ваших пользователей .. Держите мышь нажатой, и большой палец в конечном итоге достигнет мыши   -  person kleopatra    schedule 18.08.2011


Ответы (2)


Вот начало класса, который будет делать то, что вам нужно.

Общая идея состоит в том, чтобы определить, где пользователь щелкает, и вычислить смещение значения, необходимое для соответствия этому новому положению ползунка.

// 'E' stands for enhanced
public class EJSlider extends JSlider {

   public EJSlider() {
      super();
      addMouseListener(new MouseAdapter() {
         @Override
         public void mousePressed(MouseEvent e) {
            Point p = e.getPoint();
            double percent = p.x / ((double) getWidth());
            int range = getMaximum() - getMinimum();
            double newVal = range * percent;
            int result = (int)(getMinimum() + newVal);
            setValue(result);
         }
      });
   }

   public static void main(String[] args) {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.add(new EJSlider());
      f.pack();
      f.setVisible(true);
   }
}

Просто запустите пример. Ползунок переместится туда, куда вы щелкнете мышью. Это не было тщательно протестировано и пока не будет работать с вертикальными ползунками.

Аналогичным решением для этого было бы простое добавление моего пользовательского MouseListener к любому JSlider, на котором вы хотели бы использовать эту функциональность.

(Обратите внимание, я знаю, что это еще не идеально, но это хорошее начало.)

person jjnguy    schedule 17.08.2011
comment
Я ожидал, что вы переопределите какой-то метод в JSlider. Непонятно, почему ваш метод вызывается после того, что в JSlider двигает ручку. - person toto2; 17.08.2011
comment
@toto2 toto2, мой метод вызывается как часть действия по щелчку мыши. Стандартный JSlider обрабатывает щелчок, перемещая ползунок на одну позицию. Мое действие переместит ползунок на значение, на которое нажимает пользователь. На самом деле не имеет значения, в каком порядке они происходят. - person jjnguy; 17.08.2011
comment
Я имею в виду, что стандартное движение JSlider также должно вызываться из обработчика событий щелчка мышью. Порядок будет неправильным, если ваш метод вызывается первым, а затем другой; ползунок окажется в неправильном месте. - person toto2; 17.08.2011
comment
@ toto2 toto2, я не уверен на 100%, что именно делает другой метод. Но я предполагаю, что он переместит указатель 1 к положению мыши. Такое поведение допустимо, если ползунок уже приблизился к мыши; на самом деле, это поможет переместить ползунок ближе. - person jjnguy; 17.08.2011
comment
@toto2 toto2, я обнаружил, что если вы удалите всех прослушивателей, функция перетаскивания компонента будет потеряна, но это можно исправить, добавив собственный прослушиватель движения мыши. - person jjnguy; 17.08.2011

BasicSliderUI предоставляет метод называется valueForXPosition< /а>:

Возвращает значение в позиции x. Если xPos находится за пределами дорожки слева или справа, этот метод устанавливает значение либо на минимальное, либо на максимальное значение ползунка, в зависимости от того, инвертирован ли ползунок или нет.

(Для вертикальных ползунков используйте valueForYPosition)

Пример добавления MouseListener к горизонтальному JSlider с использованием valueForXPosition:

JSlider slider = new JSlider();
slider.setOrientation(JSlider.HORIZONTAL);
slider.setMinimum(0);
slider.setMaximum(100); 
slider.addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
       JSlider sourceSlider=(JSlider)e.getSource();
       BasicSliderUI ui = (BasicSliderUI)sourceSlider.getUI();
       int value = ui.valueForXPosition( e.getX() );
       slider.setValue(value);
    }
});
person clic    schedule 07.08.2018