質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

2回答

1777閲覧

初期化しているにもかかわらずNullPointerExceptionが発生する

tarutarupop

総合スコア20

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

0クリップ

投稿2017/10/10 04:40

お世話になっております。

javaのswingを学ぶため四目並べゲームのプログラムを作っていたのですが、java.lang.NullPointerExceptionのエラーが発生し解消に難航しています。

二つあり一つ目が、GameScreen コンストラクタ内のsetTelllimittext(system.getSecond());
Gamesystemにあるint secを参照するところ。

二つ目が、GameSystem 92行目screen.setTelllimittext(sec);
表示する秒数を更新するため、Gamescreentelllimitのテキストを変更する関数にsecを渡すところ。

どちらもsecを参照しているためこれがnullになっているのはわかるのですが、それがなぜなのかがわかりません。secの宣言時に値を入れてみたり宣言する場所を変えてみたりしたのですが解決できませんでした。初歩的な見落としのような気もしますが、どうかご指摘のほどお願いいたします。

Java

1public class GameScreen extends JPanel implements ActionListener{ 2 private int cn; //升目の数 cn * cn 3 private boolean press = true; 4 private JPanel backpane; 5 private JLabel telllimit; 6 private GameSystem system; 7 private JLabel tellcolor; 8 private Color player_c; 9 static JLabel timelimit; 10 static boolean play_turn; //現在のターンを保持 11 static boolean[] enter ; //すべての入力を保持 12 static ArrayList<ArrayList<JButton>> y_coordinate = new ArrayList<ArrayList<JButton>>(); 13 14 public static void main(String args[]){ 15 JFrame jf = new JFrame(); 16 GameScreen gs = new GameScreen(15); 17 jf.add(gs); 18 jf.pack(); 19 jf.setVisible(true); 20 //ゲーム開始 21 new GameSystem(15); 22 } 23 24 public GameScreen(int n){ 25 /* 26 * 画面生成 27 */ 28 //親パネル 29 super(); 30 this.setPreferredSize(new Dimension(930,700)); 31 this.setLayout(null); 32 play_turn = true; //初期値(初期ターン) 33 34 //ターン表示のためのパネル 35 tellcolor = new JLabel(); 36 tellcolor.setBackground(getPlayer_c()); 37 tellcolor.setBounds(0, 0, 200, 200); 38 this.add(tellcolor); 39 40 //残り時間表示のためのパネル 41 telllimit = new JLabel(); 42 telllimit.setBorder(new BevelBorder(BevelBorder.RAISED, Color.blue, Color.black)); 43 telllimit.setBounds(200, 0, 430, 200); 44 telllimit.setForeground(Color.RED); 45 setTelllimittext(system.getSecond()); 46 this.add(telllimit); 47 48 cn = n; 49 enter = new boolean[cn*cn]; 50 51 //升目パネル 52 JPanel screen = new JPanel(); 53 screen.setBounds(100,220,720,450); 54 screen.setLayout(new GridLayout(n,n,0,0)); 55 for(int i = 0;i<cn;i++){ 56 ArrayList<JButton> x_coordinate = new ArrayList<JButton>(); 57 for(int t = 0;t<cn;t++){ 58 JButton cell = CreateCell(i,t); 59 cell.addActionListener(this); 60 screen.add(cell); 61 x_coordinate.add(cell); 62 } 63 y_coordinate.add(x_coordinate); 64 } 65 this.add(screen); 66 } 67 68 public JButton CreateCell(int x,int y){ 69 JButton btn = new JButton(); 70 btn.setSize(10, 10); 71 btn.setActionCommand(x+"-"+y); 72 return btn; 73 } 74 75 public void setTelllimittext(int second){ 76 String s= "残り時間 "+ second +" 秒"; 77 telllimit.setText(s); 78 } 79 80 @Override 81 public void actionPerformed(ActionEvent e) { 82 if(press == true){ 83 84 press = false; 85 } 86 87 String coordinate = e.getActionCommand(); 88 for(int k=0;k<cn;k++){ 89 for(int j = 0;j<cn;j++){ 90 String number = k+"-"+j; 91 if(coordinate.equals(number)){ 92 int order = k*20 + j+1; //入力の番号を作成 93 if(play_turn == true){ 94 player_c = Color.RED; 95 system.addA(order); 96 }else{ 97 player_c = Color.BLUE; 98 system.addB(order); 99 } 100 changeTurn(); 101 if(k == 19){ //入力が底の時 102 processEnter(order,k,j,player_c); 103 }else{ //入力が上部の時 104 if(enter[order+20] == false){ 105 System.out.println("無効な入力です"); 106 }else{ 107 processEnter(order,k,j,player_c); 108 } 109 } 110 system.createCombinations(); 111 } 112 } 113 } 114 return; 115 } 116 117 public Color getPlayer_c(){ 118 return player_c; 119 } 120 121 public void changeTurn(){ 122 if(play_turn == true){ 123 player_c = Color.RED; 124 play_turn = false; 125 }else{ 126 player_c = Color.BLUE; 127 play_turn = true; 128 } 129 tellcolor.setBackground(getPlayer_c()); 130 } 131 132 /* 色塗り処理 */ 133 public void processEnter(int order,int k,int j,Color player_c){ 134 /* 過去に入力があればtrueなければfalse */ 135 if( enter[order] == true){ 136 System.out.println("既に入力されています"); 137 return; 138 }else{ 139 y_coordinate.get(k).get(j).setBackground(player_c); 140 enter[order] = true; 141 } 142 } 143}

Java

1 2public class GameSystem implements ActionListener{ 3 private int limit; 4 private Timer timer; 5 private int sec = 0; 6 private Combinations<Integer> c ; 7 private GameScreen screen ; 8 //private Screen sc; 9 private ArrayList<Integer> number_a = new ArrayList<Integer>(); //player1の入力 10 private ArrayList<Integer> number_b = new ArrayList<Integer>(); //player2の入力 11 private boolean finish = false; 12 13 14 public GameSystem(int l){ 15 limit = l; 16 timer = new Timer(limit*1000,this); 17 timer.start(); 18 } 19 20 public void createCombinations(){ 21 if(GameScreen.play_turn == !true){ 22 if(number_a.size() > 3){ 23 c = new Combinations<Integer>(number_a,4); 24 judgeWinner(); 25 }else{ 26 return; 27 } 28 }else{ 29 if(number_b.size() > 3){ 30 c = new Combinations<Integer>(number_b,4); 31 judgeWinner(); 32 }else{ 33 return; 34 } 35 } 36 37 } 38 /* 勝者判定 */ 39 public void judgeWinner(){ 40 Iterator<List<Integer>> i = c.iterator(); 41 while(i.hasNext()){ 42 List<Integer> t = i.next(); 43 Collections.sort(t); //小さい順に並び替え 44 Collections.reverse(t); //大きい順へ 45 if(t.get(0)-t.get(3)==3 && t.get(0)-t.get(1)==1 || 46 t.get(0)-t.get(1)==20 && t.get(1)-t.get(2)==20 && t.get(2)-t.get(3)==20 || 47 t.get(0)-t.get(1)==21 && t.get(1)-t.get(2)==21 && t.get(2)-t.get(3)==21 || 48 t.get(0)-t.get(1)==19 && t.get(1)-t.get(2)==19 && t.get(2)-t.get(3)==19 ){ 49 finish = true; 50 System.out.println("ゲーム終了"); 51 } 52 } 53 } 54 public void addA(int n){ 55 number_a.add(n); 56 } 57 58 public void addB(int n){ 59 number_b.add(n); 60 } 61 62 public int getSecond(){ 63 return sec; 64 } 65 66 @Override 67 public void actionPerformed(ActionEvent e) { 68 if(finish == true){ 69 timer.stop(); 70 /*後々 71 e.setSource(this); 72 sc.actionPerformed(e); 73 */ 74 } 75 if (sec == limit){ 76 sec = 0; 77 screen.changeTurn(); 78 }else{ 79 screen.setTelllimittext(sec); 80 sec++; 81 } 82 } 83} 84

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

public class GameScreen extends JPanel implements ActionListener{ private int cn; //升目の数 cn * cn private boolean press = true; private JPanel backpane; private JLabel telllimit; private GameSystem system;
public class GameSystem implements ActionListener{ private int limit; private Timer timer; private int sec = 0; private Combinations<Integer> c ; private GameScreen screen ;

「GameScreen has GameSystem」「GameSystem has GameScreen」の関係で循環参照してしまっているので、まず構造を変えたほうがいいのでは?

投稿2017/10/10 05:49

tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tkturbo

2017/10/10 06:10

たぶん循環参照による再帰的なコンストラクタ呼び出しがStackOverflowErrorの原因と思われ。
guest

0

ベストアンサー

どちらもsecを参照しているためこれがnullになっているのはわかるのですが

残念ながら、この認識自体が違います。

1つ目は、フィールドとしてprivate GameSystem system;となっていますが、コンストラクタ内で代入がまったくないため、setTelllimittext(system.getSecond());のところでもsystem == nullとなっています。

2つ目の方でも同じくprivate GameScreen screen;へのオブジェクト代入がないため、これがnullのままです。

投稿2017/10/10 04:45

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tarutarupop

2017/10/10 05:37

一つ目はGameScreenのコンストラクタでSystemを初期化することで無事解決できました。 しかし、二つ目の解決法がわかりません。具体的にはscreenをインスタンス化するタイミングがわかりません。GameSystemのほうでGameScreenのインスタンス化を行おうとするとjava.lang.StackOverflowErrorというエラーが発生しました。GameScreenから呼び出されたGameSystemのほうで新たにGameScreenをインスタンス化したため無限ループが発生したのかなと予想しているのですが...これはどのように解決すればよいのでしょう?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問