首页 > 解决方案 > 单击框架中的按钮后重新开始绘画

问题描述

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

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

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

在按钮的动作监听器中,我再次定义了 Panel 类的对象并将其添加到右侧面板中,右侧面板被添加到框架中。

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

标签: javaswing

解决方案


按下按钮时(在其分配的动作侦听器内):

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

底线和一般目标是您希望将 GUI 恢复到其原始状态,但是定义了“状态”。通常这意味着将关键状态字段返回到其原始值并重新创建任何已启动的动画循环(此处为您的 Swing Timer)。


推荐阅读