在面板中放大和缩小

我有一个面板,其中一些2D物体正在移动。 我已根据需要覆盖了paintComponent()。 现在我希望能够放大并缩小该区域。 放大时,将显示滚动条,通过滚动条可以查看整个字段。 在放大和缩小时,2D对象应相应地增大或减小尺寸。 哪个Swing组件或更确切的组件组合将有助于实现这一目标?

最简单的方法是修改面板并引入一个指示缩放级别的双精度。 这个双精度表示你的刻度,其中1是正常的,更高的是放大的。你可以在paintComponent中将这个双paintComponentGraphics2D一起使用。

如:

 Graphics2D g2 = (Graphics2D) g; int w = // real width of canvas int h = // real height of canvas // Translate used to make sure scale is centered g2.translate(w/2, h/2); g2.scale(scale, scale); g2.translate(-w/2, -h/2); 

对于滚动,将面板放在JScrollPane中,并将其与也使用缩放比例的getPreferredSize相结合。 JScrollPane使用您放入其中的组件的首选大小。 如果首选大小超过其自身大小,它将显示滚动条。

如果您更改面板的首选大小,使其返回的宽度和高度缩放,您应该没问题。 基本上你可以返回类似的东西:

 return new Dimension(w * scale, h * scale) 

我知道这个问题已经过时了,但我想我可以发布我的解决方案,以防将来对某人有用。

因此,我创建了一个扩展JPanel的类,该类实现了MouseWheelListener,以便检测用户何时滚动鼠标。 我的class级还会监听拖动,以便在用户点击和拖动时移动内容。

代码说明

首先,在构造函数中,您必须将其设置为MouseWheelListener

  addMouseWheelListener(this); 

对于放大和缩小,我使用布尔zoomer (用于指示用户何时使用鼠标滚动)和两个双精度zoomFactor (以保持当前因子乘以对象的大小)和prevZoomFactor (用于前一个缩放因子) 。

 private double zoomFactor = 1; private double prevZoomFactor = 1; private boolean zoomer; 

我还覆盖了JPanel的paint()方法,当用户缩放时(在绘制任何内容之前)( zoomer = true)我通过zoomFactor缩放图形。 码:

 @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; if (zoomer) { AffineTransform at = new AffineTransform(); at.scale(zoomFactor, zoomFactor); prevZoomFactor = zoomFactor; g2.transform(at); zoomer = false; } // All drawings go here } 

最后,我重写了MouseWheelListener的mouseWheelMoved方法,其中我增加了zoomFactor (如果用户卷起)或减小zoomFactor (如果用户滚动)。 码:

 @Override public void mouseWheelMoved(MouseWheelEvent e) { zoomer = true; //Zoom in if (e.getWheelRotation() < 0) { zoomFactor *= 1.1; repaint(); } //Zoom out if (e.getWheelRotation() > 0) { zoomFactor /= 1.1; repaint(); } } 

工作实例

如果你还想使用拖动function并想根据鼠标的位置进行缩放,你可以使用下面的类,它在构造函数中获取BufferedImage作为参数,以便在屏幕上显示某些内容。

我还在GitHub上传了一个名为Zoomable-Java-Panel的项目 ,其中有一个我上面展示的function示例,您可以测试它,看看它如何在项目中实现。

 package zoomable.panel; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.MouseInfo; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import javax.swing.JPanel; /** * * @author Thanasis1101 * @version 1.0 */ public class MainPanel extends JPanel implements MouseWheelListener, MouseListener, MouseMotionListener { private final BufferedImage image; private double zoomFactor = 1; private double prevZoomFactor = 1; private boolean zoomer; private boolean dragger; private boolean released; private double xOffset = 0; private double yOffset = 0; private int xDiff; private int yDiff; private Point startPoint; public MainPanel(BufferedImage image) { this.image = image; initComponent(); } private void initComponent() { addMouseWheelListener(this); addMouseMotionListener(this); addMouseListener(this); } @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; if (zoomer) { AffineTransform at = new AffineTransform(); double xRel = MouseInfo.getPointerInfo().getLocation().getX() - getLocationOnScreen().getX(); double yRel = MouseInfo.getPointerInfo().getLocation().getY() - getLocationOnScreen().getY(); double zoomDiv = zoomFactor / prevZoomFactor; xOffset = (zoomDiv) * (xOffset) + (1 - zoomDiv) * xRel; yOffset = (zoomDiv) * (yOffset) + (1 - zoomDiv) * yRel; at.translate(xOffset, yOffset); at.scale(zoomFactor, zoomFactor); prevZoomFactor = zoomFactor; g2.transform(at); zoomer = false; } if (dragger) { AffineTransform at = new AffineTransform(); at.translate(xOffset + xDiff, yOffset + yDiff); at.scale(zoomFactor, zoomFactor); g2.transform(at); if (released) { xOffset += xDiff; yOffset += yDiff; dragger = false; } } // All drawings go here g2.drawImage(image, 0, 0, this); } @Override public void mouseWheelMoved(MouseWheelEvent e) { zoomer = true; //Zoom in if (e.getWheelRotation() < 0) { zoomFactor *= 1.1; repaint(); } //Zoom out if (e.getWheelRotation() > 0) { zoomFactor /= 1.1; repaint(); } } @Override public void mouseDragged(MouseEvent e) { Point curPoint = e.getLocationOnScreen(); xDiff = curPoint.x - startPoint.x; yDiff = curPoint.y - startPoint.y; dragger = true; repaint(); } @Override public void mouseMoved(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { released = false; startPoint = MouseInfo.getPointerInfo().getLocation(); } @Override public void mouseReleased(MouseEvent e) { released = true; repaint(); } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } }