如何在java中拖动鼠标时制作新图片

时间:2013-08-13 13:29:38

标签: java swing graphics

我想创建一个可以使用鼠标在程序周围移动图片的程序,这是我的代码。我的代码设置了tempX和tempY的形状位置,我设置它来获取鼠标的位置,当拖动鼠标拖动时,图片将沿着鼠标移动。
*我不能把这个图片重新绘制,同时拖动我想念的鼠标吗? *添加chagnePositionVectors()

public class SiaemsiMouse extends JPanel implements MouseListener,MouseMotionListener {

int tempX = 330;
int tempY = 95;

// position of Siaemsi box
int posX[] = {tempX-30,tempX-30,tempX-30};
int posY[] = {tempY+305,tempY+80,tempY+55};

// position of Siaemsi stick
int posXS1[] = {tempX,tempX,tempX-3,tempX+8,tempX+20,tempX+17};
int posXS2[] = {tempX+20,tempX+20,tempX+17,tempX+28,tempX+40,tempX+37};
int posXS3[] = {tempX+40,tempX+40,tempX+37,tempX+48,tempX+60,tempX+57};
int posXS4[] = {tempX+60,tempX+60,tempX+57,tempX+68,tempX+80,tempX+77};
int posXS5[] = {tempX+80,tempX+80,tempX+77,tempX+88,tempX+100,tempX+97};
int posXS6[] = {tempX+100,tempX+100,tempX+97,tempX+108,tempX+120,tempX+117};
int posXS7[] = {tempX+120,tempX+120,tempX+117,tempX+128,tempX+140,tempX+137};

// All of y for stick are equals
int posYS1[] = {tempY,tempY,tempY-10,tempY-15,tempY-10,tempY};

public SiaemsiMouse(){
    addMouseMotionListener(this);
    addMouseListener(this);
}

public static void main(String[] args) {
    SiaemsiMouse siaemsimouse = new SiaemsiMouse();
    JFrame frame = new JFrame();
    frame.add(siaemsimouse);
    frame.setSize(800,600);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public void paintComponent(Graphics graphics){
    super.paintComponent(graphics);
    Graphics2D g2 = (Graphics2D) graphics;
    Random random = new Random();

    // Draw Siaemsi
    Ellipse2D.Double floor = new Ellipse2D.Double(posX[0],posY[0],200,50);
    Rectangle2D.Double body = new Rectangle2D.Double(posX[1],posY[1],200,250);
    Ellipse2D.Double top = new Ellipse2D.Double(posX[2],posY[2],200,50);
    g2.setPaint(Color.RED);
    g2.fill(floor);
    g2.fill(body);
    g2.setPaint(Color.BLACK);
    g2.fill(top);

    // Draw siaemsi's stick
    Rectangle2D.Double stick1 = new Rectangle2D.Double(posXS1[0],posYS1[0],18,100);
    GeneralPath path1 = new GeneralPath(GeneralPath.WIND_EVEN_ODD,posXS1.length);
    path1.moveTo(posXS1[1],posYS1[1]);
    for (int i = 2; i < posXS1.length; i++) {
        path1.lineTo(posXS1[i],posYS1[i]);
    }
    path1.closePath();

    Rectangle2D.Double stick2 = new Rectangle2D.Double(posXS2[0],posYS1[0],18,100);
    GeneralPath path2 = new GeneralPath(GeneralPath.WIND_EVEN_ODD,posXS2.length);
    path2.moveTo(posXS2[1],posYS1[1]);
    for (int i = 2; i < posXS2.length; i++) {
        path2.lineTo(posXS2[i],posYS1[i]);
    }
    path2.closePath();

    Rectangle2D.Double stick3 = new Rectangle2D.Double(posXS3[0],posYS1[0],18,100);
    GeneralPath path3 = new GeneralPath(GeneralPath.WIND_EVEN_ODD,posXS3.length);
    path3.moveTo(posXS3[1],posYS1[1]);
    for (int i = 2; i < posXS3.length; i++) {
        path3.lineTo(posXS3[i],posYS1[i]);
    }
    path3.closePath();

    Rectangle2D.Double stick4 = new Rectangle2D.Double(posXS4[0],posYS1[0],18,100);
    GeneralPath path4 = new GeneralPath(GeneralPath.WIND_EVEN_ODD,posXS4.length);
    path4.moveTo(posXS4[1],posYS1[1]);
    for (int i = 2; i < posXS4.length; i++) {
        path4.lineTo(posXS4[i],posYS1[i]);
    }
    path4.closePath();

    Rectangle2D.Double stick5 = new Rectangle2D.Double(posXS5[0],posYS1[0],18,100);
    GeneralPath path5 = new GeneralPath(GeneralPath.WIND_EVEN_ODD,posXS5.length);
    path5.moveTo(posXS5[1],posYS1[1]);
    for (int i = 2; i < posXS5.length; i++) {
        path5.lineTo(posXS5[i],posYS1[i]);
    }
    path5.closePath();

    Rectangle2D.Double stick6 = new Rectangle2D.Double(posXS6[0],posYS1[0],18,100);
    GeneralPath path6 = new GeneralPath(GeneralPath.WIND_EVEN_ODD,posXS6.length);
    path6.moveTo(posXS6[1],posYS1[1]);
    for (int i = 2; i < posXS6.length; i++) {
        path6.lineTo(posXS6[i],posYS1[i]);
    }
    path6.closePath();

    Rectangle2D.Double stick7 = new Rectangle2D.Double(posXS7[0],posYS1[0],18,100);
    GeneralPath path7 = new GeneralPath(GeneralPath.WIND_EVEN_ODD,posXS7.length);
    path7.moveTo(posXS7[1],posYS1[1]);
    for (int i = 2; i < posXS7.length; i++) {
        path7.lineTo(posXS7[i],posYS1[i]);
    }
    path7.closePath();

    g2.setPaint(new Color(153,153,0));
    g2.fill(stick1);
    g2.fill(path1);
    g2.setPaint(Color.BLACK);
    g2.draw(stick1);
    g2.draw(path1);
    g2.setPaint(new Color(153, 76, 0));
    g2.fill(stick2);
    g2.fill(path2);
    g2.setPaint(Color.BLACK);
    g2.draw(stick2);
    g2.draw(path2);
    g2.setPaint(new Color(255, 255, 0));
    g2.fill(stick3);
    g2.fill(path3);
    g2.setPaint(Color.BLACK);
    g2.draw(stick3);
    g2.draw(path3);
    g2.setPaint(new Color(0, 255, 128));
    g2.fill(stick4);
    g2.fill(path4);
    g2.setPaint(Color.BLACK);
    g2.draw(stick4);
    g2.draw(path4);
    g2.setPaint(new Color(102, 0, 56));
    g2.fill(stick5);
    g2.fill(path5);
    g2.setPaint(Color.BLACK);
    g2.draw(stick5);
    g2.draw(path5);
    g2.setPaint(new Color(255, 0, 127));
    g2.fill(stick6);
    g2.fill(path6);
    g2.setPaint(Color.BLACK);
    g2.draw(stick6);
    g2.draw(path6);
    g2.setPaint(new Color(224, 224, 56));
    g2.fill(stick7);
    g2.fill(path7);
    g2.setPaint(Color.BLACK);
    g2.draw(stick7);
    g2.draw(path7);

}

@Override
public void mouseClicked(MouseEvent e) {

}

@Override
public void mousePressed(MouseEvent e) {

}

@Override
public void mouseReleased(MouseEvent e) {

}

@Override
public void mouseEntered(MouseEvent e) {

}

@Override
public void mouseExited(MouseEvent e) {

}

@Override
public void mouseDragged(MouseEvent e) {
    changePositionVectors(e.getX(),e.getY());
}

@Override
public void mouseMoved(MouseEvent e) {

}
public void changePositionVectors(int xPos, int yPos){
    tempX = xPos;
    tempY = yPos;
    repaint();
}
}

2 个答案:

答案 0 :(得分:2)

我知道我认为你的问题。

  • 您假设如果您更改tempX和tempY,那么从它们派生的所有变量也会发生变化,
  • 但事实并非如此。使用tempX或tempY创建的任何变量在创建后都不会神奇地知道更改。
  • 您需要更改任何需要自己更改的变量,最简单的方法是创建一个获取tempX和tempY值并重新计算需要重新计算的所有其他字段的方法。
  • 考虑在paintComponent中创建和移动 的Shape和路径对象,可能在鼠标适配器代码中,只需在paintComponent中绘制Shape。

即,

public void changePositionVectors(int xPos, int yPos) {
  // set the fields that need to be set with x and y
  repaint();
}

修改
关于你的新代码:

public void changePositionVectors(int xPos, int yPos){
    tempX = xPos;
    tempY = yPos;
    repaint();
}

这没有任何修复,因为所有这一切都设置了tempX和tempY,再次,更改这些值不会神奇地改变最初使用这些字段创建的任何值。同样,您的changePositionVectors方法必须包含更多代码,这些代码实际上设置了绘制GUI所需的所有向量的值。


编辑我会采取完全不同于你和盒装的方式。我会:

  • 将所有内容绘制为BufferedImage
  • 将BufferedImage放入ImageIcon
  • 将ImageIcon放入JLabel
  • 将JLabel放入JLayeredPane
  • 将MouseListener和MouseMotionListener添加到JLabel。
  • 完成。

例如:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class SimpleDrawing {
   private static final int PREF_W = 780;
   private static final int PREF_H = 570;
   private static final int GAP = 1;
   private static final int BI_WIDTH = 200 + 2 * GAP;
   private static final int BI_HEIGHT = 300 + 2 * GAP;
   private static final int ELLIPSE_WIDTH = BI_WIDTH - 2 * GAP;
   private static final int ELLIPSE_HEIGHT = 50;
   private static final Color CAN_COLOR = Color.red;
   private JLayeredPane layeredPane = new JLayeredPane() {
      public Dimension getPreferredSize() {
         return SimpleDrawing.this.getPreferredSize();
      };
   };
   private JLabel imageLabel;
   private Point imageLabelPoint = new Point();

   public SimpleDrawing() {
      layeredPane.setOpaque(true);
      layeredPane.setBackground(Color.white);

      imageLabel = drawImageLabel();
      imageLabel.setLocation(imageLabelPoint);
      imageLabel.setSize(imageLabel.getPreferredSize());

      layeredPane.add(imageLabel, JLayeredPane.DEFAULT_LAYER);

      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      imageLabel.addMouseListener(myMouseAdapter);
      imageLabel.addMouseMotionListener(myMouseAdapter);
   }

   private JLabel drawImageLabel() {
      BufferedImage img = new BufferedImage(BI_WIDTH, BI_HEIGHT, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setColor(CAN_COLOR);
      int x = GAP;
      int y = BI_HEIGHT - ELLIPSE_HEIGHT - GAP;
      int width = ELLIPSE_WIDTH;
      int height = ELLIPSE_HEIGHT;
      g2.fillOval(x, y, width, height);

      y = GAP + ELLIPSE_HEIGHT / 2;
      width = ELLIPSE_WIDTH;
      height = BI_HEIGHT - ELLIPSE_HEIGHT / 2 - GAP - y;
      g2.fillRect(x, y, width, height);

      g2.setColor(Color.black);
      y = GAP;
      height = ELLIPSE_HEIGHT;
      g2.fillOval(x, y, width, height);

      g2.dispose();
      ImageIcon icon = new ImageIcon(img);      
      return new JLabel(icon);      
   }

   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   public JLayeredPane getLayeredPane() {
      return layeredPane;
   }

   private class MyMouseAdapter extends MouseAdapter {
      private boolean dragging = false;
      private Point srcLoc;
      private Point msePressLoc;

      @Override
      public void mousePressed(MouseEvent e) {
         if (e.getButton() != MouseEvent.BUTTON1) {
            return;
         }

         dragging = true;
         srcLoc = ((Component) e.getSource()).getLocation();
         msePressLoc = e.getLocationOnScreen();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (e.getButton() != MouseEvent.BUTTON1) {
            return;
         }

         dragging = false;
         moveTo(e);
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (!dragging) {
            return;
         }
         moveTo(e);
      }

      private void moveTo(MouseEvent e) {
         Point loc = e.getLocationOnScreen();
         Component comp = (Component) e.getSource();
         int x = loc.x - msePressLoc.x + srcLoc.x;
         int y = loc.y - msePressLoc.y + srcLoc.y;
         comp.setLocation(x, y);
         layeredPane.repaint();
      }
   }

   private static void createAndShowGui() {
      SimpleDrawing simpleDrawing = new SimpleDrawing();

      JFrame frame = new JFrame("Simple Drawing");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(simpleDrawing.getLayeredPane());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

答案 1 :(得分:2)

试试这个,这里基于@ HovercraftFullOfEels的评论我已经从paintComponent()移开...

编辑1:
添加了地板,车身和顶部物体。在O / P屏幕上抛出空指针异常但工作

编辑2:
仍显示NPE,修正:图像(蛋糕)没有像posX,posY那样移动,...阵列没有更新

class SiaemsiMouse extends JPanel implements MouseListener, MouseMotionListener {

    private int tempX = 330;
    private int tempY = 95;
    // position of Siaemsi box
    private int posX[] = {tempX - 30, tempX - 30, tempX - 30};
    private int posY[] = {tempY + 305, tempY + 80, tempY + 55};
    // position of Siaemsi stick
    private int posXS1[] = {tempX, tempX, tempX - 3, tempX + 8, tempX + 20, tempX + 17};
    private int posXS2[] = {tempX + 20, tempX + 20, tempX + 17, tempX + 28, tempX + 40, tempX + 37};
    private int posXS3[] = {tempX + 40, tempX + 40, tempX + 37, tempX + 48, tempX + 60, tempX + 57};
    private int posXS4[] = {tempX + 60, tempX + 60, tempX + 57, tempX + 68, tempX + 80, tempX + 77};
    private int posXS5[] = {tempX + 80, tempX + 80, tempX + 77, tempX + 88, tempX + 100, tempX + 97};
    private int posXS6[] = {tempX + 100, tempX + 100, tempX + 97, tempX + 108, tempX + 120, tempX + 117};
    private int posXS7[] = {tempX + 120, tempX + 120, tempX + 117, tempX + 128, tempX + 140, tempX + 137};
    // All of y for stick are equals
    private int posYS1[] = {tempY, tempY, tempY - 10, tempY - 15, tempY - 10, tempY};

    public SiaemsiMouse() {
        addMouseMotionListener(this);
        addMouseListener(this);
    }

    public static void main(String[] args) throws InterruptedException {
        SiaemsiMouse siaemsimouse = new SiaemsiMouse();
        JFrame frame = new JFrame();
        frame.add(siaemsimouse);
        frame.setSize(800, 600);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    //added objects here
    private Rectangle2D.Double stick1, stick2, stick3, stick4, stick5, stick6, stick7;
    private GeneralPath path1, path2, path3, path4, path5, path6, path7;
    //added more objects 
    private Ellipse2D.Double floor;
    private Rectangle2D.Double body;
    private Ellipse2D.Double top;

    @Override
    public void paintComponent(Graphics graphics) {
        Graphics2D g2 = (Graphics2D) graphics;
        super.paintComponent(graphics);     //If you use paintComponents() the previous image persists
        //Random random = new Random(); //No use for Random??

        // Draw Siaemsi
        g2.setPaint(Color.RED);
        g2.fill(floor);
        g2.fill(body);
        g2.setPaint(Color.BLACK);
        g2.fill(top);

        g2.setPaint(new Color(153, 153, 0));
        g2.fill(stick1);
        g2.fill(path1);
        g2.setPaint(Color.BLACK);
        g2.draw(stick1);
        g2.draw(path1);
        g2.setPaint(new Color(153, 76, 0));
        g2.fill(stick2);
        g2.fill(path2);
        g2.setPaint(Color.BLACK);
        g2.draw(stick2);
        g2.draw(path2);
        g2.setPaint(new Color(255, 255, 0));
        g2.fill(stick3);
        g2.fill(path3);
        g2.setPaint(Color.BLACK);
        g2.draw(stick3);
        g2.draw(path3);
        g2.setPaint(new Color(0, 255, 128));
        g2.fill(stick4);
        g2.fill(path4);
        g2.setPaint(Color.BLACK);
        g2.draw(stick4);
        g2.draw(path4);
        g2.setPaint(new Color(102, 0, 56));
        g2.fill(stick5);
        g2.fill(path5);
        g2.setPaint(Color.BLACK);
        g2.draw(stick5);
        g2.draw(path5);
        g2.setPaint(new Color(255, 0, 127));
        g2.fill(stick6);
        g2.fill(path6);
        g2.setPaint(Color.BLACK);
        g2.draw(stick6);
        g2.draw(path6);
        g2.setPaint(new Color(224, 224, 56));
        g2.fill(stick7);
        g2.fill(path7);
        g2.setPaint(Color.BLACK);
        g2.draw(stick7);
        g2.draw(path7);         
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        changePositionVectors(e.getX(), e.getY());
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @SuppressWarnings("empty-statement")
    public void changePositionVectors(int xPos, int yPos) {
        tempX = xPos;
        tempY = yPos;

        //calc pos...        
        posX = new int[]{tempX - 30, tempX - 30, tempX - 30};
        posY = new int[]{tempY + 305, tempY + 80, tempY + 55};
        // position of Siaemsi stick
        posXS1 = new int[]{tempX, tempX, tempX - 3, tempX + 8, tempX + 20, tempX + 17};
        posXS2 = new int[]{tempX + 20, tempX + 20, tempX + 17, tempX + 28, tempX + 40, tempX + 37};
        posXS3 = new int[]{tempX + 40, tempX + 40, tempX + 37, tempX + 48, tempX + 60, tempX + 57};
        posXS4 = new int[]{tempX + 60, tempX + 60, tempX + 57, tempX + 68, tempX + 80, tempX + 77};
        posXS5 = new int[]{tempX + 80, tempX + 80, tempX + 77, tempX + 88, tempX + 100, tempX + 97};
        posXS6 = new int[]{tempX + 100, tempX + 100, tempX + 97, tempX + 108, tempX + 120, tempX + 117};
        posXS7 = new int[]{tempX + 120, tempX + 120, tempX + 117, tempX + 128, tempX + 140, tempX + 137};
        // All of y for stick are equals
        posYS1 = new int[]{tempY, tempY, tempY - 10, tempY - 15, tempY - 10, tempY};

        floor = new Ellipse2D.Double(posX[0], posY[0], 200, 50);
        body = new Rectangle2D.Double(posX[1], posY[1], 200, 250);
        top = new Ellipse2D.Double(posX[2], posY[2], 200, 50);

        // Draw siaemsi's stick
        stick1 = new Rectangle2D.Double(posXS1[0], posYS1[0], 18, 100);
        path1 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, posXS1.length);
        path1.moveTo(posXS1[1], posYS1[1]);
        for (int i = 2; i < posXS1.length; i++) {
            path1.lineTo(posXS1[i], posYS1[i]);
        }
        path1.closePath();

        stick2 = new Rectangle2D.Double(posXS2[0], posYS1[0], 18, 100);
        path2 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, posXS2.length);
        path2.moveTo(posXS2[1], posYS1[1]);
        for (int i = 2; i < posXS2.length; i++) {
            path2.lineTo(posXS2[i], posYS1[i]);
        }
        path2.closePath();

        stick3 = new Rectangle2D.Double(posXS3[0], posYS1[0], 18, 100);
        path3 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, posXS3.length);
        path3.moveTo(posXS3[1], posYS1[1]);
        for (int i = 2; i < posXS3.length; i++) {
            path3.lineTo(posXS3[i], posYS1[i]);
        }
        path3.closePath();

        stick4 = new Rectangle2D.Double(posXS4[0], posYS1[0], 18, 100);
        path4 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, posXS4.length);
        path4.moveTo(posXS4[1], posYS1[1]);
        for (int i = 2; i < posXS4.length; i++) {
            path4.lineTo(posXS4[i], posYS1[i]);
        }
        path4.closePath();

        stick5 = new Rectangle2D.Double(posXS5[0], posYS1[0], 18, 100);
        path5 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, posXS5.length);
        path5.moveTo(posXS5[1], posYS1[1]);
        for (int i = 2; i < posXS5.length; i++) {
            path5.lineTo(posXS5[i], posYS1[i]);
        }
        path5.closePath();

        stick6 = new Rectangle2D.Double(posXS6[0], posYS1[0], 18, 100);
        path6 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, posXS6.length);
        path6.moveTo(posXS6[1], posYS1[1]);
        for (int i = 2; i < posXS6.length; i++) {
            path6.lineTo(posXS6[i], posYS1[i]);
        }
        path6.closePath();

        stick7 = new Rectangle2D.Double(posXS7[0], posYS1[0], 18, 100);
        path7 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, posXS7.length);
        path7.moveTo(posXS7[1], posYS1[1]);
        for (int i = 2; i < posXS7.length; i++) {
            path7.lineTo(posXS7[i], posYS1[i]);
        }
        path7.closePath();

        repaint();
    }
}