-1

我对硬币计划的作业有疑问。

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

我写了几乎所有的东西,但是更新两个JLabel状态仍然有一些问题,似乎两个下注按钮和重置按钮工作正常,经过我System.out.println的测试,但是当我们单击时标签不会同时更新按钮。

这是我的代码,其中包含四个类:coin.javaplayer.java和。coinpanel.javacoinPanelMain.java

  1. 播放器.java:

    公共类播放器{

    /**
     * @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

    导入 javax.swing。; 导入 java.awt.event。; 导入 java.awt。; / *

    • 硬币面板类显示硬币游戏的结果。
    • 它包含三个按钮,当前货币和当前翻转
    • 一旦用户点击重置按钮,当前货币将返回到 10。 * * */

公共类 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。我认为它应该随着用户输入而改变?

4

2 回答 2

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

应该包裹在 aNumberFormatException中以确保用户实际输入了一个数字。否则将导致您的程序无法按照您的预期进行更新

扩展答案

因此,在您的休息方法中,您需要更新所有各种 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方法。顺序仅对您声明方法的方式很重要,因此您可能需要切换我的参数

于 2012-10-17T19:10:13.687 回答
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在比较多个 s 时使用 block ,String从而降低比较 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 所说(对他和try catch加 1 )调用invalidate()将确保它更新。

更新:

根据评论:

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

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

阅读这些以获取有关TRYCATCH块的更多信息

于 2012-10-17T19:05:47.540 回答