- ベストアンサー
NullPointerExeptionを解決するための方法
- RPGを作成中に発生するNullPointerExeptionエラーに対処する方法を解説します。
- MainPanel()メソッド内の問題点として、mainpanel変数の警告やinsets.leftの値の取得方法が挙げられます。
- drawMapメソッド内の問題点として、マップの描画に関する処理の誤りがあります。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>insets = frame.getInsets(); >のように値を取得しています。 insetsは、frameが画面上に実際に描画されるまでnullです。 全体の構造が完全にはつかめませんが、frameが描画される前に drowMap(int mapName)メソッドが呼び出されているためだと思われます。 対処法としては、frameコンポーネント内のpaint(Graphics g)を オーバーライドしたメソッドで、getInsets()を実行することです。 このpaint(...)メソッドは、実際に描画するときにしか呼び出されませんので、 ここでsuper.paint(g)の後でgetInsets()を行えば、Insetsオブジェクトが nullである問題は避けられることになります。 >これらの問題点はコンソールに表示されるだけですが、別にeclipse側で、 >MainPanel mainpanel = new MainPanel(); >のmainpanelに黄色い下線が表示され、「ローカル変数mainpanelは >読み取られません」という警告が出されます。 これは、mainpanelオブジェクト変数は定義されているだけで、 使用されていないと言う意味です。 今のままならば、 MainPanel mainpanel = new MainPanel(); は、 new MainPanel(); と書けば、十分だということです。 あと、2点アドバイスさせて頂きます。 1点目は、 >m.drowMap(Map.HotelRoom); 現行は、HotelRoom等のアイテムをint型のシリアル定数で識別して 描画するようにされていられますが、このアイテムこそオブジェクト化される べきであると思われます。 --- MapItem.java --- interface MapItem { Image getImage(); Point2D getLocation(); void setLocation( Point2D location ); Dimension2D getSize(); void setZoom( Dimension2D size ); void draw( Graphics g ); } --- AbstractMapItem.java --- public abstract class AbstractMapItem implements MapItem { Point2D location = new Point2D(); Dimension2D size = new Dimension2D(); public void draw( Graphics g ) { Insets insets = g.getInsents(); g.drawImage( getImage(), insets,left+location.x ... ); } public Point2D getLocation() { return location; } public void setLocation( Point2D location ) { this.location = location; } public Dimension2D getSize() { return size; } public void setZoom( Dimension2D size ) { this.size = size; } } --- HotelRoom.java --- public class HotelRoom extends AbstractMapItem { public Image getImage() { Image image = ImageIO.read(getClass().getResource("/Resource/mapchip/HotelRoom.jpg")); return image; } } そして、単純にはこれをFrame内で List<MapItem> mapItens; addMapItem( MapItem mapItem ) { mapItems.add( mapItem ); } removeMapItem( MapItem mapItem ) { mapItems.remove( mapItem ); } paint( Graphics g ) { for( MapItem mi : mapItems ) { mi.draw( g ); } } この様に、描画プロセスを変更されることをお勧めします。 2点目は、 現在、Frameに直接グラフィックスを描画されておられるようですが、frameにJPanelを 追加して、その上にpaintComponent(Graphics g)で描画するように変更したほうが より汎用性が増すと思われます。 質問の本質に関係のない部分の方が断然長くなってしまった感がありますが、 描画プロセス全体をリファクタリングされることをお勧めします。 ホテルは、現実世界で物体ですので、プログラミング上でオブジェクトとして 定義することが非常に自然です。 ホテルの色を変更したりするようなメソッドを持たせたりという様に別の処理を 追加していった場合に、現行のままだと組み合わせ爆発を起こすことにもなります。
その他の回答 (1)
- hofchan
- ベストアンサー率62% (17/27)
まず、あなたのコードは読んでいないですが NullPointerException が投げられると言うことは null であってはおかしい場所が null なのです 怪しいオブジェクトを調べれば直ります
お礼
ご回答ありがとうございます。 やっぱりどこかがNullの入らない場所がNullってことですよね・・・。もう少し探してみることにします。
お礼
ご回答ありがとうございます。ウィンドウフレームの描画前にgetInsets()が行われていたからだったのですね! 解説書にpaint()メソッドについての解説がなかったので、その辺りはずっとほっぽらかしにしていたのですが、知識が曖昧なままでやっていると、お先真っ暗かもしれないですね・・・。とりあえず、このバグを改修するためにも、もう一冊本を買うなり、解説サイトを読むなどして、知識の増強を図ってきます。