java - 在每个间隔后更改帧的显示,就像动画一样
问题描述
我如何在这里使用重绘,它会在一段时间后改变显示,就像动画一样?
输出:
(就像最初和随机一样)this-1(经过一段时间后随机变为)this-2并继续......
import java.awt.*;
import java.util.Random;
import javax.swing.*;
class MatrixPanel extends JPanel {
private final int sqW = 15;
private final int sqH = 15;
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
@Override
public void paintComponent(Graphics g) {
Random rand = new Random();
for (int i = 0; i < 300; i += this.sqW) {
for (int j = 0; j < 300; j += this.sqH) {
if (rand.nextInt(2) == 1) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.GRAY);
}
g.fillRect(i, j, this.sqW, this.sqH);
g.setColor(Color.BLACK);
g.drawRect(i, j, this.sqW, this.sqH);
}
}
}
}
class GameOfLifeGUI extends JFrame {
public GameOfLifeGUI() {
JSplitPane splitPane = new JSplitPane();
/*Panels*/
JPanel topPanel = new JPanel();
JPanel bottomPanel = new JPanel();
/*Label - 1*/
JLabel generationLabel = new JLabel("GenerationLabel");
generationLabel.setText("Generation #");
generationLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 14));
generationLabel.setBounds(10, 5, 300, 20);
/*Label - 2*/
JLabel aliveLabel = new JLabel("AliveLabel");
aliveLabel.setText("Alive: ");
aliveLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 14));
aliveLabel.setBounds(10, 25, 300, 20);
topPanel.setLayout(null);
topPanel.add(generationLabel);
topPanel.add(aliveLabel);
bottomPanel.add(new MatrixPanel());
setPreferredSize(new Dimension(315, 405));
getContentPane().setLayout(new GridLayout());
getContentPane().add(splitPane);
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
splitPane.setDividerLocation(50);
splitPane.setTopComponent(topPanel);
splitPane.setBottomComponent(bottomPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
pack();
}
public static void main(String[] args) {
new GameOfLifeGUI().setVisible(true);
}
}
具体不重绘,如果有其他我可以使用并满足我的要求的组件将是最受欢迎的。
谢谢你。
解决方案
您不想执行以下操作:
public void paintComponent(Graphics g) {
Random rand = new Random();
for (int i = 0; i < 300; i += this.sqW) {
for (int j = 0; j < 300; j += this.sqH) {
if (rand.nextInt(2) == 1) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.GRAY);
}
g.fillRect(i, j, this.sqW, this.sqH);
g.setColor(Color.BLACK);
g.drawRect(i, j, this.sqW, this.sqH);
}
}
}
由于绘画是在 EDT 上完成的,因此您需要将处理保持在最低限度,否则性能会受到影响,甚至可能会锁定您的应用程序。
使用Swing 计时器并在BufferedImage对象中创建图像。BufferedImages 提供了一个图形上下文,因此您可以使用您在paintComponent
.
您可以将计时器间隔设置为适合您的任何时间,然后在创建图像时发出重绘。所以它可能类似于以下内容:
final BufferedImage image = new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
...
Timer timer = new Timer(0, ae->createImage());
timer.setDelay(300);
timer.start();
...
public void createImage(BufferedImage image) {
Random rand = new Random();
Graphics g = image.getGraphics();
for (int i = 0; i < 300; i += this.sqW) {
for (int j = 0; j < 300; j += this.sqH) {
if (rand.nextInt(2) == 1) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.GRAY);
}
g.fillRect(i, j, this.sqW, this.sqH);
g.setColor(Color.BLACK);
g.drawRect(i, j, this.sqW, this.sqH);
}
}
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Image observer not required so it can be set to null.
g.drawImage(image, 0,0, null);
}
最后,您需要将MatrixPanel
尺寸设置为足够大以容纳图像。大概300 x 300
。
推荐阅读
- r - R 不会将值作为数字导入
- react-native - 如何从 FlatList 中的存储中删除项目?
- python - 不希望用户输入数字时 Input() 函数出现问题
- mysql - mysql存储函数case语句
- voice-recognition - 对于具有 3 秒长度的音频样本,最佳窗口大小(以秒为单位)和跳跃大小(以秒为单位)是多少?
- python - Python脚本在不同的行停止并且不抛出异常
- c++ - GCC 模板推导消除了 const 错误?
- jquery - JQuery Mapael 在错误位置显示工具提示
- git - 在 Jenkins 管道中合并 Git 命令
- kubernetes - 守护进程集中的 kubernetes 副本