2012-10-31 38 views
9

Tôi cần tính vị trí mới của chế độ xem khi phóng to hình ảnh.JScrollPane - Thu phóng tương đối so với vị trí chuột

Giao diện được xây dựng như sau:

  • ImagePanel vẽ hình ảnh
  • ImagePanelWrapper là một gói JPanel quanh imagePanel
  • JScrollPane chứa ImagePanelWrapper

Khi phóng to hoặc , hệ số zoom của ImagePanel được thay đổi và kích thước ưa thích của ImagePanel đang được tính toán lại. Do đó hình ảnh trên bảng điều khiển này di chuyển, mặc dù ImagePanel vẫn ở cùng một điểm nhìn.

Các phương pháp sau đây được gọi khi người dùng giữ phím CTRL và sử dụng bánh xe chuột. Điểm cho trước là vị trí con trỏ được cung cấp bởi MouseWheelListener. Với chức năng trong các phương pháp này, hình ảnh đã ở cùng vị trí trên cùng bên trái khi phóng to hoặc thu nhỏ.

Vấn đề là tôi không thể tìm ra cách di chuyển tương đối so với chuột, chẳng hạn như Paint.NET chẳng hạn. Bất kỳ ý tưởng?

/** 
* 
*/ 
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(); 
} 

Trả lời

34

Nếu các giả định này là đúng:

  • The Point cung cấp là tương đối so với góc trên bên trái của khung nhìn.
  • Kích thước của khung nhìn nhỏ hơn ImagePanel cơ bản.

Sau đó, khung nhìn có thể được điều chỉnh sao cho con trỏ là trên cùng một điểm trong hình ảnh trước và sau khi phẫu thuật zoom, nếu di chuyển theo cách sau đây:

/** 
* 
*/ 
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(); 
} 

Đây là toán học cho đầy đủ 'sake:

enter image description here

+1

+1 Awesome, answer. Tốt nhất tôi đã thấy trong một thời gian. – max

+0

bạn sir xứng đáng cảm ơn bạn :) – EyeSpy

+0

Tôi có một câu hỏi tương tự. Tôi đang cố gắng sử dụng AffineTransform để làm điều tương tự, và tôi đang gặp một số rắc rối khi áp dụng toán học từ câu hỏi này. Nếu bạn tìm thấy thời gian, bạn có thể giúp tôi không? http://stackoverflow.com/questions/37509908/zoom-in-at-mouse-cursor – bigblind

2

Bạn sẽ có thể có được vị trí của con trỏ chuột bằng point.xpoint.y - tham khảo các tài liệu hướng dẫn Pointhere. Theo tài liệu MouseMotionEventhere, point.xpoint.y liên quan đến thành phần dưới con chuột (số JScrollPane).

Bạn có thể kết hợp các giá trị này vào phép tính của mình. Đây có phải là điều bạn đang tìm kiếm không?

Các vấn đề liên quan