GUI程序无法更新

时间:2012-10-17 18:30:31

标签: java swing user-interface jlabel event-dispatch-thread

我对我的作业硬币程序有疑问。

我们需要编写一个小的GUI程序,可以翻转硬币并显示当前的钱。

我几乎写了所有内容,但是我仍然有一些问题需要更新两个JLabel状态,看起来两个下注按钮和重置按钮的工作正常,我使用System.out.println进行测试后,但是当我们点击按钮时,标签不会同时更新。

以下是我的代码,其中包含四个类:coin.javaplayer.javacoinpanel.javacoinPanelMain.java

  1. player.java:

    public class Player {

    /**
     * @param ownMoney is currently the player own money
     * @param coin is new Coin object;
     */
    private int currMoney;
    private Coin coin; 
    
    /**
     * no-args parameter
     * default constructor 
     */
    public Player(){
        currMoney = 10;
        coin = new Coin();
    }
    /**
     * a bet method that takes in a bet and the side of coin
     * it will filp the coin and change the player's money 
     * depend on whether the player won or lost the bet 
     */
    public void bet(){
        coin.flip();
        System.out.println("filp over");
        if(coin.getFace().equals ("Heads")){
            currMoney ++;
        }
        else if(coin.getFace().equals("Tails")){
            currMoney --;
        }
        System.out.println("filp over2");
    }
    /**
     * a getter for getting current money
     * @return currMoney 
     */
    public int getCurrMon(){
        System.out.println("money is" + currMoney);
        return currMoney;
    }
    /**
     * a reset method make current money return to 10;
     * @return currMoney to 10
     */
    public void reset(){
    
        currMoney = 10;
    }
    

    }

  2. coinPanel.java

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

    • 硬币面板类显示硬币游戏的结果。
    • 它包含三个按钮,当前钱和当前翻转
    • 一旦用户点击重置按钮,当前的钱将返回10。 * * * /
  3. 公共类CoinPanel扩展了JPanel {

    private Player player = new Player();
    private Coin coin = new Coin();
    private JLabel label3 = new JLabel("Enter a bet");
    private JTextField text;
    private  int value = 0;
    
    public  int getVal(){
        return value;
    }
    public CoinPanel(){
    
        JLabel label= new JLabel("Current Money:"+player.getCurrMon());
        JLabel label2 = new JLabel("Current Flip:" + coin.getFace());
    
        JLabel label4 = new JLabel("");
    
        text = new JTextField(30);
        //JTextField text = new JTextField(30);
        //String betNum = text.getText();
        //int betNumber = Integer.parseInt(betNum);
    
    
        JButton headsBt = new JButton("Bet Heads");
        JButton tailsBt = new JButton("Bet Tails");
        JButton reset = new JButton("Reset");
    
    
        setLayout(new GridLayout(5,1,10,10));
        add(label);
        add(label2);
    
        add(headsBt);
        add(tailsBt);
        add(text);
    
        add(reset);
        add(label3);
    
    
    
    
        headsBt.addActionListener(new BetButtonListener());
        tailsBt.addActionListener(new BetButtonListener());
        reset.addActionListener(new RESETButtonListener());
    
    
    
    }
    
    public class RESETButtonListener implements ActionListener{
        public void actionPerformed(ActionEvent e){
            player.reset();
            System.out.println("reset button");
        }
    }
    
    public class BetButtonListener implements ActionListener{
        public void actionPerformed(ActionEvent e){
            //value = Integer.parseInt(text.getText());
            player.bet();
    
            int value = Integer.parseInt(text.getText());
    
        //catch (NumberFormatException e){
            if(value > player.getCurrMon()){
                label3.setText("You are out of money");
                repaint();
            }
                }
    
    }
    
    }
    
    非常感谢你。我非常感谢你的帮助!

    重新编辑代码后按指令 这里有一些错误显示如下,应用程序无法运行。我不知道为什么。 错误是:

    money is10
    face isTails
    Exception in thread "main" java.lang.NullPointerException
        at java.awt.Container.addImpl(Unknown Source)
        at java.awt.Container.add(Unknown Source)
        at CoinPanel.<init>(CoinPanel.java:48)
        at CoinPanelMain.main(CoinPanelMain.java:17)
    

    ” 以上问题解决了。我忘了在课堂上初始化了label3。

    很抱歉给你带来太多问题...... 无论文本字段中的用户输入(我的意思是数字),当前的货币标签总是增加2或减少2.我认为它应该随用户输入而变化?

2 个答案:

答案 0 :(得分:4)

Swing非常聪明,但它有点过于聪明。

我的期望是,在调用类似Label#setText的内容后,会引发重新绘制请求并更新标签,但这并不总是会发生。

您可能需要提示Swing进行重新绘制......

if(value > player.getCurrMon()) {
    label3.setText("You are out of money");
    repaint();
}

在您的情况下不太可能,但您可能需要通过调用repaint继续invalidate()请求,以鼓励容器层次结构更新其布局。

也...

int value = Integer.parseInt(text.getText());

应该包含在NumberFormatException中,以确保用户实际输入了一个号码。如果不这样做,将导致您的程序未按预期更新

扩展答案

所以,在你的rest方法中,你需要更新所有各种ui元素......

public void actionPerformed(ActionEvent e){
    player.reset();
    System.out.println("reset button");

    label3.setText(""); // assuming no new messages..
    label.setText("Current Money:"+player.getCurrMon());
    text.setEnabled(true);

    invalidate();
    repaint();

}

在你下注按钮中你有很多问题......

用户输入的内容与扣除的内容之间没有任何联系,也没有检查玩家是否可以支付赌注......

    try {
        int value = Integer.parseInt(text.getText());

        if (value > player.getCurrMon()) {
            label3.setText("You don't have enough money to cover the bet");
        } else {
            player.bet();

            label.setText("Current Money:"+player.getCurrMon());

            if(player.getCurrMon() == 0){
                label3.setText("You are out of money");
                text.setEnabled(false);
            } else if (player.getCurrMon() < 0) {
                label3.setText("We'll be sending the boys around shortly");
                text.setEnabled(false);
            }
       }
    } catch (NumberFormatException exp) {
        label3.setText(text.getText() + " is an invalid bet");
    }
    invalidate();
    repaint();

<强>已更新

首先...... label需要定义为实例字段,例如label3

中的CoinPanel
private JLabel label3 = new JLabel("Enter a bet");
private JLabel label;

然后在构造函数中,您只需要初始化它......

public CoinPanel(){

    label= new JLabel("Current Money:"+player.getCurrMon());

<强>已更新

基本上,我们需要检查按下了哪个按钮并相应地更改了“面子”下注

public class BetButtonListener implements ActionListener {

    public void actionPerformed(ActionEvent e) {
        try {
            int value = Integer.parseInt(text.getText());

            if (value > player.getCurrMon()) {
                label3.setText("You don't have enough money to cover the bet");
            } else {
                String face = "Heads";
                if (e.getSource().equals(tailsBt)) {
                    face = "Tails"
                }
                player.bet(face, value);

                label.setText("Current Money:" + player.getCurrMon());

                if (player.getCurrMon() == 0) {
                    label3.setText("You are out of money");
                    text.setEnabled(false);
                } else if (player.getCurrMon() < 0) {
                    label3.setText("We'll be sending the boys around shortly");
                    text.setEnabled(false);
                }
            }
        } catch (NumberFormatException exp) {
            label3.setText(text.getText() + " is an invalid bet");
        }
        invalidate();
        repaint();
    }

}

注意,我可能已将参数切换为bet方法。该顺序仅对您声明方法的方式很重要,因此您可能需要切换我的参数

答案 1 :(得分:2)

  • 这是一个问题:

    if(coin.getFace() == "Heads"){
        currMoney ++;
     }
    else if(coin.getFace() == "Tails"){
        currMoney --;
    }
    

不要使用String来比较==。使用equals(..)方法进行String比较:

if(coin.getFace().equals("Heads")){
    currMoney ++;
}
else if(coin.getFace().equals("Tails")){
     currMoney --;
}

我还建议在比较多个Switch时使用String块,这样也降低了使用==比较字符串的风险(Java 7只是感谢Mad):

switch(coin.getFace()) {

    case "Heads": 
          currMoney ++;
      break;
    case "Tails":  
           currMoney --;
      break;
}
  • 您向ActionListener添加JTextField这绝对不是好事(删除此行):

    text.addActionListener(new BetButtonListener());
    
  • 此外,只要在JPanel上创建Event-Dispatch-Thread实例,我就无法看到它更新,但正如@Mad所说的那样(+1给他和尝试catch )调用invalidate()将确保它。

<强>更新

根据评论:

try catch 块将围绕一个可能抛出Exception的方法调用:

int i=...;
try {
//call a method that can throw NumberFormatExecption
i=...;
}catch(NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}

有关TRYCATCH

的更多信息,请阅读这些内容