How to pan an image using your mouse in Java Swing

前端 未结 3 543
逝去的感伤
逝去的感伤 2020-12-31 23:55

I am creating a Java app that will allow users to view images and to pan the image using their mouse. To implement the panning of the image I use a combination of mous

相关标签:
3条回答
  • 2021-01-01 00:10

    I would do it in a different way. I would probably define an object called Image or similar. It would define a BufferedImage and two int values: x and y.

    The Image object would also have a draw() method that would just know how to draw an image to a Graphics2D object at the x, y location.

    On mouse events, I would modify the x and y values inside the Image object and under the paint of the component I would call image.draw(g2).

    0 讨论(0)
  • 2021-01-01 00:22

    +1 to @Dans answer.

    Here is an example I made, basically uses JPanel with added MouseAdapter and overrides mousePressed() and mouseDragged() methods. mouseDragged() method will increment x and y co-ordinates of image accordingly and will be drawn via paintComponent(...) of JPanel and Graphics2D#drawImage(Image img,int x,int y,ImageObserver io).

    Before click and drag of mouse:

    enter image description here

    After click and drag of mouse:

    enter image description here

    //necessary imports
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionAdapter;
    import java.awt.image.BufferedImage;
    import java.net.URL;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        /**
         * Default constructor
         */
        public Test() {
            initComponents();
        }
    
        /**
         * Initialize GUI and components (including ActionListeners etc)
         */
        private void initComponents() {
            JFrame frame = new JFrame("Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setResizable(false);
    
            PanPanel pp = null;
            try {
                pp = new PanPanel(ImageIO.read(new URL("http://www.sellcar.co.za/wp-content/uploads/2011/01/Porsche_911_Turbo.jpg")));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            frame.add(pp);
            //pack frame (size JFrame to match preferred sizes of added components and set visible
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
    
            /**
             * Create GUI and components on Event-Dispatch-Thread
             */
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        //set nimbus look and feel
                        for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                            if ("Nimbus".equals(info.getName())) {
                                UIManager.setLookAndFeel(info.getClassName());
                                break;
                            }
                        }
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                        e.printStackTrace();
                    }
                    //create GUI instance
                    Test test = new Test();
                }
            });
        }
    }
    
    class PanPanel extends JPanel {
    
        private int x, y;
        private int width = 400, height = 400;
        BufferedImage img;
        private final static RenderingHints textRenderHints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        private final static RenderingHints imageRenderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        private final static RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        static int startX, startY;
    
        public PanPanel(BufferedImage img) {
            x = 0;
            y = 0;
            this.img = img;
    
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent me) {
                    super.mousePressed(me);
                    startX = me.getX();
                    startY = me.getY();
                }
            });
    
            addMouseMotionListener(new MouseMotionAdapter() {
                @Override
                public void mouseDragged(MouseEvent me) {
                    super.mouseDragged(me);
    
                    if (me.getX() < startX) {//moving image to right
                        x -= 2;
                    } else if (me.getX() > startX) {//moving image to left
                        x += 2;
                    }
    
                    if (me.getY() < startY) {//moving image up
                        y -= 2;
                    } else if (me.getY() > startY) {//moving image to down
                        y += 2;
                    }
                    repaint();
                }
            });
        }
    
        @Override
        protected void paintComponent(Graphics grphcs) {
            super.paintComponent(grphcs);
            Graphics2D g2d = (Graphics2D) grphcs;
    
            //turn on some nice effects
            applyRenderHints(g2d);
    
            g2d.drawImage(img, x, y, null);
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(width, height);
        }
    
        public static void applyRenderHints(Graphics2D g2d) {
            g2d.setRenderingHints(textRenderHints);
            g2d.setRenderingHints(imageRenderHints);
            g2d.setRenderingHints(renderHints);
        }
    }
    
    0 讨论(0)
  • 2021-01-01 00:32

    Try using scrollRectToVisible(...) method instead of JViewport#setViewPosition(...):

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import javax.swing.*;
    public class HandScrollDemo {
      static class HandScrollListener extends MouseAdapter {
        private final Point pp = new Point();
        @Override public void mouseDragged(MouseEvent e) {
          JViewport vport = (JViewport)e.getSource();
          JComponent label = (JComponent)vport.getView();
          Point cp = e.getPoint();
          Point vp = vport.getViewPosition();
          vp.translate(pp.x-cp.x, pp.y-cp.y);
          label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
          //vport.setViewPosition(vp);
          pp.setLocation(cp);
        }
        @Override public void mousePressed(MouseEvent e) {
          pp.setLocation(e.getPoint());
        }
      }
      public JComponent makeUI() {
        JLabel label = new JLabel(new Icon() {
          TexturePaint TEXTURE = makeCheckerTexture();
          @Override public void paintIcon(Component c, Graphics g, int x, int y) {
            Graphics2D g2 = (Graphics2D)g.create();
            g2.setPaint(TEXTURE);
            g2.fillRect(x,y,c.getWidth(),c.getHeight());
            g2.dispose();
          }
          @Override public int getIconWidth()  { return 2000; }
          @Override public int getIconHeight() { return 2000; }
        });
        label.setBorder(BorderFactory.createLineBorder(Color.RED, 20));
        JScrollPane scroll = new JScrollPane(label);
        JViewport vport = scroll.getViewport();
        MouseAdapter ma = new HandScrollListener();
        vport.addMouseMotionListener(ma);
        vport.addMouseListener(ma);
        return scroll;
      }
      private static TexturePaint makeCheckerTexture() {
        int cs = 20;
        int sz = cs*cs;
        BufferedImage img = new BufferedImage(sz,sz,BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setPaint(Color.GRAY);
        for(int i=0; i*cs<sz; i++) { for(int j=0; j*cs<sz; j++) {
          if((i+j)%2==0) { g2.fillRect(i*cs, j*cs, cs, cs); }
        }}
        g2.dispose();
        return new TexturePaint(img, new Rectangle(0,0,sz,sz));
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          @Override public void run() { createAndShowGUI(); }
        });
      }
      public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new HandScrollDemo().makeUI());
        f.setSize(320, 320);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    }
    
    0 讨论(0)
提交回复
热议问题