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

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

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

JFrameはJFC/Swingフレームワークのコンポーネントであり、トップレベルのコンテナです。

Java

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

Q&A

解決済

2回答

819閲覧

JFrameの挙動がよくわかりません。

Keittio

総合スコア1

JFrame

JFrameはJFC/Swingフレームワークのコンポーネントであり、トップレベルのコンテナです。

Java

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

1グッド

0クリップ

投稿2023/03/07 09:25

ボタンを押すごとに画面内のTextFieldの内容と個数が切り替わるようにしたいです。
ボタンを1回押したときは正常に動作するのですが、2回目を押した際に何も反応しないです。
原因を教えていただきたいです。

import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.*; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; public class Test { public static void main(String[] args) { new a().showa(); } } class a extends JFrame implements ActionListener { JPanel p; ArrayList<JTextField> t; JButton b; int flg = 0; public void showa() { this.setTitle("a"); this.setSize(1000, 100); this.setResizable(false); p = new JPanel(); t = new ArrayList<>(); b = new JButton(); if (flg == 0) { for (int i = 0; i < 10; i++) { t.add(new JTextField()); t.get(i).setText("a"); p.add(t.get(i)); } } else { for (int i = 0; i < 5; i++) { t.add(new JTextField()); t.get(i).setText("b"); p.add(t.get(i)); } } b.setText("button"); b.addActionListener(this); this.add(b, BorderLayout.SOUTH); this.add(p); this.show(); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == this.b) { if (flg == 0) { this.flg = 1; } else { flg = 0; } this.p.removeAll(); this.showa(); } } }
TN8001👍を押しています

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

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

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

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

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

jimbe

2023/03/07 10:34

コンポーネントを随時増減するような画面は UI としてあまり良いとは思えません。 最初に全て設定しておけば良いのではないでしょうか。
guest

回答2

0

BorderLayout は一つの方向には一つしか表示出来ません。また、レイアウトは保存されているコンポーネントを並べるだけで、保存の管理には関係しません。
一方 JFrame の add メソッドはコンポーネントを追加するメソッドで、第2引数が同じだからとコンポーネントを置き換えたりはせずそのまま追加します。
つまりボタンを一回押した時、 JFrame には最初のボタンと二つ目のボタンがともに SOUTH で保存されていることになります。
同一方向のコンポーネントが複数あった場合に BorderLayout がどれを配置するかは、ドキュメント上では明言されていなかったと思います。

試した所では、二回目のボタン押下でも actionPerformed に渡される イベントのソース (getSource() で返されるオブジェクト) は最初のボタンのままで、従って e.getSource() == this.b が成立せず、二回目のボタンの処理は行われませんでした。

ボタンを押す度に JFrame から全部設定し直すような乱暴なことをしなくても、 「ボタンを押すごとに画面内のTextFieldの内容と個数が切り替わる」なら表示状態の設定(setVisible)や再配置要求(revalidate)等で出来ると思います。

java

1import java.awt.BorderLayout; 2import java.util.ArrayList; 3import java.util.List; 4 5import javax.swing.*; 6 7public class TestFrame extends JFrame { 8 public static void main(String[] args) { 9 SwingUtilities.invokeLater(() -> new TestFrame().setVisible(true)); 10 } 11 12 TestFrame() { 13 super("TestFrame"); 14 setDefaultCloseOperation(EXIT_ON_CLOSE); 15 setSize(1000, 100); 16 setResizable(false); 17 18 TestPanel panel = new TestPanel(); 19 add(panel, BorderLayout.CENTER); 20 21 JButton button = new JButton("button"); 22 button.addActionListener(e -> panel.reverseFlag()); 23 add(button, BorderLayout.SOUTH); 24 } 25 26 private class TestPanel extends JPanel { 27 private List<JTextField> list = new ArrayList<JTextField>(); 28 private int flag = 0; 29 TestPanel() { 30 super(); 31 for(int i=0; i<10; i++) { 32 JTextField textField = new JTextField(); 33 add(textField); 34 list.add(textField); 35 } 36 setFields(); 37 } 38 private void setFields() { 39 for(int i=0; i<10; i++) { 40 JTextField textField = list.get(i); 41 textField.setText(flag == 0 ? "a" : "b"); 42 textField.setVisible(i < 5 || flag == 0); 43 } 44 revalidate(); 45 } 46 void reverseFlag() { 47 flag ^= 1; 48 setFields(); 49 } 50 } 51}

投稿2023/03/07 11:15

編集2023/03/08 17:57
jimbe

総合スコア12646

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

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

Keittio

2023/03/08 16:53

詳しい解説ありがとうございます!
guest

0

ベストアンサー

ボタンを1回押したときは正常に動作するのですが、2回目を押した際に何も反応しないです。
原因を教えていただきたいです。

↓とすれば想定通りになりますが、個人的にはイヤですね(パネル内だけ入れ替えればいいのに全部作り直し)

java

1//this.p.removeAll(); 2this.getContentPane().removeAll();

自分だったらこうですかねぇ?

java

1import javax.swing.*; 2import java.awt.BorderLayout; 3import java.awt.event.ActionEvent; 4import java.awt.event.ActionListener; 5import java.util.ArrayList; 6 7 8public class Test extends JFrame implements ActionListener { 9 public static void main(String[] args) { 10 new Test().setVisible(true); 11 } 12 13 private final JPanel panel = new JPanel(); 14 private final ArrayList<JTextField> textFields = new ArrayList<>(); 15 private int flg; 16 17 public Test() { 18 setTitle("a"); 19 setSize(1000, 100); 20 setLocationRelativeTo(null); 21 setResizable(false); 22 23 var button = new JButton("button"); 24 button.addActionListener(this); 25 add(button, BorderLayout.SOUTH); 26 27 add(panel); 28 update(); 29 } 30 31 private void update() { 32 panel.removeAll(); 33 textFields.clear(); 34 35 if (flg == 0) { 36 for (var i = 0; i < 10; i++) { 37 var textField = new JTextField("a"); 38 textFields.add(textField); 39 panel.add(textField); 40 } 41 } else { 42 for (var i = 0; i < 5; i++) { 43 var textField = new JTextField("b"); 44 textFields.add(textField); 45 panel.add(textField); 46 } 47 } 48 49 // 再レイアウト&再描画 50 panel.revalidate(); 51 panel.repaint(); 52 } 53 54 @Override public void actionPerformed(ActionEvent e) { 55 flg = flg == 0 ? 1 : 0; 56 update(); 57 } 58}

投稿2023/03/07 10:18

TN8001

総合スコア9321

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

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

TN8001

2023/03/07 10:23 編集

あと提示コードだとボタンがリークしてそうです(removeActionListenerが必要)
Keittio

2023/03/07 11:11

ありがとうございます。 JFrame触り始めたばかりなのでもっと勉強頑張ります・v・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問