我正在考虑在Swing中实现缩放操作(放大/缩小,平移)。主要问题是指需要绘制的1e + 06点/线所代表的数据量。
为了尽可能快地进行变焦操作,采用了以下方法。
1]我使用的是由缓冲图像 img 表示的屏幕外缓冲区。
2]在缩放操作期间,数据仍然是未链接的。不是绘制所有点,而是用屏幕外缓冲区替换当前图像。
g2d.drawImage(img, 0, 0, this);
有一个简单的例子说明了在随机生成的点上放大/缩小的基本操作:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ZoomOperations extends JPanel{
private boolean repaint;
private double zoom;
private List<Point2D.Double> points;
private AffineTransform at;
private BufferedImage img;
public ZoomOperations() {
repaint = true;
zoom = 0.1;
points = new ArrayList<>();
at = new AffineTransform();
img = null;
Random r = new Random();
for (int i = 0; i < 100; i++)
points.add(new Point2D.Double(5000 * r.nextDouble(), 5000 * r.nextDouble()));
addMouseWheelListener(new MouseAdapter() {
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getPreciseWheelRotation() < 0)
zoom = Math.min(zoom+= 0.02,2);
else
zoom = Math.max(zoom-= 0.02,0.01);
repaint();
}
});
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if (img == null)
img = (BufferedImage)createImage(5000, 5000);
at = g2d.getTransform();
at.translate(0, 0);
at.scale(zoom, zoom);
g2d.setTransform(at);
if (repaint){
Graphics2D g2c = img.createGraphics();
for (Point2D.Double p:points)
g2c.fillOval((int)p.x-50, (int)p.y-50, 50, 50);
g2c.dispose();
repaint = false; //Only illustrative example
}
g2d.drawImage(img, 0, 0, this);
}
public static void main(String[] args) {
JFrame jf = new JFrame();
jf.setSize(800, 600);
jf.add(new ZoomOperations());
jf.setVisible(true);
}
}
是否绘制点的决定是使用标志
进行的private boolean repaint;
缩放操作相对较快,但我不知道如何设置缓冲区的初始大小
img = (BufferedImage) createImage(5000, 5000); // How to set the size ?
以避免在添加新点时进入缓冲区。关于点坐标X,Y没有先验信息,变焦比为[1 / 100.0,100.0]。请记住,仿射变换会缩小/放大缓冲区的宽度和高度(缩放&lt; 1 / zoom&gt; 1)。
不幸的是,从屏幕外缓冲区中提取的矢量数据不是平滑的,而是光栅化的(像素在放大倍率下可见)......
还有更合适的方法吗?
感谢您的帮助......