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

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

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

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

Swing

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

Q&A

解決済

1回答

540閲覧

swingのGUIプログラムについて

yuto1123581321

総合スコア16

Java

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

Swing

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

0グッド

0クリップ

投稿2020/01/14 15:20

前提・実現したいこと

swingのGUIプログラミングについて.
現在swingを用いてライフゲームを作成しているのですが,
盤面をクリックやドラッグでの生死の変更,クリックによる次世代への遷移,以前の画面への遷移を実装しました.今,0.5秒ごとに自動的に次世代へ更新していくAutoボタン機能を付随しようと考えているのですがうまくいきません.

発生している問題・エラーメッセージ

Autoを押すと初めのうちだけ正常に動くがすぐに盤面の動き方がおかしくなりウインドウが固まってしまう

該当のソースコード

Java

1package lifegame; 2import java.awt.event.ActionEvent; 3import java.awt.event.ActionListener; 4import javax.swing.Timer; 5 6public class AutoListener implements ActionListener{ 7 private BoardModel model; //Boardmodel=盤面のクラス 8 private Timer timer; 9 public AutoListener(BoardModel model){ 10 this.model = model; 11 } 12 public void actionPerformed(ActionEvent e){ 13 timer = new Timer(500, this); 14 timer.start(); 15 model.next(); //nextメソッドは盤面を次世代へ進めるもの 16 return; 17} 18}

試したこと

ネットでいろいろ調べてみたがマルチスレッドというものが必要らしいというのはわかっているが何をすれば良いかいまいちわからないです.よろしくお願いします.

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

jimbe

2020/01/14 15:32

> 盤面の動き方がおかしくなり どうなるはずがどうなるのでしょう.
yuto1123581321

2020/01/14 15:52

ご回答ありがとうございます 期待する動きは要するにnextボタンを同じタイミングで連打した時の動きなのですが,(要するに滑らかに次世代へと盤面表示が切り替わる), Timerを使っただけだと途中かくついて急にありえない遷移をしたり重たくなってウインドウのボタンが反応しなくなったりしてしまいます
guest

回答1

0

ベストアンサー

まず, 書かれたコードがどう動いているか想像してみてください.
おそらく AutoListener は AUTOボタンのリスナとして登録していると思いますので, AUTOボタンを押したとしましょう.

AutoListener.actionPerformed が呼ばれ, 0.5 秒おきの Timer(1つ目) が生成(new)・開始(start) されて, model.next が実行されます.

0.5 秒後, timer(1つ目) によって AutoListener.actionPerformed が呼ばれ, 0.5 秒おきの Timer(2つ目) が生成(new)・開始(start) されて, model.next が実行されます.

0.5 秒後, timer(1つ目) によって AutoListener.actionPerformed が呼ばれ, 0.5 秒おきの Timer(3つ目) が生成(new)・開始(start) されて, model.next が実行されると同じ頃に timer(2つ目) によって AutoListener.actionPerformed が呼ばれ, 0.5 秒おきの Timer(4つ目) が生成(new)・開始(start) されて, model.next が実行されます.

0.5 秒後, timer(1つ目) によって AutoListener.actionPerformed が呼ばれ, 0.5 秒おきの Timer(5つ目) が生成(new)・開始(start) されて, model.next が実行されると, timer(2つ目) によって AutoListener.actionPerformed が呼ばれ, 0.5 秒おきの Timer(6つ目) が生成(new)・開始(start) されて, model.next が実行され, さらに timer(3つ目) によって AutoListener.actionPerformed が呼ばれ, 0.5 秒おきの Timer(7つ目) が生成(new)・開始(start) されて, model.next が実行され, もう一つ timer(4つ目) によって AutoListener.actionPerformed が呼ばれ, 0.5 秒おきの Timer(8つ目) が生成(new)・開始(start) されて, model.next が実行されます.
:
:
お分かりでしょうか.
Timer は止めるまで AutoListener.actionPerformed を呼び続け, AutoListener.actionPerformed が呼ばれる度に新たな Timer が生成・開始されてゆきます.
何時かは資源が尽き, 異常終了します.

Timer から呼び出す actionPerformed はボタンとは別にしたほうが良いかと思います.

投稿2020/01/14 15:50

jimbe

総合スコア12646

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

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

yuto1123581321

2020/01/14 15:57

GUIを初めて使うのでよくわからいので伺ってもよろしいでしょうか. Timerから呼び出すactionPerformedをボタンと別にするとはどういうことか教えていただけるとありがたいです. Mainクラスのrun内のAndoボタンの処理は次のように書いてます JButton autobutton = new JButton("Auto"); buttonPanel.add(autobutton); //(buttonPanel = JFrameのパネル) autobutton.addActionListener(new AutoListener(model));
yuto1123581321

2020/01/14 15:59

理想の挙動はAutoボタンを押すと世代を更新し続けるが他の機能(例えばクリックでセルを動いている途中に変更などの操作が可能である)の邪魔をしないようにしたいです
jimbe

2020/01/14 16:00

> timer = new Timer(500, this); を timer = new Timer(500, new ActionListener(){ public void actionPerformed(ActionEvent e){ model.next(); } }); としてみては如何でしょうか.
jimbe

2020/01/14 16:05

0.5 秒おきに更新されているライフゲームのセルを, 動かしたままクリックで更新するのは現実的では無いように思えます. AUTO中は更新できないことにして, STOPボタンを新設しSTOPしたら更新可能とし, 更新が終わったらまた AUTOボタンで開始するようなほうが, 任意の形のセルを設定したりがやり易いのではないでしょうか.
yuto1123581321

2020/01/14 16:10

上記のコードに変更したら動かすことができました. ありがとうございます. おっしゃる通りそちらの機能の方が理にかなっているので実装させていただきます.ありがとうございました 最後に1つだけ伺いたいのですがなぜ上記のように書き換えると動くかもう少しわかりやすく教えていただけると嬉しいです!!(理解力がなくてすみません)
jimbe

2020/01/14 16:26 編集

Timer の仕様は, 一定時間毎に第二引数に指定した ActionListener の actionPerformed を呼び出すことです. 件の場合, 一定時間毎にしたいのは( Timer の生成では無く) model.next だけです. ですので, AUTOボタンのリスナである AutoListener とは別に, model.next だけを行う actionPerformed を持つ ActionListener を作って Timer に渡しています.
yuto1123581321

2020/01/14 16:26

理解できました!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問