重新点击框架中的按钮后重新开始绘画

huangapple go评论69阅读模式
英文:

To restart painting after clicking button in frame

问题

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

点击按钮后,两个计数标签似乎同时工作,但绘画保持不变,不会从初始位置开始。
我已经在按钮的动作监听器中进行了注释。
代码:

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

class Count {
    // ...(省略代码)
}

interface Callback {
    // ...(省略代码)
}

class Panel extends JPanel {
    // ...(省略代码)
}

class GUI extends JFrame {
    // ...(省略代码)
}

public class NumberPresentation {
    // ...(省略代码)
}

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

我应该如何编写按钮的程序,以便在点击后重新启动绘画?

英文:

I am trying to restart the painting after clicking restart button in the frame.<br>
But after clicking the button, it seems that two animation start working together as you can see in the gif below: 重新点击框架中的按钮后重新开始绘画

After clicking the button, two count label seems to be working simultaneously but the painting remains the same and doesn't start from initial position.<br>
I have commented across the action listener of button.<br>
CODE:

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 -&gt; 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 &lt; (number * 20); i++) {
            for (int j = 0; j &lt; (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(&quot;FileView.directoryIcon&quot;));
        
        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(&quot;Count #&quot; + 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(&quot;New Defined&quot;);
                mPanel.setOnUpdateAction(new Callback() {
                    @Override
                    public void action(int cnt) {
                        countLabel.setText(&quot;Count #&quot; + 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(&quot;CountLabel&quot;);
        countLabel.setText(&quot;Count #&quot; + number);
        countLabel.setFont(new Font(&quot;Comic Sans MS&quot;, 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);
    }
}

In the action listener of button, I again define the object of Panel class and add it to the right panel which is added into the frame.

How can I program the button so that it will restart the painting after clicking it?

答案1

得分: 1

当按钮被按下(在其分配的动作监听器内):

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

最终目标是将 GUI 返回到其初始状态,不过这个“状态”是如何定义的。通常情况下,这意味着将关键状态字段恢复到其原始值,并重新创建任何已启动的动画循环(在这里就是你的 Swing 计时器)。

英文:

When button pressed (within its assigned action listener):

  • Call .stop() on the Swing Timer
  • Create a new BufferedImage and assign it to your BufferedImage variable
  • Re-set the count object back to starting state and reset any state fields that are used to do your drawing
  • Then restart the Swing Timer

The bottom line and general goal is that you want to return the GUI to its original state, however that "state" is defined. Usually this means returning key state-fields back to their original values and recreating any animation loops that were started (here, your Swing Timer).

huangapple
  • 本文由 发表于 2020年9月7日 20:47:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/63777936.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定