回答編集履歴

8

import 部分のコピー忘れ

2024/02/11 10:36

投稿

jimbe
jimbe

スコア12721

test CHANGED
@@ -186,20 +186,19 @@
186
186
  番外編(?):『白地に黒で 上から 100 px・左右中心の位置に "test" と書くパネル』を作って配置です。
187
187
  BOLD フォントから文字列の描画幅を得て座標を計算して…とやってますが、素直にレイアウトマネージャと JLabel を使ったほうが良いですね^^
188
188
  ```java
189
- import java.awt.Color;
189
+ import java.awt.*;
190
- import java.awt.Graphics;
190
+ import java.awt.geom.Rectangle2D;
191
-
191
+
192
- import javax.swing.JFrame;
192
+ import javax.swing.*;
193
- import javax.swing.JPanel;
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(JFrame.EXIT_ON_CLOSE);
201
+ setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
203
202
  setSize(600, 400);
204
203
 
205
204
  setContentPane(new TestPanel());

7

修正

2024/02/11 10:21

投稿

jimbe
jimbe

スコア12721

test CHANGED
@@ -183,9 +183,8 @@
183
183
  }
184
184
  }
185
185
  ```
186
- 番外編(?):『白地に黒で 200,100 の位置に "test" と書くパネル』を作って配置
186
+ 番外編(?):『白地に黒で 上から 100 px・左右中心の位置に "test" と書くパネル』を作って配置です。
187
- 位置固定なのでフレームのサイズを変えても全く動きません。(もちろんパネル自体の位置が動いたらダメですが。)
188
- サイズの変化に合わせて移動させるなそれなりコード書く必要がありますのでそこまでするなら素直にレイアウトマネージャと JLabel を使ったほうが良いですね^^
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("test", 200, 100); //座標は文字列の左下の位置
230
+ g.drawString(text, tx, ty); //座標は文字列のベースラインの
218
231
  }
219
232
  }
220
233
  }

6

追加

2024/02/11 09:15

投稿

jimbe
jimbe

スコア12721

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

追加

2024/02/10 19:16

投稿

jimbe
jimbe

スコア12721

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

説明修正

2024/02/10 12:43

投稿

jimbe
jimbe

スコア12721

test CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  Swing のコンポーネントは基本となる JFrame (他にもありますが) に載せ(add)なければ表示されません。
4
4
 
5
- また、なにやら setSize やら serBounds やら呼び出していますが、それらは JFrame に対するものであって Label には関係ありません。
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 だけに JLabel を配置した場合、JLabel は ContentPane いっぱいの大きさに拡大されます。 JLabel の文字列は JLabel 自身が設定に従って描画するもので、質問のコードではそれは何も指定していませんのでデフォルト通り上下位置は中央、左右位置は左詰めで表示されます。
10
+ 中央である BorderLayout.CENTER は東西南北のコンポーネントを配置して余った空間を全て使う領域で、これだけに配置した場合は ContentPane いっぱいの大きさに拡大されます。 JLabel の文字列は JLabel 自身が設定に従って描画するもので、質問のコードではそれは何も指定していませんのでデフォルト通り上下位置は中央、左右位置は左詰めで表示されます。
11
11
 
12
12
  >フレームの上中央に配置させたいです。
13
13
  >ただし、上に100ピクセルくらい隙間を空けたいです。

3

リンク追加

2024/02/10 12:31

投稿

jimbe
jimbe

スコア12721

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

修正

2024/02/10 12:12

投稿

jimbe
jimbe

スコア12721

test CHANGED
@@ -20,8 +20,7 @@
20
20
  ```java
21
21
  import java.awt.*;
22
22
 
23
- import javax.swing.JFrame;
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
- ![実行時イメ](https://ddjkaamml8q8x.cloudfront.net/questions/2024-02-10/f89a8838-f104-4a42-a171-939115863a97.png)
54
+ ![実行時スクリンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-02-10/cc35ea65-aabd-4866-90f4-f7038e73580b.png)

1

コード追加

2024/02/10 12:05

投稿

jimbe
jimbe

スコア12721

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)