JScrollPane - масштаб относительно положения мыши
Мне нужно рассчитать новую позицию окна просмотра при увеличении изображения.
Пользовательский интерфейс построен следующим образом:
- ImagePanel рисует изображение
- ImagePanelWrapper - это JPanel, оборачивающая вокруг imagePanel
- JScrollPane содержит ImagePanelWrapper
При увеличении или уменьшении коэффициент масштабирования ImagePanel изменяется, и предпочтительный размер ImagePanel пересчитывается. Поэтому изображение на этой панели перемещается, даже если ImagePanel остается в той же точке просмотра.
Следующие методы вызываются, когда пользователь удерживает нажатой клавишу CTRL и использует колесо мыши. Данная точка является местоположением курсора, предоставленным MouseWheelListener. Благодаря функциональности этих методов изображение уже остается в том же верхнем левом положении при увеличении или уменьшении.
Проблема в том, что я просто не могу понять, как двигаться относительно мыши, как, например, Paint.NET. Есть идеи?
/**
*
*/
public void zoomOut(Point point) {
this.imagePanel.setZoom(this.imagePanel.getZoom() * 0.9f);
Point pos = this.getViewport().getViewPosition();
int newX = (int) (pos.x * 0.9f);
int newY = (int) (pos.y * 0.9f);
this.getViewport().setViewPosition(new Point(newX, newY));
this.imagePanel.revalidate();
this.imagePanel.repaint();
}
/**
*
*/
public void zoomIn(Point point) {
this.imagePanel.setZoom(this.imagePanel.getZoom() * 1.1f);
Point pos = this.getViewport().getViewPosition();
int newX = (int) (pos.x * 1.1f);
int newY = (int) (pos.y * 1.1f);
this.getViewport().setViewPosition(new Point(newX, newY));
this.imagePanel.revalidate();
this.imagePanel.repaint();
}
2 ответа
Если эти предположения верны:
- Указанная точка указана относительно левого верхнего угла области просмотра.
- Размеры области просмотра меньше, чем у базовой панели изображений.
Затем область просмотра можно отрегулировать так, чтобы курсор находился над той же точкой на изображении до и после операции масштабирования, если перемещать следующим образом:
/**
*
*/
public void zoomOut(Point point) {
this.imagePanel.setZoom(this.imagePanel.getZoom() * 0.9f);
Point pos = this.getViewport().getViewPosition();
int newX = (int)(point.x*(0.9f - 1f) + 0.9f*pos.x);
int newY = (int)(point.y*(0.9f - 1f) + 0.9f*pos.y);
this.getViewport().setViewPosition(new Point(newX, newY));
this.imagePanel.revalidate();
this.imagePanel.repaint();
}
/**
*
*/
public void zoomIn(Point point) {
this.imagePanel.setZoom(this.imagePanel.getZoom() * 1.1f);
Point pos = this.getViewport().getViewPosition();
int newX = (int)(point.x*(1.1f - 1f) + 1.1f*pos.x);
int newY = (int)(point.y*(1.1f - 1f) + 1.1f*pos.y);
this.getViewport().setViewPosition(new Point(newX, newY));
this.imagePanel.revalidate();
this.imagePanel.repaint();
}
Вот математика для полноты картины:
Вы должны быть в состоянии получить местоположение указателя мыши, используя point.x
а также point.y
- обратитесь к Point
документация здесь. В соответствии с MouseMotionEvent
документация здесь, point.x
а также point.y
относительно компонента под мышью (JScrollPane
).
Вы можете включить эти значения в свой расчет. Это то, что вы искали?