Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
482 views
in Technique[技术] by (71.8m points)

swing - Animating a Rectangle in Java

I've been trying to get this rectangle to move that I've created using a for loop. All that's happening with this code is that there is an original rectangle and then a new one next to that rectangle. No animation happens, only those two rectangles show on the window. What are some methods to get this rectangle to animate?

import java.awt.*;
import javax.swing.*;

public class Gunman extends JComponent {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public int x = 10;
    public int y = 10;
    public int width = 8;
    public int height = 10;
    public void paint(Graphics g) {
        g.setColor(Color.red);
        g.drawRect (x, y, width, height);  
        g.fillRect (x, y, width, height);
        for(int i = 0; i<=1024; i++){
            g.setColor(Color.red);
            g.drawRect(x++, y, width, height);
            g.fillRect(x++, y, width, height);
        }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Don't have program logic in a paint or paintComponent method, and by logic, I mean the for loop with "motion" as that just won't work. You want to

  • Almost never draw in a JComponent's paint method but rather in its paintComponent method.
  • Don't forget to call the super.paintComponent(g) method too, often as the first method call in the paintComponent(g) override.
  • Use a Swing Timer to step wise change the x and y values
  • call repaint() on the JComponent after the changes are made

For example

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Gunman extends JComponent {

   private static final long serialVersionUID = 1L;
   private static final int PREF_W = 900;
   private static final int PREF_H = 700;
   private static final int TIMER_DELAY = 30;
   public int rectX = 10;
   public int rectY = 10;
   public int width = 8;
   public int height = 10;

   public Gunman() {
      new Timer(TIMER_DELAY, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent actEvt) {
            if (rectX < PREF_W && rectY < PREF_H) {
               rectX++;
               rectY++;
               repaint();
            } else {
               ((Timer)actEvt.getSource()).stop();
            }
         }
      }).start();
   }


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

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.red);
      g.drawRect(rectX, rectY, width, height);
      g.fillRect(rectX, rectY, width, height);
   }

   public int getRectX() {
      return rectX;
   }

   public void setRectX(int rectX) {
      this.rectX = rectX;
   }

   public int getRectY() {
      return rectY;
   }

   public void setRectY(int rectY) {
      this.rectY = rectY;
   }

   private static void createAndShowGui() {
      Gunman mainPanel = new Gunman();

      JFrame frame = new JFrame("Gunman");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...