如何停止我的绘画方法表格重复两次? [英] How do I stop my paint method form repeating twice?

查看:79
本文介绍了如何停止我的绘画方法表格重复两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我正在研究的骰子游戏的代码,它将结果输出到窗口.绘制方法重复两次,这对我来说不好,因为我希望骰子滚动一次然后移至下一帧.请有人帮我解决这个问题.预先谢谢你.

Here is the code for a dice game that I am working on that outputs the results to a window. The paint method repeats twice, which is not good for me because I want the dice to roll once and then move on to the next frame. Please someone help me with this problem. Thank you in advance.

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

public class Dice extends JApplet {

public static int pause(int n)
{
    try {
        Thread.sleep(n);
        } catch(InterruptedException e) {
    }
    return n;
}

public void Dice() {
    JApplet app = new Dice();
    JFrame frame = new JFrame("Dice Game");
    frame.setBounds(30, 50, 1300, 650);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    frame.add(app);
}

public void paint(Graphics g) {
    int width = getWidth();    
    int height = getHeight(); 

    int num = 0;
    for (int i = 0; i < 7; i++) {
        Random generator= new Random();
        int number = generator.nextInt(6)+1;
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
        g.setColor(Color.BLACK);
        g.drawRoundRect(550, 150, 200, 200, 50, 50);
        System.out.println("Test");
        if (number == 1) {              //Roll one
            num = 1;
            g.setColor(new Color (0, 0, 0));
            g.fillOval(640, 240, 20, 20);
            pause(100);
        } if (number == 2) {                //Roll two
            num = 2;
            g.setColor(new Color (0, 0, 0));
            g.fillOval(590, 290, 20, 20);
            g.fillOval(690, 190, 20, 20);
            pause(100);
        } if (number == 3) {                //Roll three
            num = 3;
            g.setColor(new Color (0, 0, 0));
            g.fillOval(590, 290, 20, 20);
            g.fillOval(640, 240, 20, 20);
            g.fillOval(690, 190, 20, 20);
            pause(100);
        } if (number == 4) {                //Roll four
            num = 4;
            g.setColor(new Color (0, 0, 0));
            g.fillOval(590, 290, 20, 20);
            g.fillOval(590, 190, 20, 20);
            g.fillOval(690, 290, 20, 20);
            g.fillOval(690, 190, 20, 20);
            pause(100);
        } if (number == 5) {                //Roll five
            num = 5;
            g.setColor(new Color (0, 0, 0));
            g.fillOval(590, 290, 20, 20);
            g.fillOval(590, 190, 20, 20);
            g.fillOval(640, 240, 20, 20);
            g.fillOval(690, 290, 20, 20);
            g.fillOval(690, 190, 20, 20);
            pause(100);
        } if (number == 6) {                //Roll six
            num = 6;
            g.setColor(new Color (0, 0, 0));
            g.fillOval(590, 190, 20, 20);
            g.fillOval(590, 240, 20, 20);
            g.fillOval(590, 290, 20, 20);
            g.fillOval(690, 190, 20, 20);
            g.fillOval(690, 240, 20, 20);
            g.fillOval(690, 290, 20, 20);
            pause(100);
        }
    }
    g.setFont(new Font("TimesRoman", Font.PLAIN, 20));
    g.drawString("You rolled a " + num, 590, 100);
    pause(1000);
  }
}

推荐答案

  • 简短的答案是-您不能.您无法控制何时绘画是RepaintManager的域.
  • 您也永远不要在事件调度线程的上下文中调用Thread.sleep,尤其不要在任何paint方法中调用
  • 您应避免覆盖paint,而应使用paintComponent
  • 您应该避免从JFrame扩展而改用JPanel之类的东西,它实际上具有一个paintComponent方法.
  • 使用Swing Timer可以最好地实现这种性质的动画,该动画将允许员工在EDT之外保持暂停,但在EDT内又会触发该暂停,从而可以更安全地进行绘画和更新
    • The short answer is - you can't. You don't control when painting occurs that is the domain of the RepaintManager.
    • You should also NEVER call Thread.sleep within the context of the Event Dispatching Thread and especially not within any paint method
    • You should avoid overriding paint and instead use paintComponent
    • You should avoid extending from JFrame and instead use something like JPanel, which actually has a paintComponent method.
    • Animation of this nature is best achieved by using a Swing Timer, which will allow to employee a pause which is maintained outside of the EDT, but is triggered again within in the EDT making it safer to perform painting and updates
    • 看看

      • Concurrency in Swing
      • How to Use Swing Timers
      • Performing Custom Painting
      • Painting in AWT and Swing

      有关绘画在Swing中的工作方式以及如何实现您想要做的事情的更多详细信息

      For more details about how painting works in Swing and how to achieve what you are trying to do

      已更新了工作示例

      因为我很懒,所以我利用Graphics 2D API绘制了点.我这样做是因为许多数字的许多点都出现在相同的位置...

      Cause I'm lazy, I've utilised the Graphics 2D API to draw the dots. I did this because many of the dots appear in the same locations for many of the numbers...

      import java.awt.Color;
      import java.awt.Dimension;
      import java.awt.EventQueue;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.Shape;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.awt.geom.Ellipse2D;
      import java.util.ArrayList;
      import java.util.List;
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.Timer;
      import javax.swing.UIManager;
      import javax.swing.UnsupportedLookAndFeelException;
      
      public class DiceRoller {
      
          public static void main(String[] args) {
              new DiceRoller();
          }
      
          public DiceRoller() {
              EventQueue.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      try {
                          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                      } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                      }
      
                      JFrame frame = new JFrame("Testing");
                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                      frame.add(new Die());
                      frame.pack();
                      frame.setLocationRelativeTo(null);
                      frame.setVisible(true);
                  }
              });
          }
      
          public class Die extends JPanel {
      
              private int number = 1;
      
              public Die() {
                  Timer timer = new Timer(500, new ActionListener() {
                      @Override
                      public void actionPerformed(ActionEvent e) {
                          number = (int) (Math.round((Math.random() * 5) + 1));
                          repaint();
                      }
                  });
                  timer.setRepeats(true);
                  timer.setInitialDelay(0);
                  timer.start();
              }
      
              @Override
              public Dimension getPreferredSize() {
                  return new Dimension(220, 220);
              }
      
              @Override
              public void paintComponent(Graphics g) {
                  super.paintComponent(g);
                  Graphics2D g2d = (Graphics2D) g.create();
                  int width = getWidth();
                  int height = getHeight();
      
                  g2d.setColor(Color.WHITE);
                  g2d.fillRect(0, 0, width, height);
                  g2d.setColor(Color.BLACK);
                  g2d.drawRoundRect(10, 10, width - 20, height - 20, 50, 50);
      
                  List<Shape> dots = new ArrayList<>(6);
      
                  if (number == 1 || number == 3 || number == 5) {
                      int x = (width - 20) / 2;
                      int y = (height - 20) / 2;
                      dots.add(new Ellipse2D.Float(x, y, 20, 20));
                  }
      
                  if (number == 2 || number == 3 || number == 4 || number == 5 || number == 6) {
      
                      int x = ((width / 2) - 20) / 2;
                      int y = ((height / 2) - 20) / 2;
                      dots.add(new Ellipse2D.Float(x, y, 20, 20));
                      dots.add(new Ellipse2D.Float(x + (width / 2), y + (height / 2), 20, 20));
      
                  }
      
                  if (number == 4 || number == 5 || number == 6) {
      
                      int x = (width / 2) + (((width / 2) - 20) / 2);
                      int y = ((height / 2) - 20) / 2;
                      dots.add(new Ellipse2D.Float(x, y, 20, 20));
                      dots.add(new Ellipse2D.Float(x - (width / 2), y + (height / 2), 20, 20));
      
                  }
      
                  if (number == 6) {
      
                      int x = (((width / 2) - 20) / 2);
                      int y = (height - 20) / 2;
                      dots.add(new Ellipse2D.Float(x, y, 20, 20));
                      dots.add(new Ellipse2D.Float(x + (width / 2), y, 20, 20));
      
                  }
      
                  for (Shape dot : dots) {
                      g2d.fill(dot);
                  }
      
                  g2d.dispose();
              }
          }
      }
      

      这篇关于如何停止我的绘画方法表格重复两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆