在循环内绘制矩形?

Drawing rectangle within the loop?

我正在尝试根据按钮内的 for 循环确定的坐标为矩形设置动画。这是我的 JComponent Class:

public class Rect extends JComponent {
    public int x;
    public int y;
    public int w;
    public int h;
    
    public Rect (int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        repaint();
    }

    @Override
    public void paintComponent(Graphics g)  {
        Graphics2D g2 = (Graphics2D) g;
        super.paintComponent(g);
        g2.setColor(Color.green);
        g2.drawRect(x+15, y+15, w, h);
    }
}

这是我的按钮和 buttonJFrame class:

public class MainFrame extends JFrame {
    Rect R = new Rect(15, 15, 50, 50);
    JPanel lm = new JPanel();
    LayoutManager lay = new OverlayLayout(lm);
    JButton animate = new JButton("animate");

    public MainFrame () {
        setSize(1200, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        lm.setLayout(lay);
        lm.add(R);
}
    animate.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) { 
               for (int k = 0; k < 500; k+=50) {
                R = new Rect(k, k, 50, 50);
               validate();
               repaint();
               }
           }   
  });
}

但是当我 运行 代码并单击按钮时,没有任何反应。怎么了?

编辑:我 运行 我的主框架 class 是这样的:

public class OrImage {
    public static void main(String[] args) throws Exception
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MainFrame mf = new MainFrame();
                mf.setVisible(true);
            }
        });   
    }
}

我更改了 class MainFrame 的代码,这样当您按下 animate 按钮时,会发生一些事情,但我没有不知道这是不是你想要的。

我没有更改 class Rect 并且我将 main() 方法添加到 MainFrame 只是为了将所有内容集中在一个 class.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;

public class MainFrame extends JFrame {
    Rect R = new Rect(15, 15, 50, 50);
    JPanel lm = new JPanel();
    LayoutManager lay = new OverlayLayout(lm);
    JButton animate = new JButton("animate");

    public MainFrame () {
        setSize(1200, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        lm.setLayout(lay);
        lm.add(R);
        animate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) { 
                for (int k = 0; k < 500; k+=50) {
                    R = new Rect(k, k, 50, 50);
                    lm.add(R);
                }
                lm.revalidate();
                lm.repaint();
            }   
        });
        add(lm, BorderLayout.CENTER);
        add(animate, BorderLayout.PAGE_END);
        setLocationByPlatform(true);
        setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new MainFrame());
    }
}

主要变化在方法上 actionPerformed()。您需要将 R 添加到 JPanel。您需要在 JPanel 上调用 revalidate(),因为您已经更改了它包含的组件数。在调用 revalidate() 之后,您应该调用 repaint()(同样,在 JPanel 上)使其重绘。

这是按下 animate 之前的样子。

这是按下 animate

后的样子

编辑

根据要求 – 带有动画。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
import javax.swing.Timer;

public class MainFrame extends JFrame {
    Rect R = new Rect(15, 15, 50, 50);
    JPanel lm = new JPanel();
    LayoutManager lay = new OverlayLayout(lm);
    JButton animate = new JButton("animate");
    private int  x;
    private int  y;
    private Timer  timer;

    public MainFrame () {
        setSize(1200, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        lm.setLayout(lay);
        lm.add(R);
        timer = new Timer(500, event -> {
            if (x < 500) {
                lm.remove(R);
                x += 50;
                y += 50;
                R = new Rect(x, y, 50, 50);
                lm.add(R);
                lm.revalidate();
                lm.repaint();
            }
            else {
                timer.stop();
            }
        });
        timer.setInitialDelay(0);
        animate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timer.start();
            }   
        });
        add(lm, BorderLayout.CENTER);
        add(animate, BorderLayout.PAGE_END);
        setLocationByPlatform(true);
        setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new MainFrame());
    }
}