-1

宿題のコイン プログラムについて質問があります。

コインを裏返し、現在のお金を表示できる小さな GUI プログラムを作成する必要があります。

私はほとんどすべてを書きましたが、2つのJLabelステータスを更新するのにまだ問題があり、2つのベットボタンとボタンのリセットはうまく機能しているようですSystem.out.println。ボタン。

coin.javaplayer.javacoinpanel.javaおよびの 4 つのクラスを含むコードを次に示しますcoinPanelMain.java

  1. player.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. コインパネル.java

    javax.swing をインポートします。; java.awt.event をインポートします。; java.awt をインポートします。; / *

    • コイン パネル クラスは、コイン ゲームの結果を表示します。
    • 3つのボタン、現在のお金、現在のフリップが含まれています
    • ユーザーがリセットボタンをクリックすると、現在のお金は 10 に戻ります。 * * */

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

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パラメータをメソッドに切り替えた可能性があることに注意してください。順序は、メソッドを宣言した方法にのみ重要であるため、パラメーターを切り替える必要がある場合があります

于 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 を使用して比較するリスクも軽減され==ます (Mad に感謝しますが、Java 7 のみ)。

switch(coin.getFace()) {

    case "Heads": 
          currMoney ++;
      break;
    case "Tails":  
           currMoney --;
      break;
}
  • これは間違いなく良くないことに追加ActionListenerしますJTextField(この行を削除してください):

    text.addActionListener(new BetButtonListener());
    
  • JPanelまた、インスタンスが で作成されている限り、更新されていないことはわかりませんEvent-Dispatch-Threadが、@Mad が言ったように (彼に +1 し、try catchに対して) 呼び出しinvalidate()を行うと、確実に更新されます。

アップデート:

コメントに従って:

try catchブロックは、以下をスローする可能性のあるメソッド呼び出しを囲みますException

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

TRYおよびCATCHブロックの詳細については、これらをお読みください。

于 2012-10-17T19:05:47.540 に答える