我必须绘制一些点和一个多边形来将它们连接在一起。自定义绘画将在带有 JScrollPane 的 JPanel 上完成,并通过 AffineTransformation 支持一些缩放/缩放。在将 JPanel 首选尺寸设置为由点坐标定义的所需尺寸并进行重新验证后,绘图将正确显示并且可以滚动。只要点坐标不超过数据类型整数、缩放和 Dimension 类的限制设置的某些限制,一切都很好。
示例:想象坐标处的四个点
(10000,10000), (10000,-10000), (-10000,10000), (-10000,-10000).
它们定义了以原点为中心的正方形的角。我的paintComponent 方法的简写形式:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// Backup original transform
AffineTransform originalTransform = g2d.getTransform();
// Set virtual drawing area to scroll through, scaled by zoomfactor
double viewZoomFactor = 1.0; // Will be set to other values != 1.0 later
// Because of the points coordinates a rectangle of size 20000 by 20000 is required
this.setPreferedSize(new Dimension(20000 * viewZoomFactor,20000 * viewZoomFactor));
this.revalidate();
// Move point of origin to the center
Point pointOfOrigin = new Point(10000, 10000);
// Translate all points and revert y-direction
AffineTransform t = AffineTransform.getTranslateInstance(
pointOfOrigin.x, this.getHeight() - pointOfOrigin.y)
t.scale(viewZoomFactor, -viewZoomFactor);
g2d.transform(t);
this.drawPointsAndPolygonOnPanel();
// Restore original transform
g2d.setTransform(originalTransform);
}
虽然 zoomFactor == 1.0 一个像素等于一个坐标值。
由于它们的构造函数Point(int, int)
,这些点可以通过 [Integer.MIN_VALUE, Integer.MAX_VALUE] 放置在 [Integer.MIN_VALUE, Integer.MAX_VALUE] 的平面内。JPanels 的首选大小是 type Dimension(int,int)
。通常宽度和高度的值是非负整数。
现在问题来自于巨大的坐标值:想象一组像这样的点:
(Integer.MAX_VALUE,Integer.MAX_VALUE),
(Integer.MAX_VALUE,Integer.MIN_VALUE),
(Integer.MIN_VALUE,Integer.MAX_VALUE),
(Integer.MIN_VALUE,Integer.MIN_VALUE)
我的第一个想法是引入另一个比例因子来缩小所有坐标值:
t.scale(viewZoomFactor * dataZoomFactor, -viewZoomFactor * dataZoomFactor);
这将导致像素与坐标值的比率降低:viewZoomFactor = 1.0 处的 1 个像素 = 1/dataZoomFactor 坐标值。
当要绘制的点放置在上述极端位置时,如何实现整个绘图的 1:1 缩放、可滚动的可见部分?如果 viewZoomFactor > 1.0(放大镜)怎么办?