масштабирование с использованием мыши и графики

Я рисую в своем JComponent несколько кривых и т. Д. С помощью Graphics G (а не 2D).

Теперь я хочу использовать колесо прокрутки мыши для увеличения и уменьшения масштаба.

Любые треки?

Я слышал разговоры о BuferredImage?

Есть несколько соображений, которые необходимо учитывать …

Конечный результат будет зависеть от того, чего вы хотите достичь. Если вы рисуете кривые с использованием API Graphics2D, проще всего просто масштабировать координаты при каждом рендеринге компонента. Вам нужно будет убедиться, что любые изменения в масштабе отражаются в предпочтительном размере самого компонента.

Вы также можете сделать вывод по умолчанию в 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(); } } } } 

Вы также можете масштабировать контекст Graphics переданный непосредственно вашему методу paintComponent .

Важно помнить о том, чтобы сбросить 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 ; метод setMouseWheelEnabled() , используемый для управления масштабированием в ChartPanel , проиллюстрирован в приведенных здесь примерах.

Давайте будем гением компьютера.