使用鼠标和图形缩放

我在JComponent中绘制一些曲线等,使用Graphics G(非2D)。

现在我想使用鼠标的滚轮来放大和缩小。

任何曲目?

我听说过BuferredImage?

您需要考虑一些注意事项……

最终结果将取决于您想要实现的目标。 如果使用Graphics2D API绘制曲线,则每次渲染组件时简单地缩放坐标可能更简单。 您需要确保比例的任何更改都反映在组件本身的首选大小中。

例如,您还可以将“默认”输出呈现给BufferedImage并简单地使用AffineTransform来更改用于呈现结果的缩放比例。

这个简单使用BufferedImage并从磁盘加载图片,但基本概念是相同的。

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseWheelEvent; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class ZoomPane { public static void main(String[] args) { new ZoomPane(); } public ZoomPane() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new JScrollPane(new TestPane())); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private BufferedImage img; private float scale = 1; public TestPane() { try { img = ImageIO.read(new File("/path/to/image")); } catch (IOException ex) { ex.printStackTrace(); } addMouseWheelListener(new MouseAdapter() { @Override public void mouseWheelMoved(MouseWheelEvent e) { double delta = 0.05f * e.getPreciseWheelRotation(); scale += delta; revalidate(); repaint(); } }); } @Override public Dimension getPreferredSize() { Dimension size = new Dimension(200, 200); if (img != null) { size.width = Math.round(img.getWidth() * scale); size.height = Math.round(img.getHeight() * scale); } return size; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (img != null) { Graphics2D g2d = (Graphics2D) g.create(); AffineTransform at = new AffineTransform(); at.scale(scale, scale); g2d.drawImage(img, at, this); g2d.dispose(); } } } } 

您还可以直接缩放传递给paintComponent方法的Graphics上下文。

这里重要的是记住在完成后重置AffineTransform ,否则它将在渲染时传递给其他组件,这将不会生成预期的输出……

这个例子基本上创建了一个Graphics上下文的副本,我们可以在不影响原始的情况下操作和处理它,使得更容易弄乱

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseWheelEvent; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Path2D; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class ZoomPane { public static void main(String[] args) { new ZoomPane(); } public ZoomPane() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new JScrollPane(new TestPane())); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private float scale = 1; public TestPane() { addMouseWheelListener(new MouseAdapter() { @Override public void mouseWheelMoved(MouseWheelEvent e) { double delta = 0.05f * e.getPreciseWheelRotation(); scale += delta; revalidate(); repaint(); } }); } @Override public Dimension getPreferredSize() { Dimension size = new Dimension(200, 200); size.width = Math.round(size.width * scale); size.height = Math.round(size.height * scale); return size; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); AffineTransform at = new AffineTransform(); at.scale(scale, scale); g2d.setTransform(at); g2d.setColor(Color.RED); // This is for demonstration purposes only // I prefer to use getWidth and getHeight int width = 200; int height = 200; Path2D.Float path = new Path2D.Float(); int seg = width / 3; path.moveTo(0, height / 2); path.curveTo(0, 0, seg, 0, seg, height / 2); path.curveTo( seg, height, seg * 2, height, seg * 2, height / 2); path.curveTo( seg * 2, 0, seg * 3, 0, seg * 3, height / 2); g2d.draw(path); g2d.dispose(); } } } 

有关更多详细信息,请参阅转换形状,文本和图像

试试JFreeChart ; 用于控制ChartPanel缩放的setMouseWheelEnabled()方法在此处引用的示例中说明。