如何停止两次重复绘制方法?

这是我正在处理的骰子游戏的代码,它将结果输出到窗口。 油漆方法重复两次,这对我不利,因为我希望骰子滚动一次然后移动到下一帧。 请有人帮我解决这个问题。 先谢谢你。

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的域。
  • 您也不应该在Event Dispatching Thread的上下文中调用Thread.sleep ,尤其不要在任何paint方法中调用
  • 您应该避免覆盖paint ,而是使用paintComponent
  • 你应该避免从JFrame扩展而是使用类似JPanel东西,它实际上有一个paintComponent方法。
  • 这种性质的动画最好通过使用Swing Timer来实现,这将允许员工在EDT之外保持暂停,但在EDT内再次触发,使得执行绘画和更新更安全

看一眼

  • Swing中的并发性
  • 如何使用Swing Timers
  • 执行自定义绘画
  • 在AWT和Swing中绘画

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

更新了工作示例

蛇的眼睛

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

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