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

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

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

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

Q&A

解決済

1回答

1344閲覧

keyListenerが、画面遷移後に反応しない。

退会済みユーザー

退会済みユーザー

総合スコア0

Java

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

0グッド

0クリップ

投稿2021/06/19 19:20

前提・実現したいこと

KeyListenerが期待通りに動作しません。

今までの実装で、Main関数を司るClientMain, frameを司るGameFrame, タイトル画面を司るTitleView, ゲーム画面を司るGameViewを実装しました。

GameView内で利用しているKeyListenerについて、ClientMainのmain関数で「初期画面をGameViewに設定した場合」には、KeyListnerが動作していることは確認済です。しかし、「初期画面をTitleViewに設定した場合」には、全く反応がありません。

当初はフォーカスの問題かと思ったのですが、TabキーでのFocus移動によっても改善しなかったので、別の問題かと思われます。(おそらく、画面遷移時の処理が怪しいです。)

該当のソースコード

java

1public class ClientMain { 2 public static GameFrame frame; 3 public static void main(String[] args) { 4 frame = new GameFrame(); 5 frame.changeView(new TitleView()); //new GameView() と置き換えるとKeyListenerが動く。 6 } 7}

java

1import java.awt.*; 2import javax.swing.*; 3 4public class GameFrame extends JFrame { 5 public GameFrame() { 6 //表示ウィンドウの設定 7 this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 8 this.setTitle("TypingEats"); 9 this.setSize(800, 500); 10 this.setResizable(false); 11 this.setLocationRelativeTo(null); 12 this.setBackground(Color.GRAY); 13 this.setVisible(true); 14 } 15 16 public void changeView(JPanel view) { 17 getContentPane().removeAll(); 18 19 super.add(view); 20 validate(); 21 repaint(); 22 } 23}

java

1import java.awt.*; 2import java.awt.event.*; 3import javax.swing.*; 4 5public class TitleView extends JPanel implements ActionListener { 6 public TitleView() { 7 //レイアウトを変更可能に設定 8 this.setLayout(null); 9 setFocusable(true); 10 11 //スタートボタンの追加 12 JButton startButton = new JButton("GAME START"); 13 startButton.setSize(300,60); 14 startButton.setLocation(250,350); 15 startButton.addActionListener(this); 16 startButton.setActionCommand("start"); 17 this.add(startButton); 18 //Enterでスタートボタンを押せるように設定 19 ClientMain.frame.getRootPane().setDefaultButton(startButton); 20 } 21 22 @Override 23 public void paintComponent(Graphics graphics) { 24 super.paintComponent(graphics); 25 graphics.setColor(Color.RED); 26 graphics.fillRect(0, 0, ClientMain.frame.getWidth(), ClientMain.frame.getHeight()); 27 } 28 29 @Override 30 public void actionPerformed(ActionEvent e) { 31 32 if(e.getActionCommand() == "start") { 33 ClientMain.frame.changeView(new GameView()); 34 } 35 } 36}

java

1import java.awt.*; 2import java.awt.event.*; 3import java.util.Random; 4 5import javax.swing.*; 6 7public class GameView extends JPanel implements ActionListener, KeyListener { 8 public JLabel label; 9 static final String[] words = {"apple","banana","chocolate","demaecan"}; 10 11 public GameView() { 12 13 //レイアウトを変更可能に設定 14 this.setLayout(null); 15 16 //キーの打ち込みを検出できるように設定 17 setFocusable(true); 18 addKeyListener(this); 19 20 //タイトル画面に戻るボタンの追加 21 // JButton goTitleButton = new JButton("Back to Title"); 22 // goTitleButton.setSize(100, 40); 23 // goTitleButton.setLocation(0, 0); 24 // goTitleButton.addActionListener(this); 25 // goTitleButton.setActionCommand("backToTitle"); 26 // this.add(goTitleButton); 27 28 //お題表示ラベルの追加 29 label = new JLabel("start", SwingConstants.CENTER); 30 label.setSize(800,80); 31 label.setLocation(0,120); 32 label.setFont(new Font(null, Font.PLAIN, 40)); 33 this.add(label); 34 } 35 36 //ランダムなお題をピックアップする関数 37 public String getRandomWord() { 38 Random random = new Random(); 39 int index = random.nextInt(words.length); 40 41 return words[index]; 42 } 43 44 @Override 45 public void paintComponent(Graphics graphics) { 46 super.paintComponent(graphics); 47 graphics.setColor(Color.GREEN); 48 graphics.fillRect(0, 0, ClientMain.frame.getWidth(), ClientMain.frame.getHeight()); 49 } 50 51 @Override 52 public void actionPerformed(ActionEvent e) { 53 if(e.getActionCommand() == "backToTitle") { 54 ClientMain.frame.changeView(new TitleView()); 55 } 56 } 57 58 @Override 59 public void keyPressed(KeyEvent e) { 60 61 } 62 63 @Override 64 public void keyReleased(KeyEvent e) { 65 66 } 67 68 @Override 69 public void keyTyped(KeyEvent e) { 70 char key = e.getKeyChar(); 71 String word = label.getText(); 72 73 if(word.charAt(0) == key) { 74 //お題が打ち込み終わったかを判定 75 if(word.length() == 1) { 76 //お題を全てタイプされたら、新しいお題へ 77 label.setText(getRandomWord()); 78 }else { 79 //お題の残りがあるなら、黒文字表示、先頭文字を一文字消去 80 label.setForeground(Color.BLACK); 81 label.setText(word.substring(1)); 82 } 83 84 repaint(); 85 }else { 86 //間違えたキーを打つと赤文字表示 87 label.setForeground(Color.RED); 88 } 89 } 90}

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

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

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

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

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

guest

回答1

0

ベストアンサー

遷移ありの場合でも、ほかのウィンドウをアクティブにしてからまた戻ってくるとキーが打てますので、KeyListnerが効いていないわけではありません。
おそらく遷移後にGameViewにフォーカスがないんでしょう(特に深堀しませんが^^;

requestFocusInWindowを呼んだら、手元環境では想定通り最初からキーが打てました。
JComponent (Java Platform SE 8 )

Java

1import java.awt.Color; 2import java.awt.Font; 3import java.awt.event.ActionEvent; 4import java.awt.event.ActionListener; 5import java.awt.event.KeyEvent; 6import java.awt.event.KeyListener; 7import java.util.Random; 8import javax.swing.JButton; 9import javax.swing.JFrame; 10import javax.swing.JLabel; 11import javax.swing.JPanel; 12import javax.swing.SwingConstants; 13import javax.swing.WindowConstants; 14 15public class ClientMain { 16 public static GameFrame frame; 17 18 public static void main(String[] args) { 19 frame = new GameFrame(); 20 frame.changeView(new TitleView()); 21// frame.changeView(new GameView()); 22 } 23} 24 25class GameFrame extends JFrame { 26 public GameFrame() { 27 setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 28 setTitle("TypingEats"); 29 setSize(800, 500); 30 setResizable(false); 31 setLocationRelativeTo(null); 32// setBackground(Color.GRAY); 33 setVisible(true); 34 } 35 36 public void changeView(JPanel view) { 37 getContentPane().removeAll(); 38 add(view); 39 view.requestFocusInWindow(); 40 validate(); 41 } 42} 43 44class TitleView extends JPanel implements ActionListener { 45 public TitleView() { 46 setLayout(null); 47 setFocusable(true); 48 setBackground(Color.RED); 49 50 JButton startButton = new JButton("GAME START"); 51 startButton.setBounds(250, 350, 300, 60); 52 startButton.addActionListener(this); 53 startButton.setActionCommand("start"); 54 add(startButton); 55 56 ClientMain.frame.getRootPane().setDefaultButton(startButton); 57 } 58 59 @Override public void actionPerformed(ActionEvent e) { 60 if (e.getActionCommand().equals("start")) { 61 ClientMain.frame.changeView(new GameView()); 62 } 63 } 64} 65 66class GameView extends JPanel implements ActionListener, KeyListener { 67 private static final String[] words = { "apple", "banana", "chocolate", "demaecan" }; 68 private JLabel label; 69 70 public GameView() { 71 setLayout(null); 72 setFocusable(true); 73 addKeyListener(this); 74 setBackground(Color.GREEN); 75 76// JButton goTitleButton = new JButton("Back to Title"); 77// goTitleButton.setBounds(0, 0, 100, 40); 78// goTitleButton.addActionListener(this); 79// goTitleButton.setActionCommand("backToTitle"); 80// this.add(goTitleButton); 81// ClientMain.frame.getRootPane().setDefaultButton(goTitleButton); 82 83 label = new JLabel("start", SwingConstants.CENTER); 84 label.setBounds(0, 120, 800, 80); 85 label.setFont(new Font(null, Font.PLAIN, 40)); 86 this.add(label); 87 } 88 89 private Random random = new Random(); 90 91 private String getRandomWord() { 92 return words[random.nextInt(words.length)]; 93 } 94 95 @Override public void actionPerformed(ActionEvent e) { 96 if (e.getActionCommand().equals("backToTitle")) { 97 ClientMain.frame.changeView(new TitleView()); 98 } 99 } 100 101 @Override public void keyTyped(KeyEvent e) { 102 char key = e.getKeyChar(); 103 String word = label.getText(); 104 105 if (word.charAt(0) == key) { 106 if (word.length() == 1) { 107 label.setText(getRandomWord()); 108 } else { 109 label.setForeground(Color.BLACK); 110 label.setText(word.substring(1)); 111 } 112 } else { 113 label.setForeground(Color.RED); 114 } 115 } 116 117 @Override public void keyPressed(KeyEvent e) { } 118 119 @Override public void keyReleased(KeyEvent e) { } 120}

投稿2021/06/21 10:05

TN8001

総合スコア9801

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問