回答編集履歴

12

アイコン Disable 対応, Title icon設定 簡略化

2024/01/09 04:06

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -116,12 +116,10 @@
116
116
  private static Icon icon = new ExpandedStateIcon();
117
117
 
118
118
  Title(String text) {
119
- super(text);
119
+ super(text, icon);
120
120
  setOpaque(false);
121
121
  setForeground(Color.BLUE);
122
122
  setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 2));
123
- setIcon(icon);
124
- setSelectedIcon(icon);
125
123
  }
126
124
 
127
125
  @Override
@@ -154,7 +152,7 @@
154
152
  public void paintIcon(Component c, Graphics g, int x, int y) {
155
153
  Graphics2D g2 = (Graphics2D)g.create();
156
154
  g2.translate(x+dx, y+dy);
157
- g2.setColor(c.getForeground());
155
+ g2.setColor(c.isEnabled() ? c.getForeground() : Color.GRAY);
158
156
  g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
159
157
  if(c instanceof AbstractButton && ((AbstractButton)c).isSelected()) {
160
158
  g2.draw(selectedPolygon);

11

コードコメント追加

2024/01/08 17:49

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -13,6 +13,7 @@
13
13
  f.setVisible(true);
14
14
  }
15
15
  }
16
+ //CheckBox_Accordion の makePanel で作っていたヤツ
16
17
  class CheckBoxContents extends JPanel {
17
18
  CheckBoxContents(String... chkboxTitle) {
18
19
  super(null);
@@ -20,6 +21,7 @@
20
21
  Stream.of(chkboxTitle).map(JCheckBox::new).forEach(this::add);
21
22
  }
22
23
  }
24
+ //makePanel で作るのでは無くコンストラクタパラメータで貰う
23
25
  class Accordion extends JPanel {
24
26
  Accordion(String iTitle, JPanel panel){
25
27
  JLabel label = new JLabel(iTitle);

10

編集

2024/01/08 06:59

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -1,7 +1,38 @@
1
+ 質問のコードは makePanel でフィールドを初期化していますが、そこまで行っていればあと少しで「コンストラクタパラメータで渡してしまえば」と気付けたように思います。
2
+ 回答としては TN8001 さんと同じく「コンテンツの生成をリンク先のようにメソッドで持つ必要は無い」ということになります。
3
+ ```java
4
+ class Main {
5
+ public static void main(String[] args){
6
+ JFrame f = new JFrame();
7
+ JPanel p = new JPanel();
8
+ Accordion instance = new Accordion("mockTitle", new CheckBoxContents("chk1", "chk2", "chk3"));
9
+ f.add(p);
10
+ p.add(instance);
11
+ f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
12
+ f.setBounds(100, 100, 640, 400);
13
+ f.setVisible(true);
14
+ }
15
+ }
16
+ class CheckBoxContents extends JPanel {
17
+ CheckBoxContents(String... chkboxTitle) {
18
+ super(null);
19
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
20
+ Stream.of(chkboxTitle).map(JCheckBox::new).forEach(this::add);
21
+ }
22
+ }
23
+ class Accordion extends JPanel {
24
+ Accordion(String iTitle, JPanel panel){
25
+ JLabel label = new JLabel(iTitle);
26
+ label.addMouseListener(/* 省略 */);
27
+
28
+ add(label, BorderLayout.NORTH);
29
+ add(panel, BorderLayout.CENTER);
30
+ }
31
+ }
32
+ ```
33
+ ---
1
34
  リンク先の GitHub のコードを弄ってみました。
2
- 回答としては TN8001 さんと同じく「コンテンツの生成をリンク先のようにメソッドで持つ必要は無い」ということになります。
3
- 質問のコードは makePanel でフィールドを初期化していますが、そこまで行っていればあと少しで「コンストラクタパラメータで渡してしまえば」と気付けたように思います。
4
- コンテンツクラスを流用するようなこをしたということで、以下では CheckPanel を 2 回使ってした。配列にしてというのは意味が無さそうですのでやっていません。
35
+ コンテンツクラスを流用ということで CheckPanel を 2 回使ってすが、配列にしてというのは必要か分からなかったのでやっていません。
5
36
  また、ラベルとコンテンツパネルの組のクラスを土台のパネルに並べるよりも(ラベルとコンテンツの組は複数有るのが通常でしょうから)土台に直接ラベルとパネルを並べたほうが階層が減って良いと思います。
6
37
 
7
38
  ついでに、タイトルにはラベルで無くチェックボックスを使えば操作はマウス以外でも出来るようになります(チェック部分の画像は差し替えられます)し、 BoxLayout で無く GridBagLayout なら大きさの調整の為にメソッドをオーバーライドする必要もありません。

9

Title の Icon 関係を分離、コンテンツ表示時のスクロール処理を AncestorListener へ。

2024/01/08 06:36

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -9,6 +9,8 @@
9
9
  import java.awt.*;
10
10
 
11
11
  import javax.swing.*;
12
+ import javax.swing.event.AncestorEvent;
13
+ import javax.swing.event.AncestorListener;
12
14
 
13
15
  public class MainFrame extends JFrame {
14
16
  public static void main(String[] args) {
@@ -28,19 +30,32 @@
28
30
  }
29
31
 
30
32
  class ExpandableContentsPanel extends JPanel {
33
+ private static final AncestorListener visibleToScroll = new AncestorListener() {
34
+ @Override
35
+ public void ancestorRemoved(AncestorEvent event) { /*no process*/ }
36
+ @Override
37
+ public void ancestorMoved(AncestorEvent event) { /*no process*/ }
38
+ @Override
39
+ public void ancestorAdded(AncestorEvent event) { scrollRectToVisible(event.getComponent()); }
40
+ };
41
+
42
+ private static void scrollRectToVisible(JComponent c) {
43
+ ((JComponent)c.getParent()).scrollRectToVisible(c.getBounds());
44
+ }
45
+
31
46
  ExpandableContentsPanel() {
32
47
  super(new GridBagLayout());
33
- setBackground(new Color(0xB4_B4_FF));
48
+ setBackground(new Color(180, 180, 255));
34
49
  setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
35
50
 
36
51
  GridBagConstraints gbc = new GridBagConstraints();
37
52
  gbc.gridx = 0;
38
53
  gbc.fill = GridBagConstraints.HORIZONTAL;
39
54
  gbc.weightx = 1;
40
- add(new Title("System Tasks"), new CheckPanel("1111","222222"), gbc);
55
+ add("System Tasks", new CheckPanel("1111","222222"), gbc);
41
- add(new Title("User Tasks"), new CheckPanel("33333","444","55"), gbc);
56
+ add("User Tasks", new CheckPanel("33333","444","55"), gbc);
42
- add(new Title("Other Places"), new LabelPanel("Desktop","My Network Places","My Documents","Shared Documents"), gbc);
57
+ add("Other Places", new LabelPanel("Desktop","My Network Places","My Documents","Shared Documents"), gbc);
43
- add(new Title("Details"), new RadioPanel("aaa","bbb","ccc","ddd"), gbc);
58
+ add("Details", new RadioPanel("aaa","bbb","ccc","ddd"), gbc);
44
59
 
45
60
  gbc.weighty = 1;
46
61
  add(Box.createVerticalStrut(0), gbc);
@@ -48,19 +63,15 @@
48
63
  KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", e -> {
49
64
  if(!(e.getNewValue() instanceof JComponent)) return;
50
65
  JComponent focused = (JComponent)e.getNewValue();
51
- if(ExpandableContentsPanel.this.isAncestorOf(focused)) {
52
- ((JComponent)focused.getParent()).scrollRectToVisible(focused.getBounds());
66
+ if(this.isAncestorOf(focused)) scrollRectToVisible(focused);
53
- }
54
67
  });
55
68
  }
56
69
 
57
- private void add(AbstractButton title, JComponent contents, GridBagConstraints gbc) {
70
+ private void add(String titleText, JComponent contents, GridBagConstraints gbc) {
58
- title.addItemListener(e -> {
59
- boolean open = title.isSelected();
71
+ Title title = new Title(titleText);
60
- contents.setVisible(open);
61
- if(open) EventQueue.invokeLater(() -> contents.scrollRectToVisible(contents.getBounds())); //スクロール
72
+ title.addItemListener(e -> contents.setVisible(title.isSelected()));
62
- });
63
73
  contents.setVisible(title.isSelected());
74
+ contents.addAncestorListener(visibleToScroll);
64
75
 
65
76
  if(getComponentCount() > 0) add(Box.createVerticalStrut(5), gbc);
66
77
  add(title, gbc);
@@ -68,22 +79,16 @@
68
79
  }
69
80
  }
70
81
 
71
- class Title extends JCheckBox implements Icon {
82
+ class Title extends JCheckBox {
72
- private final Icon orgIcon = UIManager.getIcon("CheckBox.icon");
73
- private int pw = (int)(orgIcon.getIconWidth() * 0.8);
74
- private int ph = (int)(orgIcon.getIconHeight() * 0.6);
83
+ private static Icon icon = new ExpandedStateIcon();
75
- private int dx = (orgIcon.getIconWidth()-pw) / 2;
76
- private int dy = (orgIcon.getIconHeight()-ph) / 2;
77
- private Polygon selectedPolygon = new Polygon(new int[]{pw/2,0,pw}, new int[]{0,ph,ph}, 3); //上向き三角
78
- private Polygon polygon = new Polygon(new int[]{0,pw,pw/2}, new int[]{0,0,ph}, 3); //下向き三角
79
84
 
80
85
  Title(String text) {
81
86
  super(text);
82
87
  setOpaque(false);
83
88
  setForeground(Color.BLUE);
84
89
  setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 2));
85
- setIcon(this);
90
+ setIcon(icon);
86
- setSelectedIcon(this);
91
+ setSelectedIcon(icon);
87
92
  }
88
93
 
89
94
  @Override
@@ -93,6 +98,24 @@
93
98
  g2.fillRect(0, 0, getWidth(), getHeight());
94
99
  super.paintComponent(g);
95
100
  }
101
+ }
102
+
103
+ class ExpandedStateIcon implements Icon {
104
+ private final int iconWidth, iconHeight;
105
+ private final int dx, dy; //位置補正
106
+ private final Polygon selectedPolygon, polygon;
107
+
108
+ ExpandedStateIcon() {
109
+ Icon orgIcon = UIManager.getIcon("CheckBox.icon");
110
+ iconWidth = orgIcon.getIconWidth();
111
+ iconHeight = orgIcon.getIconHeight();
112
+ int pw = (int)(iconWidth * 0.8); //大きさはテキトウ
113
+ int ph = (int)(iconHeight * 0.6); // 〃
114
+ dx = (iconWidth-pw) / 2;
115
+ dy = (iconHeight-ph) / 2;
116
+ selectedPolygon = new Polygon(new int[]{pw/2,0,pw}, new int[]{0,ph,ph}, 3); //上向き三角
117
+ polygon = new Polygon(new int[]{0,pw,pw/2}, new int[]{0,0,ph}, 3); //下向き三角
118
+ }
96
119
 
97
120
  @Override
98
121
  public void paintIcon(Component c, Graphics g, int x, int y) {
@@ -100,7 +123,7 @@
100
123
  g2.translate(x+dx, y+dy);
101
124
  g2.setColor(c.getForeground());
102
125
  g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
103
- if(isSelected()) {
126
+ if(c instanceof AbstractButton && ((AbstractButton)c).isSelected()) {
104
127
  g2.draw(selectedPolygon);
105
128
  } else {
106
129
  g2.fill(polygon);
@@ -108,9 +131,9 @@
108
131
  g2.dispose();
109
132
  }
110
133
  @Override
111
- public int getIconWidth() { return orgIcon.getIconWidth(); }
134
+ public int getIconWidth() { return iconWidth; }
112
135
  @Override
113
- public int getIconHeight() { return orgIcon.getIconHeight(); }
136
+ public int getIconHeight() { return iconHeight; }
114
137
  }
115
138
 
116
139
  class Contents extends JPanel {

8

revalidate 削除

2024/01/07 13:29

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -58,7 +58,6 @@
58
58
  title.addItemListener(e -> {
59
59
  boolean open = title.isSelected();
60
60
  contents.setVisible(open);
61
- contents.revalidate();
62
61
  if(open) EventQueue.invokeLater(() -> contents.scrollRectToVisible(contents.getBounds())); //スクロール
63
62
  });
64
63
  contents.setVisible(title.isSelected());

7

キーボードによるフォーカス移動によってスクロールする処理を追加

2024/01/07 11:15

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -44,6 +44,14 @@
44
44
 
45
45
  gbc.weighty = 1;
46
46
  add(Box.createVerticalStrut(0), gbc);
47
+
48
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner", e -> {
49
+ if(!(e.getNewValue() instanceof JComponent)) return;
50
+ JComponent focused = (JComponent)e.getNewValue();
51
+ if(ExpandableContentsPanel.this.isAncestorOf(focused)) {
52
+ ((JComponent)focused.getParent()).scrollRectToVisible(focused.getBounds());
53
+ }
54
+ });
47
55
  }
48
56
 
49
57
  private void add(AbstractButton title, JComponent contents, GridBagConstraints gbc) {

6

Title のアイコンをアンチエイリアス等

2024/01/07 09:18

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -63,6 +63,12 @@
63
63
 
64
64
  class Title extends JCheckBox implements Icon {
65
65
  private final Icon orgIcon = UIManager.getIcon("CheckBox.icon");
66
+ private int pw = (int)(orgIcon.getIconWidth() * 0.8);
67
+ private int ph = (int)(orgIcon.getIconHeight() * 0.6);
68
+ private int dx = (orgIcon.getIconWidth()-pw) / 2;
69
+ private int dy = (orgIcon.getIconHeight()-ph) / 2;
70
+ private Polygon selectedPolygon = new Polygon(new int[]{pw/2,0,pw}, new int[]{0,ph,ph}, 3); //上向き三角
71
+ private Polygon polygon = new Polygon(new int[]{0,pw,pw/2}, new int[]{0,0,ph}, 3); //下向き三角
66
72
 
67
73
  Title(String text) {
68
74
  super(text);
@@ -84,22 +90,13 @@
84
90
  @Override
85
91
  public void paintIcon(Component c, Graphics g, int x, int y) {
86
92
  Graphics2D g2 = (Graphics2D)g.create();
87
- int w = (int)(getIconWidth() * 0.8);
93
+ g2.translate(x+dx, y+dy);
88
- int h = (int)(getIconHeight() * 0.6);
89
- g2.translate(x+(getIconWidth()-w)/2, y+(getIconHeight()-h)/2);
90
94
  g2.setColor(c.getForeground());
91
- Polygon triangle = new Polygon();
95
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
92
96
  if(isSelected()) {
93
- triangle.addPoint(w/2, 0);
94
- triangle.addPoint(0, h);
95
- triangle.addPoint(w, h);
96
- g2.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
97
- g2.draw(triangle);
97
+ g2.draw(selectedPolygon);
98
98
  } else {
99
- triangle.addPoint(0, 0);
100
- triangle.addPoint(w, 0);
101
- triangle.addPoint(w/2, h);
102
- g2.fill(triangle);
99
+ g2.fill(polygon);
103
100
  }
104
101
  g2.dispose();
105
102
  }
@@ -156,4 +153,4 @@
156
153
  }
157
154
  }
158
155
  ```
159
- ![スクリーンショット - Tasks をオープンしてチェック](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-07/bb93fd7a-c295-476c-9c9c-b7fff45ac3b6.png)
156
+ ![スクリーンショット - Tasks をオープンしてチェック](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-07/b65d3407-b61c-4122-b99d-2753a77cae0b.png)

5

コード簡略化

2024/01/07 04:33

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -31,17 +31,19 @@
31
31
  ExpandableContentsPanel() {
32
32
  super(new GridBagLayout());
33
33
  setBackground(new Color(0xB4_B4_FF));
34
- setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5));
34
+ setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
35
35
 
36
36
  GridBagConstraints gbc = new GridBagConstraints();
37
37
  gbc.gridx = 0;
38
38
  gbc.fill = GridBagConstraints.HORIZONTAL;
39
39
  gbc.weightx = 1;
40
-
41
40
  add(new Title("System Tasks"), new CheckPanel("1111","222222"), gbc);
42
41
  add(new Title("User Tasks"), new CheckPanel("33333","444","55"), gbc);
43
42
  add(new Title("Other Places"), new LabelPanel("Desktop","My Network Places","My Documents","Shared Documents"), gbc);
44
43
  add(new Title("Details"), new RadioPanel("aaa","bbb","ccc","ddd"), gbc);
44
+
45
+ gbc.weighty = 1;
46
+ add(Box.createVerticalStrut(0), gbc);
45
47
  }
46
48
 
47
49
  private void add(AbstractButton title, JComponent contents, GridBagConstraints gbc) {
@@ -53,15 +55,9 @@
53
55
  });
54
56
  contents.setVisible(title.isSelected());
55
57
 
56
- gbc.weighty = 0;
57
- if(getComponentCount() > 0) {
58
+ if(getComponentCount() > 0) add(Box.createVerticalStrut(5), gbc);
58
- GridBagLayout layout = (GridBagLayout)getLayout();
59
- layout.setConstraints(getComponent(getComponentCount()-1), gbc);
60
- }
61
59
  add(title, gbc);
62
60
  add(contents, gbc);
63
- gbc.weighty = 1;
64
- add(Box.createVerticalStrut(5), gbc);
65
61
  }
66
62
  }
67
63
 

4

Title クラスの Icon を変更

2024/01/06 20:49

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -65,12 +65,16 @@
65
65
  }
66
66
  }
67
67
 
68
- class Title extends JCheckBox {
68
+ class Title extends JCheckBox implements Icon {
69
+ private final Icon orgIcon = UIManager.getIcon("CheckBox.icon");
70
+
69
71
  Title(String text) {
70
72
  super(text);
71
73
  setOpaque(false);
72
74
  setForeground(Color.BLUE);
73
75
  setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 2));
76
+ setIcon(this);
77
+ setSelectedIcon(this);
74
78
  }
75
79
 
76
80
  @Override
@@ -80,6 +84,33 @@
80
84
  g2.fillRect(0, 0, getWidth(), getHeight());
81
85
  super.paintComponent(g);
82
86
  }
87
+
88
+ @Override
89
+ public void paintIcon(Component c, Graphics g, int x, int y) {
90
+ Graphics2D g2 = (Graphics2D)g.create();
91
+ int w = (int)(getIconWidth() * 0.8);
92
+ int h = (int)(getIconHeight() * 0.6);
93
+ g2.translate(x+(getIconWidth()-w)/2, y+(getIconHeight()-h)/2);
94
+ g2.setColor(c.getForeground());
95
+ Polygon triangle = new Polygon();
96
+ if(isSelected()) {
97
+ triangle.addPoint(w/2, 0);
98
+ triangle.addPoint(0, h);
99
+ triangle.addPoint(w, h);
100
+ g2.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
101
+ g2.draw(triangle);
102
+ } else {
103
+ triangle.addPoint(0, 0);
104
+ triangle.addPoint(w, 0);
105
+ triangle.addPoint(w/2, h);
106
+ g2.fill(triangle);
107
+ }
108
+ g2.dispose();
109
+ }
110
+ @Override
111
+ public int getIconWidth() { return orgIcon.getIconWidth(); }
112
+ @Override
113
+ public int getIconHeight() { return orgIcon.getIconHeight(); }
83
114
  }
84
115
 
85
116
  class Contents extends JPanel {
@@ -129,4 +160,4 @@
129
160
  }
130
161
  }
131
162
  ```
132
- ![スクリーンショット - Tasks をオープン](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-06/304f9ad2-b53f-48ae-bafe-101b66bf1937.png)
163
+ ![スクリーンショット - Tasks をオープンしてチェック](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-07/bb93fd7a-c295-476c-9c9c-b7fff45ac3b6.png)

3

コード修正

2024/01/06 20:02

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -46,12 +46,12 @@
46
46
 
47
47
  private void add(AbstractButton title, JComponent contents, GridBagConstraints gbc) {
48
48
  title.addItemListener(e -> {
49
- boolean open = title.getSelectedObjects() != null;
49
+ boolean open = title.isSelected();
50
50
  contents.setVisible(open);
51
51
  contents.revalidate();
52
52
  if(open) EventQueue.invokeLater(() -> contents.scrollRectToVisible(contents.getBounds())); //スクロール
53
53
  });
54
- contents.setVisible(title.getSelectedObjects() != null);
54
+ contents.setVisible(title.isSelected());
55
55
 
56
56
  gbc.weighty = 0;
57
57
  if(getComponentCount() > 0) {

2

脱字

2024/01/06 19:50

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -1,7 +1,7 @@
1
1
  リンク先の GitHub のコードを弄ってみました。
2
2
  回答としては TN8001 さんと同じく「コンテンツの生成をリンク先のようにメソッドで持つ必要は無い」ということになります。
3
3
  質問のコードは makePanel でフィールドを初期化していますが、そこまで行っていればあと少しで「コンストラクタパラメータで渡してしまえば」と気付けたように思います。
4
- コンテンツクラスを用するようなことをしたいということで、以下では CheckPanel を 2 回使ってみました。配列にしてというのは意味が無さそうですのでやっていません。
4
+ コンテンツクラスを用するようなことをしたいということで、以下では CheckPanel を 2 回使ってみました。配列にしてというのは意味が無さそうですのでやっていません。
5
5
  また、ラベルとコンテンツパネルの組のクラスを土台のパネルに並べるよりも(ラベルとコンテンツの組は複数有るのが通常でしょうから)土台に直接ラベルとパネルを並べたほうが階層が減って良いと思います。
6
6
 
7
7
  ついでに、タイトルにはラベルで無くチェックボックスを使えば操作はマウス以外でも出来るようになります(チェック部分の画像は差し替えられます)し、 BoxLayout で無く GridBagLayout なら大きさの調整の為にメソッドをオーバーライドする必要もありません。

1

追記、画像追加

2024/01/06 10:14

投稿

jimbe
jimbe

スコア13168

test CHANGED
@@ -2,6 +2,7 @@
2
2
  回答としては TN8001 さんと同じく「コンテンツの生成をリンク先のようにメソッドで持つ必要は無い」ということになります。
3
3
  質問のコードは makePanel でフィールドを初期化していますが、そこまで行っていればあと少しで「コンストラクタパラメータで渡してしまえば」と気付けたように思います。
4
4
  コンテンツクラスを用するようなことをしたいということで、以下では CheckPanel を 2 回使ってみました。配列にしてというのは意味が無さそうですのでやっていません。
5
+ また、ラベルとコンテンツパネルの組のクラスを土台のパネルに並べるよりも(ラベルとコンテンツの組は複数有るのが通常でしょうから)土台に直接ラベルとパネルを並べたほうが階層が減って良いと思います。
5
6
 
6
7
  ついでに、タイトルにはラベルで無くチェックボックスを使えば操作はマウス以外でも出来るようになります(チェック部分の画像は差し替えられます)し、 BoxLayout で無く GridBagLayout なら大きさの調整の為にメソッドをオーバーライドする必要もありません。
7
8
  ```java
@@ -128,3 +129,4 @@
128
129
  }
129
130
  }
130
131
  ```
132
+ ![スクリーンショット - Tasks をオープン](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-06/304f9ad2-b53f-48ae-bafe-101b66bf1937.png)