回答編集履歴
8
import 部分のコピー忘れ
test
CHANGED
@@ -186,20 +186,19 @@
|
|
186
186
|
番外編(?):『白地に黒で 上から 100 px・左右中心の位置に "test" と書くパネル』を作って配置です。
|
187
187
|
BOLD フォントから文字列の描画幅を得て座標を計算して…とやってますが、素直にレイアウトマネージャと JLabel を使ったほうが良いですね^^
|
188
188
|
```java
|
189
|
-
import java.awt.
|
189
|
+
import java.awt.*;
|
190
|
-
import java.awt.
|
190
|
+
import java.awt.geom.Rectangle2D;
|
191
|
-
|
191
|
+
|
192
|
-
import javax.swing.
|
192
|
+
import javax.swing.*;
|
193
|
-
|
193
|
+
|
194
|
-
|
195
|
-
public class TestFrame extends JFrame {
|
194
|
+
public class TestFrame extends JFrame {
|
196
|
-
public static void main(String[] args) {
|
195
|
+
public static void main(String[] args) {
|
197
|
-
new TestFrame().setVisible(true);
|
196
|
+
new TestFrame().setVisible(true);
|
198
|
-
}
|
197
|
+
}
|
199
|
-
|
198
|
+
|
200
|
-
TestFrame() {
|
199
|
+
TestFrame() {
|
201
|
-
super("テスト");
|
200
|
+
super("テスト");
|
202
|
-
setDefaultCloseOperation(
|
201
|
+
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
203
202
|
setSize(600, 400);
|
204
203
|
|
205
204
|
setContentPane(new TestPanel());
|
7
修正
test
CHANGED
@@ -183,9 +183,8 @@
|
|
183
183
|
}
|
184
184
|
}
|
185
185
|
```
|
186
|
-
番外編(?):『白地に黒で
|
186
|
+
番外編(?):『白地に黒で 上から 100 px・左右中心の位置に "test" と書くパネル』を作って配置です。
|
187
|
-
位置固定なのでフレームのサイズを変えても全く動きません。(もちろんパネル自体の位置が動いたらダメですが。)
|
188
|
-
|
187
|
+
BOLD フォントから文字列の描画幅を得て座標を計算して…とやってますが、素直にレイアウトマネージャと JLabel を使ったほうが良いですね^^
|
189
188
|
```java
|
190
189
|
import java.awt.Color;
|
191
190
|
import java.awt.Graphics;
|
@@ -213,8 +212,22 @@
|
|
213
212
|
@Override
|
214
213
|
protected void paintComponent(Graphics g) {
|
215
214
|
super.paintComponent(g);
|
215
|
+
|
216
|
+
String text = "test";
|
217
|
+
|
218
|
+
Font font = getFont().deriveFont(Font.BOLD);
|
219
|
+
FontMetrics metrics = g.getFontMetrics(font);
|
220
|
+
Rectangle2D rect = metrics.getStringBounds(text, g);
|
221
|
+
int tx = (getWidth()-(int)rect.getWidth()) / 2;
|
222
|
+
int ty = 100 + metrics.getMaxAscent();
|
223
|
+
int rw = (int)rect.getWidth();
|
224
|
+
int rh = metrics.getMaxAscent() + metrics.getMaxDescent();
|
225
|
+
|
226
|
+
g.setColor(Color.CYAN);
|
227
|
+
g.fillRect(tx, 100, rw, rh); //座標は矩形の左上
|
228
|
+
g.setFont(font);
|
216
229
|
g.setColor(Color.BLACK);
|
217
|
-
g.drawString(
|
230
|
+
g.drawString(text, tx, ty); //座標は文字列のベースラインの左端
|
218
231
|
}
|
219
232
|
}
|
220
233
|
}
|
6
追加
test
CHANGED
@@ -147,6 +147,39 @@
|
|
147
147
|
label.setBackground(Color.CYAN);
|
148
148
|
label.setBorder(BorderFactory.createEmptyBorder(100,0,0,0));
|
149
149
|
contentPane.add(label);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
```
|
153
|
+
使ったことは無いですが SpringLayout というのもあります。
|
154
|
+
ラベルの上辺と contentPane の上辺との間を 100 px とし、ラベルの左右中心と contentPAne の左右中心を合わせています。
|
155
|
+
```java
|
156
|
+
import java.awt.Color;
|
157
|
+
import java.awt.Container;
|
158
|
+
|
159
|
+
import javax.swing.*;
|
160
|
+
|
161
|
+
public class TestFrame extends JFrame {
|
162
|
+
public static void main(String[] args) {
|
163
|
+
new TestFrame().setVisible(true);
|
164
|
+
}
|
165
|
+
|
166
|
+
TestFrame() {
|
167
|
+
super("テスト");
|
168
|
+
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
169
|
+
setSize(600, 400);
|
170
|
+
|
171
|
+
Container contentPane = getContentPane();
|
172
|
+
contentPane.setBackground(Color.WHITE);
|
173
|
+
SpringLayout layout = new SpringLayout();
|
174
|
+
contentPane.setLayout(layout);
|
175
|
+
|
176
|
+
JLabel label = new JLabel("test");
|
177
|
+
label.setOpaque(true);
|
178
|
+
label.setBackground(Color.CYAN);
|
179
|
+
contentPane.add(label);
|
180
|
+
|
181
|
+
layout.putConstraint(SpringLayout.NORTH, label, 100, SpringLayout.NORTH, contentPane);
|
182
|
+
layout.putConstraint(SpringLayout.HORIZONTAL_CENTER, label, 0, SpringLayout.HORIZONTAL_CENTER, contentPane);
|
150
183
|
}
|
151
184
|
}
|
152
185
|
```
|
5
追加
test
CHANGED
@@ -55,3 +55,134 @@
|
|
55
55
|
}
|
56
56
|
```
|
57
57
|
![実行時スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-02-10/cc35ea65-aabd-4866-90f4-f7038e73580b.png)
|
58
|
+
|
59
|
+
---
|
60
|
+
TN8001 さんの回答を見て、幾つかパターンを ^^;
|
61
|
+
|
62
|
+
BoxLayout だとこんな感じ。
|
63
|
+
縦方向の設定にして、100 px の空白、ラベル、残りを埋める糊、を並べます。
|
64
|
+
```java
|
65
|
+
import java.awt.*;
|
66
|
+
|
67
|
+
import javax.swing.*;
|
68
|
+
|
69
|
+
public class TestFrame extends JFrame {
|
70
|
+
public static void main(String[] args) {
|
71
|
+
new TestFrame().setVisible(true);
|
72
|
+
}
|
73
|
+
|
74
|
+
TestFrame() {
|
75
|
+
super("テスト");
|
76
|
+
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
77
|
+
setSize(600, 400);
|
78
|
+
|
79
|
+
Container contentPane = getContentPane();
|
80
|
+
contentPane.setBackground(Color.WHITE);
|
81
|
+
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); //レイアウトマネージャを変更
|
82
|
+
|
83
|
+
contentPane.add(Box.createVerticalStrut(100)); //高さ 100 px の棒(?)
|
84
|
+
|
85
|
+
JLabel label = new JLabel("test");
|
86
|
+
label.setOpaque(true);
|
87
|
+
label.setBackground(Color.CYAN);
|
88
|
+
label.setAlignmentX(Component.CENTER_ALIGNMENT);
|
89
|
+
contentPane.add(label);
|
90
|
+
|
91
|
+
contentPane.add(Box.createVerticalGlue());
|
92
|
+
}
|
93
|
+
}
|
94
|
+
```
|
95
|
+
BorderLayout でも北南は横にしか広がらないので、ラベルを北(or南)に配置して直接 Border で上に 100 px の間を開けることでもできます。
|
96
|
+
ただこの場合は上 2 点と違って JLabel が北(or南)の部分全体に広がるので、文字列の配置を setHorizontalAlignment で設定する必要があります。
|
97
|
+
```java
|
98
|
+
import java.awt.*;
|
99
|
+
|
100
|
+
import javax.swing.*;
|
101
|
+
|
102
|
+
public class TestFrame extends JFrame {
|
103
|
+
public static void main(String[] args) {
|
104
|
+
new TestFrame().setVisible(true);
|
105
|
+
}
|
106
|
+
|
107
|
+
TestFrame() {
|
108
|
+
super("テスト");
|
109
|
+
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
110
|
+
setSize(600, 400);
|
111
|
+
|
112
|
+
Container contentPane = getContentPane();
|
113
|
+
contentPane.setBackground(Color.WHITE);
|
114
|
+
|
115
|
+
JLabel label = new JLabel("test");
|
116
|
+
label.setOpaque(true);
|
117
|
+
label.setBackground(Color.CYAN);
|
118
|
+
label.setHorizontalAlignment(JLabel.CENTER);
|
119
|
+
label.setBorder(BorderFactory.createEmptyBorder(100,0,0,0));
|
120
|
+
contentPane.add(label, BorderLayout.NORTH);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
```
|
124
|
+
上のようにラベルの border で空きを調整するなら FlowLayout のほうが簡単かもしれません。
|
125
|
+
FlowLayout はコンポーネントの推奨サイズで中央に並べますので、縦長の JLabel になります。
|
126
|
+
```java
|
127
|
+
import java.awt.*;
|
128
|
+
|
129
|
+
import javax.swing.*;
|
130
|
+
|
131
|
+
public class TestFrame extends JFrame {
|
132
|
+
public static void main(String[] args) {
|
133
|
+
new TestFrame().setVisible(true);
|
134
|
+
}
|
135
|
+
|
136
|
+
TestFrame() {
|
137
|
+
super("テスト");
|
138
|
+
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
139
|
+
setSize(600, 400);
|
140
|
+
|
141
|
+
Container contentPane = getContentPane();
|
142
|
+
contentPane.setBackground(Color.WHITE);
|
143
|
+
contentPane.setLayout(new FlowLayout());
|
144
|
+
|
145
|
+
JLabel label = new JLabel("test");
|
146
|
+
label.setOpaque(true);
|
147
|
+
label.setBackground(Color.CYAN);
|
148
|
+
label.setBorder(BorderFactory.createEmptyBorder(100,0,0,0));
|
149
|
+
contentPane.add(label);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
```
|
153
|
+
番外編(?):『白地に黒で 200,100 の位置に "test" と書くパネル』を作って配置
|
154
|
+
位置固定なのでフレームのサイズを変えても全く動きません。(もちろんパネル自体の位置が動いたらダメですが。)
|
155
|
+
サイズの変化に合わせて移動させるならそれなりのコードを書く必要がありますので、そこまでするなら素直にレイアウトマネージャと JLabel を使ったほうが良いですね^^
|
156
|
+
```java
|
157
|
+
import java.awt.Color;
|
158
|
+
import java.awt.Graphics;
|
159
|
+
|
160
|
+
import javax.swing.JFrame;
|
161
|
+
import javax.swing.JPanel;
|
162
|
+
|
163
|
+
public class TestFrame extends JFrame {
|
164
|
+
public static void main(String[] args) {
|
165
|
+
new TestFrame().setVisible(true);
|
166
|
+
}
|
167
|
+
|
168
|
+
TestFrame() {
|
169
|
+
super("テスト");
|
170
|
+
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
171
|
+
setSize(600, 400);
|
172
|
+
|
173
|
+
setContentPane(new TestPanel());
|
174
|
+
}
|
175
|
+
|
176
|
+
private class TestPanel extends JPanel {
|
177
|
+
TestPanel() {
|
178
|
+
setBackground(Color.WHITE);
|
179
|
+
}
|
180
|
+
@Override
|
181
|
+
protected void paintComponent(Graphics g) {
|
182
|
+
super.paintComponent(g);
|
183
|
+
g.setColor(Color.BLACK);
|
184
|
+
g.drawString("test", 200, 100); //座標は文字列の左下の位置
|
185
|
+
}
|
186
|
+
}
|
187
|
+
}
|
188
|
+
```
|
4
説明修正
test
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
Swing のコンポーネントは基本となる JFrame (他にもありますが) に載せ(add)なければ表示されません。
|
4
4
|
|
5
|
-
また、なにやら setSize やら se
|
5
|
+
また、なにやら frame.setSize やら frame.setBounds やら呼び出していますが、それらは JFrame に対するものであって Label には関係ありません。
|
6
6
|
|
7
7
|
Swing のコンポーネントの配置は基本的に LayoutManager が自動で行います。
|
8
8
|
質問のコードで frame.add している先は JFrame の ContentPane であり、それには BorderLayout が設定されています。
|
9
|
-
BorderLayout は東西南北中央の 5 か所
|
9
|
+
BorderLayout は東西南北中央の 5 か所のコンポーネントの大きさ等から全体を **適切に** 配置・設定するものです。
|
10
|
-
中央である BorderLayout.CENTER だけに
|
10
|
+
中央である BorderLayout.CENTER は東西南北のコンポーネントを配置して余った空間を全て使う領域で、これだけに配置した場合は ContentPane いっぱいの大きさに拡大されます。 JLabel の文字列は JLabel 自身が設定に従って描画するもので、質問のコードではそれは何も指定していませんのでデフォルト通り上下位置は中央、左右位置は左詰めで表示されます。
|
11
11
|
|
12
12
|
>フレームの上中央に配置させたいです。
|
13
13
|
>ただし、上に100ピクセルくらい隙間を空けたいです。
|
3
リンク追加
test
CHANGED
@@ -17,6 +17,9 @@
|
|
17
17
|
---
|
18
18
|
以下は GridBagLayout で配置したものです。他に frame クラスを JFrame の TestFrame クラスとしています。
|
19
19
|
フレームの大きさを変えてもラベルが上から 100 px の左右中央にあり続けます。
|
20
|
+
|
21
|
+
[Google検索「java swing gridbaglayout」](https://www.google.com/search?q=java+swing+gridbaglayout)
|
22
|
+
|
20
23
|
```java
|
21
24
|
import java.awt.*;
|
22
25
|
|
2
修正
test
CHANGED
@@ -20,8 +20,7 @@
|
|
20
20
|
```java
|
21
21
|
import java.awt.*;
|
22
22
|
|
23
|
-
import javax.swing.
|
23
|
+
import javax.swing.*;
|
24
|
-
import javax.swing.JLabel;
|
25
24
|
|
26
25
|
public class TestFrame extends JFrame { //java はクラス名は大文字始まりが基本、また、 main メソッドのためだけのクラスでは無く JFrame として活用
|
27
26
|
public static void main(String[] args) {
|
@@ -42,9 +41,14 @@
|
|
42
41
|
JLabel label = new JLabel("test");
|
43
42
|
label.setOpaque(true); //JLabel の背景は基本透明なので不透明にし
|
44
43
|
label.setBackground(Color.CYAN); //位置・大きさを確認し易いよう色を付けてみる
|
44
|
+
gbc.gridx = 0;
|
45
45
|
gbc.insets = new Insets(100, 0, 0, 0); //上に 100 px の空き
|
46
46
|
contentPane.add(label, gbc);
|
47
|
+
|
48
|
+
gbc.insets = new Insets(0, 0, 0, 0); //クリア
|
49
|
+
gbc.weighty = 1; //余計な空白はここが吸収
|
50
|
+
contentPane.add(Box.createVerticalGlue(), gbc);
|
47
51
|
}
|
48
52
|
}
|
49
53
|
```
|
50
|
-
![実行時
|
54
|
+
![実行時スクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-02-10/cc35ea65-aabd-4866-90f4-f7038e73580b.png)
|
1
コード追加
test
CHANGED
@@ -13,3 +13,38 @@
|
|
13
13
|
>ただし、上に100ピクセルくらい隙間を空けたいです。
|
14
14
|
|
15
15
|
その位置に表示してもしウインドウの大きさを変えたらどう変化する **べき** なのか、他のコンポーネントを追加した時にそれらとお互いにどのように配置されることになるのかによって、フレーム内のコンテナの設定やコンポーネントの置き方が大きく変わります。
|
16
|
+
|
17
|
+
---
|
18
|
+
以下は GridBagLayout で配置したものです。他に frame クラスを JFrame の TestFrame クラスとしています。
|
19
|
+
フレームの大きさを変えてもラベルが上から 100 px の左右中央にあり続けます。
|
20
|
+
```java
|
21
|
+
import java.awt.*;
|
22
|
+
|
23
|
+
import javax.swing.JFrame;
|
24
|
+
import javax.swing.JLabel;
|
25
|
+
|
26
|
+
public class TestFrame extends JFrame { //java はクラス名は大文字始まりが基本、また、 main メソッドのためだけのクラスでは無く JFrame として活用
|
27
|
+
public static void main(String[] args) {
|
28
|
+
new TestFrame().setVisible(true); //表示したら速やかに main メソッドを終えるよう、setVisible をここに書いておく
|
29
|
+
}
|
30
|
+
|
31
|
+
TestFrame() {
|
32
|
+
super("テスト");
|
33
|
+
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
34
|
+
setSize(600, 400); //これはフレームの大きさ
|
35
|
+
|
36
|
+
Container contentPane = getContentPane();
|
37
|
+
contentPane.setBackground(Color.WHITE); //ContentPane の背景色
|
38
|
+
contentPane.setLayout(new GridBagLayout()); //レイアウトマネージャを変更
|
39
|
+
|
40
|
+
GridBagConstraints gbc = new GridBagConstraints();
|
41
|
+
|
42
|
+
JLabel label = new JLabel("test");
|
43
|
+
label.setOpaque(true); //JLabel の背景は基本透明なので不透明にし
|
44
|
+
label.setBackground(Color.CYAN); //位置・大きさを確認し易いよう色を付けてみる
|
45
|
+
gbc.insets = new Insets(100, 0, 0, 0); //上に 100 px の空き
|
46
|
+
contentPane.add(label, gbc);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
```
|
50
|
+
![実行時イメージ](https://ddjkaamml8q8x.cloudfront.net/questions/2024-02-10/f89a8838-f104-4a42-a171-939115863a97.png)
|