java - 让 JButtons 在每个循环周期中刷新标签

标签 java swing

好的,这个程序的目标是让红色 x 从“桥”(由 7 个 JButton 组成)的一侧到达窗口的另一侧。我试图让按钮在每个循环周期后刷新显示在其上的文本,使其看起来像红色 x 穿过桥。任何关于为什么它不刷新的基于以下代码的帮助都是令人难以置信的。

感谢您的宝贵时间

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GeorgeBridge extends JApplet implements ActionListener{
  // Create a frame to hold the contents of application
  JFrame frame = new JFrame ("George's Big Bridge Crossing");

  // Panel to hold the bridge
  JPanel bridgePanel = new JPanel(new GridLayout(1,7));

  /* The following JLabels are used for spacing of the panels in the frame to make the window look more like a bridge 
   * crossing over a river
   */
  JLabel northLabel = new JLabel(" ");
  JLabel eastLabel = new JLabel("         ");
  JLabel westLabel = new JLabel("         ");
  // Asks the user whether or not they would like George to cross the bridge
  JLabel southLabel = new JLabel("Would you like George to cross the Bridge?"); 

  // George is represented by a red X
  String george = "X";

  // An array of 7 JButtons to act as the bridge
  JButton [] bridge = new JButton [7];

  int spot;





  public void init() { 
    bridge[0] = new JButton ("");
    bridge[1] = new JButton ("");
    bridge[2] = new JButton ("");
    bridge[3] = new JButton ("");
    bridge[4] = new JButton ("");
    bridge[5] = new JButton ("");
    bridge[6] = new JButton ("");



    // Set the program to exit when the JFrame is closed
    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    //set a border layout manager to the frame
    frame.setLayout(new BorderLayout());

    // Background set to look like water under the bridge
    bridgePanel.setBackground (new Color(0,191,246));

    // Panel to make it look like the bridge is crossing a river
    JPanel northPanel = new JPanel();
    northPanel.setBackground (new Color (0,191,246));

    // Panel to make it look like the bridge is crossing a river
    JPanel eastPanel = new JPanel();
    eastPanel.setBackground (new Color (0,184,48));

    // Panel to make it look like the bridge is crossing a river
    JPanel southPanel = new JPanel();
    southPanel.setBackground (new Color (0,191,246));

    // Panel to make it look like the bridge is crossing a river
    JPanel westPanel = new JPanel();
    westPanel.setBackground (new Color(0,184,48));

    // JButton to let the user choose when George crosses the bridge
    JButton cross = new JButton("Make George cross!");
    cross.setActionCommand("cross");
    cross.addActionListener(this);   

    // Starts George standing on the West Bank
    westLabel.setText(george);
    // Makes George red so he is more visible
    westLabel.setForeground(new Color(255,0,0));
    // Makes George size 24 font so he is more visible
    westLabel.setFont(westPanel.getFont().deriveFont(24.0f));

    // Initiates the first button that represents a foot of the bridge
//    bridge[0] = new JButton ("");
    bridge[0].setBackground(new Color(143,66,19));// Set the background to a brown to make the bridge look like a wooden bridge
    bridge[0].setForeground(new Color(255,0,0));// Set the colour of George to red
    bridge[0].setFont(bridge[0].getFont().deriveFont(24.0f));// Set the font for George to 24

    // Initiates the second button that represents a foot of the bridge
//    bridge[1] = new JButton ("");
    bridge[1].setBackground(new Color(143,66,19));// Set the background to a brown to make the bridge look like a wooden bridge
    bridge[1].setForeground(new Color(255,0,0));// Set the colour of George to red
    bridge[1].setFont(bridge[0].getFont().deriveFont(24.0f));// Set the font for George to 24

    // Initiates the third button that represents a foot of the bridge
//    bridge[2] = new JButton ("");
    bridge[2].setBackground(new Color(143,66,19));// Set the background to a brown to make the bridge look like a wooden bridge
    bridge[2].setForeground(new Color(255,0,0));// Set the colour of George to red
    bridge[2].setFont(bridge[0].getFont().deriveFont(24.0f));// Set the font for George to 24

    // Initiates the fourth button that represents a foot of the bridge
//    bridge[3] = new JButton ("");
    bridge[3].setBackground(new Color(143,66,19));// Set the background to a brown to make the bridge look like a wooden bridge
    bridge[3].setForeground(new Color(255,0,0));// Set the colour of George to red
    bridge[3].setFont(bridge[0].getFont().deriveFont(24.0f));// Set the font for George to 24

    // Initiates the fifth button that represents a foot of the bridge
//    bridge[4] = new JButton ("");
    bridge[4].setBackground(new Color(143,66,19));// Set the background to a brown to make the bridge look like a wooden bridge
    bridge[4].setForeground(new Color(255,0,0));// Set the colour of George to red
    bridge[4].setFont(bridge[0].getFont().deriveFont(24.0f));// Set the font for George to 24

    // Initiates the sixth button that represents a foot of the bridge
//    bridge[5] = new JButton ("");
    bridge[5].setBackground(new Color(143,66,19));// Set the background to a brown to make the bridge look like a wooden bridge
    bridge[5].setForeground(new Color(255,0,0));// Set the colour of George to red
    bridge[5].setFont(bridge[0].getFont().deriveFont(24.0f));// Set the font for George to 24

    // Initiates the seventh button that represents a foot of the bridge
//    bridge[6] = new JButton ("");
    bridge[6].setBackground(new Color(143,66,19));// Set the background to a brown to make the bridge look like a wooden bridge
    bridge[6].setForeground(new Color(255,0,0));// Set the colour of George to red
    bridge[6].setFont(bridge[0].getFont().deriveFont(24.0f));// Set the font for George to 24

    // Add the bridge buttons to the bridge panel
    bridgePanel.add(bridge[0]);
    bridgePanel.add(bridge[1]);
    bridgePanel.add(bridge[2]);
    bridgePanel.add(bridge[3]);
    bridgePanel.add(bridge[4]);
    bridgePanel.add(bridge[5]);
    bridgePanel.add(bridge[6]);

    // Add the labels and buttons to the 4 border panels
    northPanel.add(northLabel);
    eastPanel.add(eastLabel);
    southPanel.add(southLabel);
    southPanel.add(cross);
    westPanel.add(westLabel);

    // Add all the panels to the JFrame
    frame.getContentPane().add(northPanel, BorderLayout.NORTH);
    frame.getContentPane().add(eastPanel, BorderLayout.EAST);
    frame.getContentPane().add(bridgePanel, BorderLayout.CENTER);
    frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
    frame.getContentPane().add(westPanel, BorderLayout.WEST);

    // Set the JFrame size and visibility
    frame.setSize(450,150);
    frame.setVisible(true);
  }

  public void actionPerformed (ActionEvent event) {

    new Thread (new Runnable() {
      public void run() {
        moveGeorge();
      }
    }).start();
  }

  public void moveGeorge() {
    for(int i=0; i<7; i++) {
      spot = i;
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          if (spot > 0) {
            bridge[spot].setText(george);
            bridge[spot-1].setText("");
          }
          else {
            westLabel.setText("");
            bridge[spot].setText(george);
          }

          try
        {
          Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
        }
        catch(InterruptedException e)
        {
          e.printStackTrace();
        }

          frame.setVisible(true);
        }
      });
    }
  }
}

最佳答案

Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)

当代码在事件调度线程上执行时,切勿使用 Thread.sleep()。这会阻止 GUI 响应事件并重新绘制自身。

该代码需要移至 invokeLater() 代码之外。

参见Concurrency in Swing有关 EDT 的更多信息。

关于java - 让 JButtons 在每个循环周期中刷新标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7019300/

相关文章:

java - BigDecimal.divide(BD,int,RM) - BigDecimal 无法转换为双错误

java - 有限制的 Cassandra BoundStatement

java - 为什么这个 Java 正则表达式不起作用?

java - 为小型桌面应用程序构建 GUI

java:如何只选择一个jtable中的一个单元格而不是整行

java - 如何使 BoxLayout 表现为垂直 FlowLayout?

java - SecureSocial:如何修改注册系统(UsernamePasswordProvider)?

java - 加载应用程序上下文.xml

java - 我如何用java制作蛇与梯子游戏的棋盘?

java - 改变 GridLayout 的宽度