回答編集履歴

5

誤字修正等

2023/10/20 16:33

投稿

jimbe
jimbe

スコア13336

test CHANGED
@@ -71,7 +71,8 @@
71
71
  ただ、 JFrame は基本的には一つのアプリケーション内で幾つも出したり消したりするような類ではありません。一つの JFrame を一つのアプリケーションの土台とし、表示内容が変わるならそれぞれを JPanel 等として JFrame 内への配置・表示を切り替える形にするのが良いと思います。
72
72
 
73
73
  以下のコードは JFrame 1つですが Event1Frame/Event2Frame の組と同じ動きです。
74
+ CardLayout は、複数のパネルの中から一つを選んで表示することが出来ます。
74
- ScanPanel のコンストラクタに渡している Cunsumer オブジェクトによって、ボタン押下時の動作を外から指定できるようにしているのがミソでしょうか。クラス名は新しめですが使い方は addActionListener と同じ感じです。
75
+ ScanPanel のコンストラクタに渡している Consumer オブジェクトによって、ボタン押下時の動作を外から指定できるようにしているのがミソでしょうか。クラス名は新しめですが使い方は addActionListener と同じ感じです。
75
76
 
76
77
  SingleFrame.java
77
78
  ```java

4

追加

2023/10/19 08:08

投稿

jimbe
jimbe

スコア13336

test CHANGED
@@ -145,3 +145,30 @@
145
145
  }
146
146
  }
147
147
  ```
148
+
149
+ パネルをテストする際は、
150
+ ```java
151
+ class TestFrame extends JFrame {
152
+ static void invoke(JComponent component) {
153
+ SwingUtilities.invokeLater(() -> new TestFrame(component).setVisible(true));
154
+ }
155
+ private TestFrame(JComponent component) {
156
+ super(component.getClass().getSimpleName() + "テスト");
157
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
158
+ setSize(640, 400);
159
+ setLocationRelativeTo(null);
160
+ add(component);
161
+ }
162
+ }
163
+ ```
164
+ のようなテスト用のフレームクラスを作り、 ScanPanel なら main メソッドを付け加えて
165
+ ```java
166
+ class ScanPanel extends JPanel {
167
+ public static void main(String[] args) {
168
+ TestFrame.invoke(new ScanPanel(v -> System.out.println("onClick")));
169
+ }
170
+ //略
171
+ }
172
+ ```
173
+ クリックしたときには (FolderPanel では無く)コンソールに `onClick` を表示するようにします。
174
+ こうすると FolderPanel がまだ無くても ScanPanel を作っていくことが出来ます。

3

コード修正

2023/10/19 05:54

投稿

jimbe
jimbe

スコア13336

test CHANGED
@@ -88,6 +88,9 @@
88
88
  SwingUtilities.invokeLater(() -> new SingleFrame().setVisible(true));
89
89
  }
90
90
 
91
+ private static final String CARD_SCAN = "scan";
92
+ private static final String CARD_FOLDER = "folder"; //個別に書くと間違うかもしれないので定義しておくと確実です
93
+
91
94
  SingleFrame() {
92
95
  super("SingleFrame"); //タイトルは super で設定できます
93
96
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -98,14 +101,14 @@
98
101
  setLayout(cardLayout);
99
102
 
100
103
  ScanPanel scanPanel = new ScanPanel(
101
- v -> cardLayout.show(getContentPane(), "folder") //クリックされたら "folder" を表示
104
+ v -> cardLayout.show(getContentPane(), CARD_FOLDER) //クリックされたら "folder" を表示
102
105
  );
103
106
  scanPanel.addAncestorListener(createTitleSetter("スキャン")); //パネルが表示されたらタイトルを変える
104
- add(scanPanel, "scan");
107
+ add(scanPanel, CARD_SCAN);
105
108
 
106
109
  FolderPanel folderPanel = new FolderPanel();
107
110
  folderPanel.addAncestorListener(createTitleSetter("フォルダ"));
108
- add(folderPanel, "folder");
111
+ add(folderPanel, CARD_FOLDER);
109
112
  }
110
113
 
111
114
  private AncestorListener createTitleSetter(String title) {

2

コード修正

2023/10/19 05:29

投稿

jimbe
jimbe

スコア13336

test CHANGED
@@ -101,14 +101,11 @@
101
101
  v -> cardLayout.show(getContentPane(), "folder") //クリックされたら "folder" を表示
102
102
  );
103
103
  scanPanel.addAncestorListener(createTitleSetter("スキャン")); //パネルが表示されたらタイトルを変える
104
- add(scanPanel);
104
+ add(scanPanel, "scan");
105
105
 
106
106
  FolderPanel folderPanel = new FolderPanel();
107
107
  folderPanel.addAncestorListener(createTitleSetter("フォルダ"));
108
- add(folderPanel);
109
-
110
- cardLayout.addLayoutComponent(scanPanel, "scan");
111
- cardLayout.addLayoutComponent(folderPanel, "folder");
108
+ add(folderPanel, "folder");
112
109
  }
113
110
 
114
111
  private AncestorListener createTitleSetter(String title) {

1

追加

2023/10/19 05:19

投稿

jimbe
jimbe

スコア13336

test CHANGED
@@ -69,3 +69,79 @@
69
69
  後から Event1Frame 内でボタン押下時処理をダイアログからにしたりとかもできるはずです。
70
70
 
71
71
  ただ、 JFrame は基本的には一つのアプリケーション内で幾つも出したり消したりするような類ではありません。一つの JFrame を一つのアプリケーションの土台とし、表示内容が変わるならそれぞれを JPanel 等として JFrame 内への配置・表示を切り替える形にするのが良いと思います。
72
+
73
+ 以下のコードは JFrame 1つですが Event1Frame/Event2Frame の組と同じ動きです。
74
+ ScanPanel のコンストラクタに渡している Cunsumer オブジェクトによって、ボタン押下時の動作を外から指定できるようにしているのがミソでしょうか。クラス名は新しめですが使い方は addActionListener と同じ感じです。
75
+
76
+ SingleFrame.java
77
+ ```java
78
+ import java.awt.BorderLayout;
79
+ import java.awt.CardLayout;
80
+ import java.util.function.Consumer;
81
+
82
+ import javax.swing.*;
83
+ import javax.swing.event.AncestorEvent;
84
+ import javax.swing.event.AncestorListener;
85
+
86
+ public class SingleFrame extends JFrame {
87
+ public static void main(String[] args) {
88
+ SwingUtilities.invokeLater(() -> new SingleFrame().setVisible(true));
89
+ }
90
+
91
+ SingleFrame() {
92
+ super("SingleFrame"); //タイトルは super で設定できます
93
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
94
+ setSize(320, 200);
95
+ setLocationRelativeTo(null);
96
+
97
+ CardLayout cardLayout = new CardLayout(); //表示を切り替えられるレイアウトマネージャ
98
+ setLayout(cardLayout);
99
+
100
+ ScanPanel scanPanel = new ScanPanel(
101
+ v -> cardLayout.show(getContentPane(), "folder") //クリックされたら "folder" を表示
102
+ );
103
+ scanPanel.addAncestorListener(createTitleSetter("スキャン")); //パネルが表示されたらタイトルを変える
104
+ add(scanPanel);
105
+
106
+ FolderPanel folderPanel = new FolderPanel();
107
+ folderPanel.addAncestorListener(createTitleSetter("フォルダ"));
108
+ add(folderPanel);
109
+
110
+ cardLayout.addLayoutComponent(scanPanel, "scan");
111
+ cardLayout.addLayoutComponent(folderPanel, "folder");
112
+ }
113
+
114
+ private AncestorListener createTitleSetter(String title) {
115
+ return new AncestorListener() {
116
+ @Override
117
+ public void ancestorRemoved(AncestorEvent event) { /*ignore*/ }
118
+ @Override
119
+ public void ancestorMoved(AncestorEvent event) { /*ignore*/ }
120
+ @Override
121
+ public void ancestorAdded(AncestorEvent event) { setTitle(title); }
122
+ };
123
+ }
124
+ }
125
+
126
+ class ScanPanel extends JPanel {
127
+ ScanPanel(Consumer<ScanPanel> onClick) {
128
+ super(new BorderLayout()); //レイアウトは super で設定できます
129
+
130
+ JButton button = new JButton("ハローワールド");
131
+ button.addActionListener(v -> {
132
+ //dispose();
133
+ //SwingUtilities.invokeLater(() -> new Event2Frame().setVisible(true));
134
+ onClick.accept(this);
135
+ });
136
+ add(button);
137
+ }
138
+ }
139
+
140
+ class FolderPanel extends JPanel {
141
+ FolderPanel() {
142
+ super(new BorderLayout());
143
+
144
+ add(new JLabel("Hello World"));
145
+ }
146
+ }
147
+ ```