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

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

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

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

Q&A

解決済

3回答

1621閲覧

Java初心者:カウントダウン後に画面遷移をしたいです

kei0005

総合スコア19

Java

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

0グッド

1クリップ

投稿2018/01/05 07:19

Java初心者の質問です。こちらのサイト https://www.javadrive.jp/tutorial/timer/index1.html を参考にタイマーが5、4、3・・とカウントダウンしていき、-1になった瞬間に"GameOver"と"Score"を表示するようにしたいのですが,
タイマーが止まったままになってしまいうまくいっていない状況です。

以下、ソースコードです。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class TimerTest1 extends JFrame implements ActionListener{

javax.swing.Timer timer;
JLabel label;
int sec;

public void paint(Graphics g){ //この関数をカウントダウン後に呼び出したい

g.setColor(Color.YELLOW);
g.clearRect(0,0,1000,1000);
g.drawRect(0,0,800,8000);
g.setColor(Color.RED);
g.drawString("GameOver",330,40);
g.drawString("Score",330,60);
}

public static void main(String[] args){
TimerTest1 frame = new TimerTest1();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(10, 10, 800, 800);
frame.setTitle("タイトル画面");
frame.setVisible(true);
}

TimerTest1(){
sec = 5;
label = new JLabel();

JPanel labelPanel = new JPanel();
labelPanel.add(label);

timer = new Timer(1000 , this);

getContentPane().add(labelPanel, BorderLayout.WEST);

timer.start();
}

public void actionPerformed(ActionEvent e){
label.setText(sec "");

if (sec ==-1){
timer.stop();

System.exit(1);// これを強制終了ではなくゲームオーバー画面への遷移にしたい

}else{
sec--;
}
}
}


どなたかご教授お願いします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

質問文のソースコードがJFrame#paintをオーバーライドしている状態で、
ContentPaneにJPanel (labelPanel)を追加しているコードなため、描画処理の依存関係が破綻しています。。
paint処理を治すのが手間なので、アプローチ方法を変更しました。

JFrameのレイアウトマネージャをCardLayoutにして、GameOverパネルに表示を切り替えるサンプルソースコードです。
□注意点
Swingのコンポーネント(JFrame/JPanel)を継承したクラスでpaintメソッドはオーバライドしないでください。
どうしてもオーバーライドしたい時はpaintComponentをオーバーライドしてください。

Q107683.java

Java

1import java.awt.CardLayout; 2 3import javax.swing.JFrame; 4import javax.swing.JLabel; 5import javax.swing.JPanel; 6import javax.swing.SwingUtilities; 7import javax.swing.Timer; 8 9@SuppressWarnings("serial") 10public class Q107683 extends JFrame { 11 12 private Timer timer; 13 private int countdown_sec = 5;// 変数名をsecから変更 14 private CardLayout card = new CardLayout(0, 0); 15 16 public static void main(String[] args) { 17 // 画面の生成はSwingUtilities.invokeLaterを使用してスレッドセーフにしてくださいな。 18 SwingUtilities.invokeLater(() -> { 19 Q107683 frame = new Q107683(); 20 frame.setBounds(10, 10, 800, 800); 21 frame.setVisible(true); 22 }); 23 } 24 25 Q107683() { 26 // setDefaultCloseOperationは一番先頭で 27 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 28 setTitle("タイトル画面"); 29 setLayout(card); 30 JPanel labelPanel = new JPanel(); 31 JLabel label = new JLabel(); 32 labelPanel.add(label); 33 add(labelPanel, "title_window"); 34 timer = new Timer(1000, (e) -> { 35 label.setText(String.valueOf(countdown_sec)); 36 if (countdown_sec ==-1){ 37 timer.stop(); 38 showPanel("gameover_window"); 39 return; 40 } 41 countdown_sec--; 42 }); 43 JPanel game_over = new GameOver(); 44 add(game_over, "gameover_window"); 45 // コンストラクタ内からTimer(別スレッド)をスタートするのはスレッドの可視性の関係上あまり良くないです。 46 // frame.setVisible(true);後に別のメソッドより、timer.startを呼び出す形に変更したほうがいいです。 47 timer.start(); 48 } 49 50 public void showPanel(String name) { 51 card.show(getContentPane(), name); 52 } 53 54} 55 56

GameOver.java

Java

1import javax.swing.JPanel; 2import java.awt.BorderLayout; 3import javax.swing.JLabel; 4import javax.swing.SwingConstants; 5import java.awt.Color; 6 7@SuppressWarnings("serial") 8public class GameOver extends JPanel { 9 /** 10 * Create the panel. 11 */ 12 public GameOver() { 13 //背景を黄色にする。 14 setBackground(Color.YELLOW); 15 setLayout(new BorderLayout(0, 0)); 16 // drawStringはコンポーネントの領域を計算する必要があるので、文字列を表示するだけならJLabelの方がいいです。 17 JLabel lblGameOver = new JLabel("GameOver"); 18 // 文字色を赤色にする。 19 lblGameOver.setForeground(Color.RED); 20 lblGameOver.setVerticalAlignment(SwingConstants.TOP); 21 lblGameOver.setHorizontalAlignment(SwingConstants.CENTER); 22 add(lblGameOver, BorderLayout.NORTH); 23 24 JLabel lblScore = new JLabel("Score"); 25 lblScore.setForeground(Color.RED); 26 lblScore.setHorizontalAlignment(SwingConstants.CENTER); 27 add(lblScore); 28 } 29}

□補足
作った画面のSwingのコンポーネント配置が知りたい時は画面をクリックした状態で、Ctrl+Shift+F1キーを押下すると、Swingのコンポーネントツリーがコンソールに出力されます。

投稿2018/01/05 12:12

編集2018/01/06 13:53
umyu

総合スコア5846

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

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

kei0005

2018/01/08 05:34

ありがとうございます! 自分の思ってたような形に動いてくれました!
guest

0

要はsec == -1のときにpaint内の「画面を黄色に染めて、赤文字でGameOverやScoreを表示」が出来ればいいんですよね?

Java

1public void paint(Graphics g){ // secが-1でないときは何もしないようにすればよい 2 if(sec == -1) { 3 g.setColor(Color.YELLOW); 4 g.clearRect(0,0,1000,1000); 5 g.drawRect(0,0,800,8000); 6 g.setColor(Color.RED); 7 g.drawString("GameOver",330,40); 8 g.drawString("Score",330,60); 9 } 10}

paintというのは基本的に「プログラマ」が呼び出すのではなく、「OS」や「Java」が勝手に呼び出すので、任意のタイミングでこちらから呼び出す、というものではありません。そのため、「勝手なタイミングで呼ばれてもいいように内部の処理を書く」というのが正しい手法です。
「プログラマ」から確実に「今この瞬間paintを実行してくれ!」という方法は無いですが、「次暇になったときにpaintを実行してくれ」というお願いは可能です。それはrepaint()です。これを呼び出せば、できるだけ早いタイミングでpaintが実行されます。なので、カウントダウンが終わり、secが-1になったときにpaintを予約するためにrepaintを呼び出しておきましょう。

Java

1if (sec ==-1){ 2 timer.stop(); 3 repaint(); 4}

投稿2018/01/05 07:42

masaya_ohashi

総合スコア9206

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

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

kei0005

2018/01/08 05:35

迅速な回答ありがとうございます! repaint();なんていう便利なものがあったのですね・・
guest

0

System.exit(1);の代わりにthis.repaint();を呼べば、一応画面は更新できますよ。
あとは、状態を管理して、いつどういう表示を行うか決めてみてください。
昨日Timerを使う例を別な質問に回答しましたので、そちらも参考にしてみてください。

https://teratail.com/questions/107417

投稿2018/01/05 07:50

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kei0005

2018/01/08 05:44

回答ありがとうございます! ワニワニパニックの方も参考にしたいと思います・・!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問