如何在Java Swing中使用鼠标平移图像

时间:2012-11-12 10:16:56

标签: java image swing point jviewport

我正在创建一个Java应用程序,允许用户查看图像并使用鼠标平移图像。为了实现图像的平移,我使用JViewports组合mouseClickedmouseDragged事件。大部分代码都在mouseDragged方法中

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

虽然这有效,但我觉得必须有一种更简单的方法来完成所有这些工作。如果不是全部的话,是否可以替换防止视口从图像到周围边界的代码?

3 个答案:

答案 0 :(得分:8)

尝试使用scrollRectToVisible(...)方法代替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);
  }
}

答案 1 :(得分:3)

我会以不同的方式做到这一点。我可能会定义一个名为Image或类似的对象。它会定义BufferedImage和两个int值:xy

Image对象还有一个draw()方法,该方法只知道如何将图像绘制到Graphics2D位置的x, y对象。

在鼠标事件中,我会修改x对象内的yImage值以及我将调用paint组件的image.draw(g2)下的值

答案 2 :(得分:3)

+1给@Dans回答。

以下是我制作的示例,主要使用添加了MouseAdapter的JPanel并覆盖mousePressed()mouseDragged()方法。 mouseDragged()方法会相应地增加xy图像的坐标,并将通过paintComponent(...)JPanel的{​​{1}}绘制。

在点击并拖动鼠标之前:

enter image description here

点击并拖动鼠标后:

enter image description here

Graphics2D#drawImage(Image img,int x,int y,ImageObserver io)