java - 单击框架中的按钮后重新开始绘画

标签 java swing

我正在尝试在单击框架中的重新启动按钮后重新开始绘画。
但是单击按钮后,两个动画似乎开始协同工作,如下图所示:OutputGIF

点击按钮后,两个计数标签似乎同时工作,但绘画保持不变,并没有从初始位置开始。
我已经评论了按钮的 Action 监听器。
代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;

class Count {
    private int num;

    public Count() {
        this.num = 1;
    }

    // Generate Next Number
    public void generate(int currentNumber) {
        this.num = currentNumber;
        this.num += 1;
    }

    public int getNumber() {
        return this.num;
    }
}

interface Callback {
    public void action(int cnt);
}

class Panel extends JPanel {
    private final BufferedImage image;
    private Count count;
    private Callback onUpdate;


    public void setOnUpdateAction(Callback action) {
        this.onUpdate = action;
    }

    public Panel() {
        this.image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
        this.count = new Count();
        Timer timer = new Timer(0, ae -> createImage(image));
        timer.setDelay(1000);
        timer.start();
    }

    public void createImage(BufferedImage image) {
        Graphics g = image.getGraphics();

        int number = this.count.getNumber();

        // Set field on frame which will be added to bottomPanel
        for (int i = 0; i < (number * 20); i++) {
            for (int j = 0; j < (number * 20); j++) {
                g.setColor(Color.GRAY);
                g.fillRect(i, j, 20, 20);
                g.setColor(Color.GREEN);
                g.drawRect(i, j, 20, 20);
            }
        }

        // Generating next number
        this.count.generate(number);
        onUpdate.action(this.count.getNumber());
        repaint();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, null);
    }
}

class GUI extends JFrame {
    private JPanel leftPanel;
    private JPanel rightPanel;
    private JLabel countLabel;
    private JButton restartButton;

    public GUI() {

        /*Panels*/
        leftPanel = new JPanel();
        rightPanel = new JPanel();
        
        /* Button */
        restartButton = new JButton(UIManager.getIcon("FileView.directoryIcon"));
        
        leftPanel.add(restartButton);
        
        updateLabel(0);

        Panel matrixPanel = new Panel();
        matrixPanel.setPreferredSize(new Dimension(300, 300));

        matrixPanel.setOnUpdateAction(new Callback() {
            @Override
            public void action(int cnt) {
                countLabel.setText("Count #" + cnt);
            }
        });
        
        /* Restart Button, Action Listener */
        restartButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Panel mPanel = new Panel();
                mPanel.setPreferredSize(new Dimension(300, 300));
                System.out.println("New Defined");
                mPanel.setOnUpdateAction(new Callback() {
                    @Override
                    public void action(int cnt) {
                        countLabel.setText("Count #" + cnt);
                    }
                });
                rightPanel.add(mPanel);
            }
            
        });
        /* Action Listener Part End */

        rightPanel.add(matrixPanel);
        
        setLayout(new GridLayout(1, 2));
        
        add(leftPanel);
        add(rightPanel); 

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        pack();
    }

    public void updateLabel(int number) {
        /*Label - 1*/
        countLabel = new JLabel();
        countLabel.setName("CountLabel");
        countLabel.setText("Count #" + number);
        countLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 14));
        countLabel.setBounds(10, 5, 300, 20);

        leftPanel.add(countLabel);
    }
}

public class NumberPresentation {
    public static void main(String[] args) {
        new GUI().setVisible(true);
    }
}

在button的action listener中,我再次定义了Panel类的对象,并将其添加到添加到frame中的右侧面板。

如何对按钮进行编程,使其在单击后重新开始绘画?

最佳答案

当按下按钮时(在其分配的 Action 监听器中):

  • 在 Swing 定时器上调用 .stop()
  • 创建一个新的 BufferedImage 并将其分配给您的 BufferedImage 变量
  • 将计数对象重新设置回起始状态并重置用于绘制的所有状态字段
  • 然后重启Swing Timer

底线和总体目标是您希望将 GUI 返回到其原始状态,但该“状态”是已定义的。通常这意味着将关键状态字段返回到它们的原始值并重新创建任何已启动的动画循环(这里是您的 Swing 计时器)。

关于java - 单击框架中的按钮后重新开始绘画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63777936/

相关文章:

java - JPA 保留具有外键值的实体,但不想显式查找外键实体

java - Proguard 保留所有实现某个接口(interface)的内部类

java - 等待文本字段输入

java - 从线程内部操作 Swing 组件

java - 水平滚动+JTable+Java

java - 'BadPaddingException : pad block corrupted' while decrypting using AES/ECB

java - Java 中的 Func 编程。方法引用与函数应用签名不匹配但成功运行

java - 在java中创建一个gui元素

java - GlassFish SHA-256 摘要认证

java - 为什么这段代码注释可以作为JFrame运行?