質問: Javaの質問で以下のプログラムをコマンドプロントでコンパイルはできるのですが 実行した時に以下のエラーが出ます どのようにしたらしっかりと実行できるようになるでしょうか? 変更したらいい部分などを教えてください! 回答よろしくお願いします ``` エラー文 Exception in thread "main" java.lang.NullPointerException at MyFrame.suraimu(MyFrame.java:175) at MyFrame.addMonster(MyFrame.java:128) at MyFrame.createBasePanel(MyFrame.java:93) at MyFrame.(MyFrame.java:35) at part18.main(part18.java:8) ``` ``` import javax.swing.JFrame; import javax.swing.JLabel; import java.awt.Color; import java.awt.Font; import java.awt.Image; import javax.swing.JPanel; import java.io.File; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import javax.swing.ImageIcon; public class MyFrame extends JFrame { JLabel jlMsg; JPanel jpChild2; BufferedImage ba1; BufferedImage ba2; BufferedImage ba3; public MyFrame()throws java.io.IOException//コンストラクタ化 { File file1=new File("[Monster]Bat_pochi.jpg");//コウモリのファイル読み込み ba1=ImageIO.read(file1);//コウモリ画像全体を読み込む File file2=new File("[Monster]Goblin1_tapis.jpg");//ゴブリンのファイル読み込み ba2=ImageIO.read(file2);//ゴブリン画像全体を読み込む File file3=new File("[Monster]Slime1_pochi.jpg");//スライムのファイル読み込み ba3=ImageIO.read(file3);//スライム画像全体を読み込む setBounds(20,40,940,540);//フレームサイズ変更 setDefaultCloseOperation(EXIT_ON_CLOSE);//×ボタン有効化 add(createBasePanel());//親パネル作成しフレームに貼り付け setVisible(true);//フレームを表示状態へ enableEvents(java.awt.AWTEvent.KEY_EVENT_MASK);//キー入力有効化 } protected void processKeyEvent(java.awt.event.KeyEvent e) { if(e.getID()==java.awt.event.KeyEvent.KEY_PRESSED){ System.out.println("キー"+e.getKeyCode()+"が押されました"); if(e.getKeyCode()==java.awt.event.KeyEvent.VK_1){ jlMsg.setText("魔王と戦い勝利しました"); } if(e.getKeyCode()==java.awt.event.KeyEvent.VK_2){ jlMsg.setText("修行して強くなった"); } if(e.getKeyCode()==java.awt.event.KeyEvent.VK_3){ jlMsg.setText("宿屋に泊まった"); } } } //基盤パネルを作成 JPanel createBasePanel()throws java.io.IOException { JPanel jp=createPanel(Color.BLACK); //フォントを作成 Font f=new Font(Font.MONOSPACED,Font.BOLD,40); //レイアウト1行目 //パネルを作成し親パネルに貼り付け JPanel jpChild=createPanel(Color.BLUE);//小パネル作成 jp.add(jpChild);//親パネルにパネル追加 //ラベルを作成し子パネルに貼り付け JLabel jlChild=new JLabel(player.getStatusString());//文字列作成 jlChild.setFont(f);//文字サイズ変更 jlChild.setForeground(Color.WHITE);//文字色設定 jpChild.add(jlChild);//子パネルに文字追加 //レイアウト2行目 //可変表示パネル JPanel jpChild2=createPanel(Color.CYAN);//小パネル作成 jp.add(jpChild2);//親パネルにパネル追加 /* //選択肢をパネルに貼り付け JLabel jlMain=new JLabel( "1.すぐに魔王を倒しに行く2.修行する3.宿屋に泊まる" ); jlMain.setFont(f); jpChild2.add(jlMain); */ addMonster(); //レイアウト3行目 //ラベルを作成し親パネルに貼り付け jlMsg=new JLabel("魔王が世界を滅ぼそうとしています");//文字入力 jlMsg.setFont(f);//文字サイズ変更 jlMsg.setForeground(new Color(255,128,0));//文字色設定 jp.add(jlMsg);//ウィンドウに文字追加 System.out.println("プログラムを全て読み込みましました!");//読み込み確認 return(jp); } //ここより以降は関数作成コード //パネルを作成し背景色を設定する関数 JPanel createPanel(Color c) { JPanel jp=new JPanel(); jp.setBackground(c); return(jp); } void addMonster() { int cw=32;//セルサイズ/幅 int ch=48;//セルサイズ・高さ int sw=32*4;//表示サイズ・幅 int sh=48*4;//表示サイズ・高さ suraimu(jpChild2,ba3,0,0,cw,ch,sw,sh);//スライム表示の関数を呼び出して村人の正面の画像を表示する koomori(jpChild2,ba1,0,0,cw,ch,sw,sh);//コウモリ表示の関数を呼び出して村人の正面の画像を表示する goburinn(jpChild2,ba2,0,0,cw,ch,sw,sh);//ゴブリン表示の関数を呼び出して村人の正面の画像を表示する } /* @param jpChild2 表示対象パネル @param ba0,1,2,3 画像全体 @param x 表示する座標X @param y 表示する座標Y @param cw セルの大きさ・幅 @param ch セルの大きさ・高さ @param sw 表示サイズ・幅 @param sh 表示サイズ・高さ */ void koomori(JPanel jpChild2,BufferedImage ba1,int x,int y,int cw,int ch,int sw,int sh)//コウモリ表示関数作成 { BufferedImage bs1=ba1.getSubimage(cw*x,ch*y,cw,ch); //画像サイズ192*192に変更した画像の左端に切り取り Image im=bs1.getScaledInstance(sw,sh,Image.SCALE_DEFAULT); ImageIcon ii=new ImageIcon(im);//JLabelように型変換 JLabel jlImage=new JLabel(ii);//画像部品を作成 jlImage.setSize(sw,sh);//画像部品の座標とサイズ変更 jpChild2.add(jlImage);//親パネルに画像貼り付け } void goburinn(JPanel jpChild2,BufferedImage ba2,int x,int y,int cw,int ch,int sw,int sh)//ゴブリン表示関数作成 { BufferedImage bs2=ba2.getSubimage(cw*x,ch*y,cw,ch); //画像サイズ192*192に変更した画像の左端に切り取り Image im=bs2.getScaledInstance(sw,sh,Image.SCALE_DEFAULT); ImageIcon ii=new ImageIcon(im);//JLabelように型変換 JLabel jlImage=new JLabel(ii);//画像部品を作成 jlImage.setSize(sw,sh);//画像部品の座標とサイズ変更 jpChild2.add(jlImage);//親パネルに画像貼り付け } void suraimu(JPanel jpChild2,BufferedImage ba3,int x,int y,int cw,int ch,int sw,int sh)//スライム表示関数作成 { BufferedImage bs3=ba3.getSubimage(cw*x,ch*y,cw,ch); //画像サイズ192*192に変更した画像の左端に切り取り Image im=bs3.getScaledInstance(sw,sh,Image.SCALE_DEFAULT); ImageIcon ii=new ImageIcon(im);//JLabelように型変換 JLabel jlImage=new JLabel(ii);//画像部品を作成 jlImage.setSize(sw,sh);//画像部品の座標とサイズ変更 jpChild2.add(jlImage);//親パネルに画像貼り付け } } ```
回答: 考えたら、ファイル入力の失敗は例外が送出されるので、ヌルポにならないですね。失礼しました。 改めまして、createBasePanelメソッド内の次のコードに問題がありました。 > > > ``` > //可変表示パネル > JPanel jpChild2=createPanel(Color.CYAN);//小パネル作成 > jp.add(jpChild2);//親パネルにパネル追加 > ``` > > ここの`jpChild2`はローカル変数ですが... addMonsterメソッドで参照している`jpChild2`はクラスMyFrameのフィールドです。 そもそも見ているものが違うんですね。 次のように書き換えてください。 ``` //可変表示パネル jpChild2=createPanel(Color.CYAN);//小パネル作成 jp.add(jpChild2);//親パネルにパネル追加 ``` このエラー、質問者様の前回の質問と同じ原因ですね... fiveHundred様が回答されているように、同じ名前の変数が宣言されていることに問題があります。 次回以降、同様のエラーが出たときはこいつを重点的にチェックしてみてください。 残骸 メソッドslimeの、以下の行が怪しいです。 > > > ``` > BufferedImage bs3=ba3.getSubimage(cw*x,ch*y,cw,ch); > ``` > > ba3の中身が空っぽだと、ご提示のようなエラーが出ます。 ba3は、コンストラクタで初期化されているようですが... > > > ``` > File file3=new File("[Monster]Slime1_pochi.jpg");//スライムのファイル読み込み > ba3=ImageIO.read(file3);//スライム画像全体を読み込む > ``` > > ファイルが正しく開けていないような気がします。 画像ファイルのパスを絶対パスにしたとき、上手く動作するか確認してみてください。