0

私は現在、2つのサイコロを振る単純なGUIアプリケーションに取り組んでいます。現在、「ゲーム」と「ダイスロール」の2つのクラスを使用しています。割り当て基準を満たすには、プログラムを機能させるために複数のクラスを使用する必要があります。1つのクラスを使用するだけの方がはるかに簡単です...とにかく、switchステートメントを使用して「Graphics.drawImage()」メソッドを順番に実装する「DiceRoll」クラスで「roll()」メソッドを正常に呼び出しています。指定された「.png」画像を描画します。すべてが正常に見え、実行する前にエラーは発生しません。プログラムを実行すると、GUIフレームがポップアップし、作成したすべてのボタン/メニューが機能します。ただし、「ロールダイス」ボタンを押すと、複数の実行時エラーが発生し続けます。これは私がこれまでに持っているものです:

ゲームクラス

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Game extends JFrame implements ActionListener 
{
JPanel mainPanel;
JPanel optionPanel;
JPanel dicePanel;
JButton rollDice;
JMenu options;
JMenuItem quit;
JMenuItem explanation;
JMenuBar menuBar;
JLabel diceLabel;
JLabel diceLabel2;
DiceRoll dr;
Graphics die1;
Graphics die2;

public Game()
{
    setTitle("Rollin' Dice");
    this.setPreferredSize(new Dimension(600,600));

    mainPanel = new JPanel();
    optionPanel = new JPanel();
    dicePanel = new JPanel();
    rollDice = new JButton("Roll Dice");
    options = new JMenu("Options");
    quit = new JMenuItem("Quit");
    explanation = new JMenuItem("Explanation");
    menuBar = new JMenuBar();
    dr = new DiceRoll();
    diceLabel = new JLabel();
    diceLabel2 = new JLabel();

    options.add(quit);
    options.add(explanation);

    menuBar.add(options);

    optionPanel.add(menuBar);
    optionPanel.setPreferredSize(new Dimension(600,100));

    dicePanel.add(rollDice);

    dicePanel.add(diceLabel);
    dicePanel.add(diceLabel2);

    mainPanel.setPreferredSize(new Dimension(600,600));
    mainPanel.add(optionPanel);
    mainPanel.add(dicePanel);


    quit.addActionListener(this);
    explanation.addActionListener(this);
    rollDice.addActionListener(this);

    this.getContentPane().add(mainPanel);

    this.pack();
    this.setVisible(true);
}


public void actionPerformed(ActionEvent e) {
    if (e.getSource()== quit)
        System.exit(0);

    if (e.getSource() == explanation)
    {
        JOptionPane.showMessageDialog(mainPanel,
                "Win: Roll a sum that is an even number \nLose: Roll a sum that is an odd number" + dicePanel, "Rules", JOptionPane.INFORMATION_MESSAGE); 
    }

    if (e.getSource() == rollDice)
    {

        dr.roll(die1);
        dr.roll(die2);

        diceLabel.updateUI();

        dicePanel.updateUI();
    }

}

public static void main (String []args)
{
    Game dg = new Game();
}

}

DiceRollクラス

    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import javax.imageio.*;
    import java.io.File;
    import java.io.IOException;
    import javax.swing.JComponent;

public class DiceRoll extends JComponent {

private BufferedImage die1;
private BufferedImage die2;
private BufferedImage die3;
private BufferedImage die4;
private BufferedImage die5;
private BufferedImage die6;


public DiceRoll()
{
    try {
        die1 = (ImageIO.read(new File("die1.png")));
        die2 = ImageIO.read(new File("die2.png"));
        die3 = ImageIO.read(new File("die3.png"));
        die4 = ImageIO.read(new File("die4.png"));
        die5 = ImageIO.read(new File("die5.png"));
        die6 = ImageIO.read(new File("die6.png"));
    } catch (IOException ex){
        System.err.println("That is invalid");
    }
}


public Graphics roll(Graphics g)
{
    int dieResult = (int)(6 * Math.random());

    switch(dieResult){
    case 1: 
        g.drawImage(die1, 0, 0, null);
        break;
    case 2:
        g.drawImage(die2, 0, 0, null);
        break;
    case 3:
        g.drawImage(die3, 0, 0, null);
        break;
    case 4:
        g.drawImage(die4, 0, 0, null);
        break;
    case 5:
        g.drawImage(die5, 0, 0, null);
        break;
    case 6:
        g.drawImage(die6, 0, 0, null);
        break;
    }
    return g;
}

}

私が受け取っているエラー

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at DiceRoll.roll(DiceRoll.java:51)
at Game.actionPerformed(Game.java:89)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
4

2 に答える 2

2

ここを通過null します:

dr.roll(die1);
dr.roll(die2);

die1とをインスタンス化することは決してないdie2ため、NullPointerExceptionが発生します。

于 2012-05-07T02:47:28.547 に答える
1

あなたはこれを必要以上に複雑にしていると思います。public Graphics roll(Graphics g)ロールを計算して更新する方法を変更してみませんかJLabel、このように...

public void roll(JLabel dieLabel) {
    int dieResult = (int)(6 * Math.random());
    dieLabel.setIcon(new ImageIcon("die" + dieResult + ".png"))
}

次に、ここでコードを変更するだけです...

if (e.getSource() == rollDice){
    dr.roll(die1);
    dr.roll(die2);
    diceLabel.updateUI();
    dicePanel.updateUI();
}

このように、変更したいラベルを送信するには...

if (e.getSource() == rollDice){
    dr.roll(diceLabel);
    dr.roll(diceLabel2);
}

メソッドにパススルーしますJLabelroll()メソッドはロールを計算し、そのラベルに画像を設定します。はるかに簡単です。

Graphicsこれは、2つのオブジェクト(die1と)も必要ないことを意味するdie2ため、これらを取り除くことができます。BufferedImagesまた、画像ファイルの読み込みはImageIconクラスによって行われるため、は必要ありません。

学習目的で、私の提案についてさらに情報が必要な場合はお知らせください。

編集...

これはコンストラクターを書き直したもので、レイアウトマネージャーとして使用Game()するアイテムを追加する方法を示しています...JPanelsGridLayoutBorderLayout

public Game(){
    // Set the JFrame properties
    setTitle("Rollin' Dice");
    this.setPreferredSize(new Dimension(600,600));

    // Create the main JPanel to hold the interface
    mainPanel = new JPanel(new BorderLayout());


    // Build the Menu
    options = new JMenu("Options");

    quit = new JMenuItem("Quit");
    options.add(quit);

    explanation = new JMenuItem("Explanation");
    options.add(explanation);

    menuBar = new JMenuBar();
    menuBar.add(options);

    // Add the menu to the top of the main panel
    mainPanel.add(menuBar,BorderLayout.NORTH);


    // Create the dice
    dr = new DiceRoll();
    diceLabel = new JLabel();
    diceLabel2 = new JLabel();

    dicePanel = new JPanel(new GridLayout(2,1));
    dicePanel.add(diceLabel);
    dicePanel.add(diceLabel2);

    // Add the dicePanel to the center of the main panel
    mainPanel.add(dicePanel,BorderLayout.CENTER);


    // Add the rollDice button to the bottom of the main panel
    rollDice = new JButton("Roll Dice");
    mainPanel.add(rollDice,BorderLayout.SOUTH);


    // Add listeners to the menu items and buttons
    quit.addActionListener(this);
    explanation.addActionListener(this);
    rollDice.addActionListener(this);

    // Add the main panel to the JFrame
    this.getContentPane().add(mainPanel);

    // Show the JFrame
    this.pack();
    this.setVisible(true);
}
于 2012-05-07T03:04:06.197 に答える