更改帧的显示,每隔一段时间,就像动画一样。

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

Changing the frame's display after every interval, like an animation

问题

  1. import java.awt.*;
  2. import java.util.Random;
  3. import javax.swing.*;
  4. class MatrixPanel extends JPanel {
  5. private final int sqW = 15;
  6. private final int sqH = 15;
  7. @Override
  8. public Dimension getPreferredSize() {
  9. return new Dimension(300, 300);
  10. }
  11. @Override
  12. public void paintComponent(Graphics g) {
  13. Random rand = new Random();
  14. for (int i = 0; i < 300; i += this.sqW) {
  15. for (int j = 0; j < 300; j += this.sqH) {
  16. if (rand.nextInt(2) == 1) {
  17. g.setColor(Color.BLACK);
  18. } else {
  19. g.setColor(Color.GRAY);
  20. }
  21. g.fillRect(i, j, this.sqW, this.sqH);
  22. g.setColor(Color.BLACK);
  23. g.drawRect(i, j, this.sqW, this.sqH);
  24. }
  25. }
  26. }
  27. }
  28. class GameOfLifeGUI extends JFrame {
  29. public GameOfLifeGUI() {
  30. JSplitPane splitPane = new JSplitPane();
  31. /*Panels*/
  32. JPanel topPanel = new JPanel();
  33. JPanel bottomPanel = new JPanel();
  34. /*Label - 1*/
  35. JLabel generationLabel = new JLabel("GenerationLabel");
  36. generationLabel.setText("Generation #");
  37. generationLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 14));
  38. generationLabel.setBounds(10, 5, 300, 20);
  39. /*Label - 2*/
  40. JLabel aliveLabel = new JLabel("AliveLabel");
  41. aliveLabel.setText("Alive: ");
  42. aliveLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 14));
  43. aliveLabel.setBounds(10, 25, 300, 20);
  44. topPanel.setLayout(null);
  45. topPanel.add(generationLabel);
  46. topPanel.add(aliveLabel);
  47. bottomPanel.add(new MatrixPanel());
  48. setPreferredSize(new Dimension(315, 405));
  49. getContentPane().setLayout(new GridLayout());
  50. getContentPane().add(splitPane);
  51. splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
  52. splitPane.setDividerLocation(50);
  53. splitPane.setTopComponent(topPanel);
  54. splitPane.setBottomComponent(bottomPanel);
  55. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  56. setLocationRelativeTo(null);
  57. pack();
  58. }
  59. public static void main(String[] args) {
  60. new GameOfLifeGUI().setVisible(true);
  61. }
  62. }

Specifically not repaint, if there are other components that I can use and meet my requirements will be most welcome.

Thank you.

  1. <details>
  2. <summary>英文:</summary>
  3. How can I use repaint here, that it changes the display after some interval, like an animation?
  4. Ouput:
  5. (Like initially and randomly it is) [this-1][1] (after some short interval and randomly it changes to) [this-2][2] and continued...

import java.awt.;
import java.util.Random;
import javax.swing.
;

class MatrixPanel extends JPanel {

  1. private final int sqW = 15;
  2. private final int sqH = 15;
  3. @Override
  4. public Dimension getPreferredSize() {
  5. return new Dimension(300, 300);
  6. }
  7. @Override
  8. public void paintComponent(Graphics g) {
  9. Random rand = new Random();
  10. for (int i = 0; i &lt; 300; i += this.sqW) {
  11. for (int j = 0; j &lt; 300; j += this.sqH) {
  12. if (rand.nextInt(2) == 1) {
  13. g.setColor(Color.BLACK);
  14. } else {
  15. g.setColor(Color.GRAY);
  16. }
  17. g.fillRect(i, j, this.sqW, this.sqH);
  18. g.setColor(Color.BLACK);
  19. g.drawRect(i, j, this.sqW, this.sqH);
  20. }
  21. }
  22. }

}

class GameOfLifeGUI extends JFrame {

  1. public GameOfLifeGUI() {
  2. JSplitPane splitPane = new JSplitPane();
  3. /*Panels*/
  4. JPanel topPanel = new JPanel();
  5. JPanel bottomPanel = new JPanel();
  6. /*Label - 1*/
  7. JLabel generationLabel = new JLabel(&quot;GenerationLabel&quot;);
  8. generationLabel.setText(&quot;Generation #&quot;);
  9. generationLabel.setFont(new Font(&quot;Comic Sans MS&quot;, Font.PLAIN, 14));
  10. generationLabel.setBounds(10, 5, 300, 20);
  11. /*Label - 2*/
  12. JLabel aliveLabel = new JLabel(&quot;AliveLabel&quot;);
  13. aliveLabel.setText(&quot;Alive: &quot;);
  14. aliveLabel.setFont(new Font(&quot;Comic Sans MS&quot;, Font.PLAIN, 14));
  15. aliveLabel.setBounds(10, 25, 300, 20);
  16. topPanel.setLayout(null);
  17. topPanel.add(generationLabel);
  18. topPanel.add(aliveLabel);
  19. bottomPanel.add(new MatrixPanel());
  20. setPreferredSize(new Dimension(315, 405));
  21. getContentPane().setLayout(new GridLayout());
  22. getContentPane().add(splitPane);
  23. splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
  24. splitPane.setDividerLocation(50);
  25. splitPane.setTopComponent(topPanel);
  26. splitPane.setBottomComponent(bottomPanel);
  27. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  28. setLocationRelativeTo(null);
  29. pack();
  30. }
  31. public static void main(String[] args) {
  32. new GameOfLifeGUI().setVisible(true);
  33. }

}

  1. Specifically not repaint, if there are other components that I can use and meet my requirements will be most welcome.
  2. Thank you.
  3. [1]: https://i.stack.imgur.com/8Mxsz.png
  4. [2]: https://i.stack.imgur.com/FpP1D.png
  5. </details>
  6. # 答案1
  7. **得分**: 0
  8. 你不希望执行以下操作:
  9. ```java
  10. public void paintComponent(Graphics g) {
  11. Random rand = new Random();
  12. for (int i = 0; i < 300; i += this.sqW) {
  13. for (int j = 0; j < 300; j += this.sqH) {
  14. if (rand.nextInt(2) == 1) {
  15. g.setColor(Color.BLACK);
  16. } else {
  17. g.setColor(Color.GRAY);
  18. }
  19. g.fillRect(i, j, this.sqW, this.sqH);
  20. g.setColor(Color.BLACK);
  21. g.drawRect(i, j, this.sqW, this.sqH);
  22. }
  23. }
  24. }

由于绘图是在事件调度线程(EDT)上进行的,您需要尽量减少处理,否则性能会受到影响,甚至可能导致应用程序锁定。

使用Swing计时器,并在BufferedImage对象中创建图像。BufferedImage提供图形上下文,因此您可以使用与paintComponent中相同的方法。

您可以将计时器间隔设置为适合您的值,然后在创建图像时发出重绘。因此,它可能类似于以下内容:

  1. final BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
  2. ...
  3. Timer timer = new Timer(0, ae -> createImage());
  4. timer.setDelay(300);
  5. timer.start();
  6. ...
  7. public void createImage(BufferedImage image) {
  8. Random rand = new Random();
  9. Graphics g = image.getGraphics();
  10. for (int i = 0; i < 300; i += this.sqW) {
  11. for (int j = 0; j < 300; j += this.sqH) {
  12. if (rand.nextInt(2) == 1) {
  13. g.setColor(Color.BLACK);
  14. } else {
  15. g.setColor(Color.GRAY);
  16. }
  17. g.fillRect(i, j, this.sqW, this.sqH);
  18. g.setColor(Color.BLACK);
  19. g.drawRect(i, j, this.sqW, this.sqH);
  20. }
  21. }
  22. repaint();
  23. }
  24. public void paintComponent(Graphics g) {
  25. super.paintComponent(g);
  26. // 图像观察器不需要,因此可以设置为null。
  27. g.drawImage(image, 0, 0, null);
  28. }

最后,您需要将MatrixPanel的大小设置为足够大,以容纳图像。可能是300 x 300

英文:

You don't want to do the following:

  1. public void paintComponent(Graphics g) {
  2. Random rand = new Random();
  3. for (int i = 0; i &lt; 300; i += this.sqW) {
  4. for (int j = 0; j &lt; 300; j += this.sqH) {
  5. if (rand.nextInt(2) == 1) {
  6. g.setColor(Color.BLACK);
  7. } else {
  8. g.setColor(Color.GRAY);
  9. }
  10. g.fillRect(i, j, this.sqW, this.sqH);
  11. g.setColor(Color.BLACK);
  12. g.drawRect(i, j, this.sqW, this.sqH);
  13. }
  14. }
  15. }

Since painting is done on the EDT, you need to keep your processing to a minimum, otherwise performance will suffer and you may even lock up your application.

Use a Swing timer and create the image in a BufferedImage object. BufferedImages provide a graphics context so you can use the same methods you are using in paintComponent.

You can set the timer interval to whatever works for you and then issue a repaint when the image is created. So it could look similar to the following:

  1. final BufferedImage image = new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
  2. ...
  3. Timer timer = new Timer(0, ae-&gt;createImage());
  4. timer.setDelay(300);
  5. timer.start();
  6. ...
  7. public void createImage(BufferedImage image) {
  8. Random rand = new Random();
  9. Graphics g = image.getGraphics();
  10. for (int i = 0; i &lt; 300; i += this.sqW) {
  11. for (int j = 0; j &lt; 300; j += this.sqH) {
  12. if (rand.nextInt(2) == 1) {
  13. g.setColor(Color.BLACK);
  14. } else {
  15. g.setColor(Color.GRAY);
  16. }
  17. g.fillRect(i, j, this.sqW, this.sqH);
  18. g.setColor(Color.BLACK);
  19. g.drawRect(i, j, this.sqW, this.sqH);
  20. }
  21. }
  22. repaint();
  23. }
  24. public void paintComponent(Graphics g) {
  25. super.paintComponent(g);
  26. // Image observer not required so it can be set to null.
  27. g.drawImage(image, 0,0, null);
  28. }

Finally, you need to set your MatrixPanel size large enough to hold the image. Probably 300 x 300.

huangapple
  • 本文由 发表于 2020年8月25日 20:58:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63579388.html
匿名

发表评论

匿名网友

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

确定