回答編集履歴
5
誤字修正等
test
CHANGED
@@ -71,7 +71,8 @@
|
|
71
71
|
ただ、 JFrame は基本的には一つのアプリケーション内で幾つも出したり消したりするような類ではありません。一つの JFrame を一つのアプリケーションの土台とし、表示内容が変わるならそれぞれを JPanel 等として JFrame 内への配置・表示を切り替える形にするのが良いと思います。
|
72
72
|
|
73
73
|
以下のコードは JFrame 1つですが Event1Frame/Event2Frame の組と同じ動きです。
|
74
|
+
CardLayout は、複数のパネルの中から一つを選んで表示することが出来ます。
|
74
|
-
ScanPanel のコンストラクタに渡している C
|
75
|
+
ScanPanel のコンストラクタに渡している Consumer オブジェクトによって、ボタン押下時の動作を外から指定できるようにしているのがミソでしょうか。クラス名は新しめですが使い方は addActionListener と同じ感じです。
|
75
76
|
|
76
77
|
SingleFrame.java
|
77
78
|
```java
|
4
追加
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
コード修正
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(),
|
104
|
+
v -> cardLayout.show(getContentPane(), CARD_FOLDER) //クリックされたら "folder" を表示
|
102
105
|
);
|
103
106
|
scanPanel.addAncestorListener(createTitleSetter("スキャン")); //パネルが表示されたらタイトルを変える
|
104
|
-
add(scanPanel,
|
107
|
+
add(scanPanel, CARD_SCAN);
|
105
108
|
|
106
109
|
FolderPanel folderPanel = new FolderPanel();
|
107
110
|
folderPanel.addAncestorListener(createTitleSetter("フォルダ"));
|
108
|
-
add(folderPanel,
|
111
|
+
add(folderPanel, CARD_FOLDER);
|
109
112
|
}
|
110
113
|
|
111
114
|
private AncestorListener createTitleSetter(String title) {
|
2
コード修正
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
|
-
|
108
|
+
add(folderPanel, "folder");
|
112
109
|
}
|
113
110
|
|
114
111
|
private AncestorListener createTitleSetter(String title) {
|
1
追加
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
|
+
```
|