質問: new JButton(); > > button1.setBorder(new > > EtchedBorder(EtchedBorder.RAISED)); > > button1.setPreferredSize(new Dimension(80, 20)); > > button1.setText("リセット"); > > > p1.add(text1) > > p2.add(button1) > > > contentPane.add(p1, BorderLayout.WEST); > > contentPane.add(p2, BorderLayout.EAST); > > > と言う感じに分けてるんですが、 ![現実イメージ](https://teratail.storage.googleapis.com/uploads/contributed_images/ff3b4f9d961744e1fb5d0dbb424ba33f.png) このようになってしまいます。 これはおそらく > > contentPane.add(p1, BorderLayout.WEST); > > contentPane.add(p2, BorderLayout.EAST); > > > ここが問題だと言うことはわかったんですがこれを使わずに分ける方法がわかりません。 GridLayoutでなくても構わないので実現できる方法を教えてください。 ### 補足情報(言語/FW/ツール等のバージョンなど)
回答: 追記:もう一つ言い忘れました。コードは`>`で表現するのではなくマークダウン(コード行の前後にバッククォート文字を3つ連続して書く)を使って本回答にあるようにしていただきたいです。質問編集画面でコードの行を選択し``ボタンを押すとそうできます。 レイアウトって難しいですよね・・・ 何が最適かはある程度試してみて特徴をつかむ必要があると思いますが・・・ 真ん中が空いてしまう原因: BorderLayoutでの主役はCENTERにいるコンポーネントで、その周りは全てCENTERの邪魔にならないように控えめにレイアウトされると考えておくとよいと思います。(大雑把な表現でスミマセン) 対処案: 自分の場合、縦方向や横方向に連続して並ぶものはとりあえずBoxを最初に試すことにしています。本件の場合なら ``` Box(horizontal) +-- JTextArea +-- Box(vertical) +-- JButton +-- JTextField +-- JTextField +-- JLabel ... etc. +-- glue(※1) ※1: 隙間を埋めるための軽量部品。Box.createVerticalGlue()で生成する ``` 左右のバランスはTextAreaのpreferredSizeの横幅と右側にある一番大きな部品のpreferredSizeの横幅によって決まります。 なお、JFrameのcontentPaneにはデフォルトでBorderLayoutを持つJPanelになっていることはご存知と思いますが、例えば上記のようにしたいとき、デフォルトのJPanelをそのまま使わなくてはならないルールはないので、入れかえてしまってもよいですし、デフォルトのJPanelのCENTERへaddしてやってもよいでしょう。 ``` public MyFrame extends JFrame { public static void main(String[] args) { SwingUtilities.invokeLater(() -> new MyFrame().setVisible(true)); } class MyFrame() { ... Box hBox = Box.createHorizontalBox(); ... setContentPane(hBox); // (1) getContentPane().add(hBox, BorderLayout.CENTER); // (2) setDefaultCloseOperation(EXIT_ON_FRAME); pack(); } } ``` (1) or (2)いずれかを選択 なおGridLayoutも使えなくはないと思います。ただ、GridLayoutはROWS x COLUMNSの同じ大きさの区画に格子状に部品を並べるためのもので将棋盤のようなものなら一番適していますが、本件のようなものには今一つマッチしないと思います。というのは「全体を左右に分けて」=>「さらに右側を上下に分けて」=>「さらに・・・」というように階層的な構成を格子として考えるとrow span/column spanを使わざるを得ず、あまり自然な配置設計でない気がするのです。