Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JScrollPane setViewPosition在“后”;“缩放”;_Java_Image_Zooming_Jscrollpane - Fatal编程技术网

Java JScrollPane setViewPosition在“后”;“缩放”;

Java JScrollPane setViewPosition在“后”;“缩放”;,java,image,zooming,jscrollpane,Java,Image,Zooming,Jscrollpane,我这里的代码是使用MouseAdapter,让用户在想要放大的图像区域周围“绘制”一个框,并计算框与图像的比率。然后将图像调整为计算出的比例。这部分是有效的 我遇到的问题是使JScrollPane视图在图像调整大小后仍处于相同的左上角位置。我尝试了几种方法,似乎已经接近我想要的结果,但并不完全如此 这是查找比例并设置位置的侦听器: import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.a

我这里的代码是使用MouseAdapter,让用户在想要放大的图像区域周围“绘制”一个框,并计算框与图像的比率。然后将图像调整为计算出的比例。这部分是有效的

我遇到的问题是使JScrollPane视图在图像调整大小后仍处于相同的左上角位置。我尝试了几种方法,似乎已经接近我想要的结果,但并不完全如此

这是查找比例并设置位置的侦听器:

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Graphics;
import java.awt.Point;

import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.JComponent;

public class DynamicZoom extends MouseAdapter {

private Point start;
private Point end;
private double zoom = 1.0;
private JScrollPane pane;
private JViewport port;


public void mousePressed(MouseEvent e) {
    if(e.getButton() == MouseEvent.BUTTON1) {
        this.pane = (JScrollPane)e.getSource();
        this.port = pane.getViewport();
        start = e.getPoint();
    }
}

public void mouseReleased(MouseEvent e) {
    if(this.pane != null) {
        Point curr = this.port.getViewPosition();
        end = e.getPoint();

        ImageComponent canvas = (ImageComponent)this.port.getView();
        zoom = canvas.getScale();
        double factor = 0.0;
        double selectedWidth = Math.abs(end.getX() - start.getX());
        double selectedHeight = Math.abs(end.getY() - start.getY());
        if(selectedWidth > selectedHeight)
            factor = this.port.getWidth() / selectedWidth;
        else
            factor = this.port.getHeight() / selectedHeight;

        zoom *= factor;
        int x = (int)((start.x+curr.x)*zoom);
        int y = (int)((start.y+curr.y)*zoom);

        Point point = new Point(x, y);

        ((ImageComponent)(this.port.getView())).setScale(zoom);

        ResizeViewport.resize(pane);
        this.port.setViewPosition(point);
    }
}

public void mouseDragged(MouseEvent e) {
    if(this.pane != null) {
        Graphics g = this.port.getGraphics();
        int width = this.start.x - e.getX();
        int height = this.start.y - e.getY();

        int w = Math.abs( width );
        int h = Math.abs( height );
        int x = width < 0 ? this.start.x : e.getX();
        int y = height < 0 ? this.start.y : e.getY();
        g.drawRect(x, y, w, h);
        this.port.repaint();
    }
}
“ResizeViewport”强制视口在放大时显示整个ImageComponent,因为否则它将按照以前的大小剪裁图像:

import java.awt.Dimension;

import javax.swing.JScrollPane;
public class ResizeViewport {
public static void resize(JScrollPane scroll) {
    int vw = scroll.getWidth()-scroll.getVerticalScrollBar().getWidth();
    int vh = scroll.getHeight()-scroll.getHorizontalScrollBar().getHeight();
    scroll.getViewport().setViewSize(new Dimension(vw, vh));
}
}

事实证明,用于计算位置的数学或我设计代码的方式没有问题。问题是,在计算位置时,ImageComponent仍在另一个线程中绘制;因此,为getWidth()和getHeight()方法返回“false”值。我使用以下代码解决了该问题:

EventQueue.invokeLater(new Runnable() {
   public void run() {
      port.setViewPosition(new Point(x,y));
   }
});

这允许在尝试计算图像大小并在JScrollPane中设置位置之前完成绘制。问题解决了。我仍然想感谢那些花时间至少审查了这个问题的人。

我也有类似的问题,但有时面板在调整大小后第一次被涂错了颜色,经过几个小时的努力找到了解决办法,我找到了一个解决方案

在scrollpane中调整面板大小后,最好是通过设置为null来销毁视口,然后将面板添加回scrollpane,这样将重新创建一个新视口,并且一切正常

// Old viewport has to be replaced
scrollPane.setViewport(null);
scrollPane.setViewportView(zoomablePanel);

/Anders

请告诉我们在哪里可以找到ImageComponent和ResizeViewport。您能发布一些简单的代码来说明如何使用它吗?也许我做错了,但我一直得到ClassCastException,因为DynamicZoom试图将我单击的JLabel转换为JScrollPane。我知道这个问题已经存在10年了,但这解决了我几天来一直试图修复的一个bug。谢谢
// Old viewport has to be replaced
scrollPane.setViewport(null);
scrollPane.setViewportView(zoomablePanel);