首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >让JButtons在每个循环周期中刷新标签

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

Stack Overflow用户
提问于 2011-08-11 07:44:45
回答 3查看 1.1K关注 0票数 0

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

耽误您时间,实在对不起

代码语言:javascript
运行
复制
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);
        }
      });
    }
  }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-11 08:11:02

代码语言:javascript
运行
复制
Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)

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

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

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

票数 3
EN

Stack Overflow用户

发布于 2011-08-11 09:25:45

离题,但它不适合评论:

  • 使用循环来初始化相等的components.
  • Use名称,如'brown‘而不是注释,主要是重复代码
  • 使用已定义的值,如Color.RED

颜色棕色=新颜色(143,66,19);for (int i= 0;i< 7;++i) { bridgei =新JButton ("");bridgei.setBackground (棕色);bridgei.setForeground (Color.RED);bridgei.setFont (桥接.getFont ().deriveFont (24.0f));bridgePanel.add (桥接I);}

这为您节省了30行代码。

票数 0
EN

Stack Overflow用户

发布于 2011-08-11 08:11:55

首先,swing不是线程安全的。

使用Swing Timer,而不是使用Thread.sleep()和搞乱EDT (事件分派线程)

其次,尝试在修改${JComponent}之后立即添加一对${JComponent}.revalidate()和${JComponent}.repaint()

例如

代码语言:javascript
运行
复制
// 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));
//VVVV NOW ADD THIS VVVV
westLabel.revalidate();
westLabel.repaint();
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7019300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档