Java 使用鼠标和图形缩放

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19643637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 19:05:12  来源:igfitidea点击:

zoom using mouse and graphics

javaswingawtzoom

提问by Choubidou

I draw in my JComponent some curves, etc .. with Graphics G ( not 2D ).

我在我的 JComponent 中绘制了一些曲线等......使用 Graphics G(不是 2D)。

Now I want to use the scroll wheel of my mouse to zoom in and out.

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

Any tracks ?

任何曲目?

I heard talk about a BuferredImage ?

我听说过一个 BuferredImage ?

回答by trashgod

Try JFreeChart; the setMouseWheelEnabled()method, used to control zooming in ChartPanel, is illustrated in examples cited here.

尝试JFreeChart; setMouseWheelEnabled()用于控制放大的方法ChartPanel此处引用的示例中进行了说明。

回答by MadProgrammer

There are a few considerations you need to take into account...

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

The end result will depend on what you want to achieve. If you are drawing curves using the Graphics2D API, it might be simpler to simply scale the coordinates each time the component is rendered. You will need to make sure that any changes in the scale are reflected in the preferred size of the component itself.

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

You could also render the "default" output to a BufferedImageand simply use an AffineTransformto change the scaling the is used to render the result, for example.

例如,您还可以将“默认”输出渲染为 aBufferedImage并简单地使用 anAffineTransform更改用于渲染结果的缩放比例。

This simple uses a BufferedImageand loads a picture from disk, but the basic concept is the same.

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

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();
            }
        }
    }

}

You could also scale the Graphicscontext passed to your paintComponentmethod directly.

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

The important thing here is to remember to reset the AffineTransformafter you have completed, otherwise it will be passed to other components when they are rendered, which won't generate the expected output...

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

This example basically creates a copy of the Graphicscontext which we can manipulate and dispose of without effecting the original, making it simpler to mess with

这个例子基本上创建了一个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();
        }
    }
}

Take a look at Transforming Shapes, Text and Imagesfor more details

查看变换形状、文本和图像以了解更多详细信息

回答by Younes Meridji

I put this simple code to show you how to use mouse wheel mouving by adding a MouseWheelListener to a JPanel:

我把这个简单的代码告诉你如何通过向 JPanel 添加一个 MouseWheelListener 来使用鼠标滚轮移动:

myJpanel.addMouseWheelListener(new MouseWheelListener() {               
   @Override
   public void mouseWheelMoved(MouseWheelEvent mwe) {
      jPanelMouseWheelMoved(mwe);
   }
});

To implement the mouse wheel listener:

要实现鼠标滚轮侦听器:

private void jPaneMouseWheelMoved(MouseWheelEvent mwe) {
    if(Event.ALT_MASK != 0) {
        if(mwe.getWheelRotation() > 0) {
            //here you put your code to scrool douwn or to minimize. 
            System.out.println(" minimize by "+(-1*mwe.getWheelRotation()));             
        }
        else if(mwe.getWheelRotation() < 0) {
            //here you put your code to scrool up or to maximize.
            System.out.println(" maximaze by "+(-1*mwe.getWheelRotation()));
        }           
    }        
}

You can adapt this exemple to zoom or to scrool what you want.

您可以调整此示例以缩放或滚动您想要的内容。