How to pan an image with the mouse in Java Swing

I am creating a Java application that will allow users to view images and pan the image with the mouse. To implement image panning, I use a combination of mouseClicked and mouseDragged events using JViewports. The bulk of the code is in the mouseDragged method.

 public void mouseDragged(MouseEvent e, WindowWrapper w) { final JViewport vp = someFieldViewPort; //Getting the point that the mouse is dragged to to Point cp = e.getPoint(); final Point vPoint = vp.getViewPosition(); //I found the image went off the content to show the white border so I included this // Here pp is a field that I sent when the mouse is clicked in a separate method if(vPoint.getX()+pp.x-cp.x>=0 & vPoint.getY()+pp.y-cp.y>=0) vPoint.translate(pp.x-cp.x, pp.y-cp.y); else if(vPoint.getX()+pp.x-cp.x>=0 & vPoint.getY()+pp.y-cp.y<0) vPoint.translate(pp.x-cp.x, (int) -vPoint.getY()); else if(vPoint.getX()+pp.x-cp.x<0 & vPoint.getY()+pp.y-cp.y>=0) vPoint.translate((int) -vPoint.getX(), pp.y-cp.y); //finally set the position of the viewport vp.setViewPosition(vPoint); vp.repaint(); } 

While this works, I feel that there should be an easier way to do all this. If not for all this, is it possible to replace the code in order to exclude the image from being displayed on the surrounding border?

+4
source share
3 answers

Try using the scrollRectToVisible(...) method instead of the 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); } } 
+8
source

I would do it differently. I would probably call an object named Image or similar. It will determine the BufferedImage values ​​and two int : x and y .

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

In mouse events, I would change the x and y values ​​inside the Image object and under the paint component, which I would call image.draw(g2) .

+3
source

+1 to @ Answer.

Here is an example that I did, mainly using a JPanel with added MouseAdapter and overriding the mousePressed() and mouseDragged() methods. mouseDragged() will increase the x and y coordinates of the image, respectively, and will be output via paintComponent(...) from JPanel and Graphics2D#drawImage(Image img,int x,int y,ImageObserver io) .

Before clicking and dragging the mouse:

enter image description here

After mouse click and drag:

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); } } 
+3
source

Source: https://habr.com/ru/post/1445480/


All Articles