放大图像时,我需要计算视口(viewport)的新位置。

用户界面的构建如下:

  • ImagePanel绘制图像
  • ImagePanelWrapper是JPanel,包裹在imagePanel
  • 周围
  • JScrollPane包含ImagePanelWrapper

  • 放大或缩小时,将更改ImagePanel的缩放系数,并重新计算ImagePanel的首选大小。因此,即使ImagePanel停留在相同的视口(viewport)点,此面板上的图像也会移动。

    当用户按住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();
    }
    

    最佳答案

    如果这些假设是正确的:

  • 提供的Point相对于视口(viewport)的左上角。
  • 视口(viewport)的尺寸小于基础ImagePanel的尺寸。

  • 然后,可以按照以下方式调整视口(viewport),以使光标在缩放操作之前和之后位于图像中的同一点上:
     /**
     *
     */
    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();
    }
    

    这是出于完整性的数学考虑:

    关于java - JScrollPane-相对于鼠标位置缩放,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13155382/

    10-09 07:07