gpt4 book ai didi

java - JScrollPane setViewPosition After "Zoom"

转载 作者:行者123 更新时间:2023-12-02 15:42:09 25 4
gpt4 key购买 nike

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

我遇到的问题是使 JScrollPane View 看起来好像在调整图像大小后它仍然位于左上角的相同位置。我尝试了几种方法,似乎已经接近我想要的结果,但又不完全是。

这是找到缩放比例并设置位置的Listener:

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

这是调整大小并显示图像的 ImageComponent:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;

public class ImageComponent extends JComponent {
private static final long serialVersionUID = 1975488835382044371L;
private BufferedImage img = null;

private double scale = 0.0;

public ImageComponent() {}

public ImageComponent(BufferedImage img) {
this.displayPage(img);
}

@Override
public void paint(Graphics g) {
Graphics2D g2 = ((Graphics2D)g);
if(this.img != null) {
int width = (int)(this.img.getWidth() * this.scale);
int height = (int)(this.img.getHeight() * this.scale);
this.setPreferredSize(new Dimension(width, height));
g2.drawImage(this.img, 0, 0, width, height, null, null);
g2.dispose();
}
}

public void displayPage(BufferedImage pic) {
if(img != null) {
this.img = pic;
}
}

public BufferedImage getPage() {
return this.img;
}

public void setScale(double ratio) {
if(ratio > .04) {
this.scale = ratio;
this.repaint();
}
}

public double getScale() {
return this.scale;
}
}

ResizeViewport 会强制视口(viewport)在放大时显示整个 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() 方法返回“假”值。我使用以下代码解决了这个问题:

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

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

关于java - JScrollPane setViewPosition After "Zoom",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2067511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com