複数のパネルを持つアプリケーションがあります。パネルごとに異なるレイアウトマネージャーを自由に使用できるようにしたいのですが、ユーザーがウィンドウのサイズを変更しても同じように動作するようにしたいと思います。
package example;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
public class TP1 extends JFrame
{
public static void main(String[] args)
{
TP1 tp1 = new TP1();
tp1.go();
}
public void go()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
// create a panel with some labels on it
JPanel innerFirst = new JPanel();
innerFirst.setLayout(new BoxLayout(innerFirst, BoxLayout.PAGE_AXIS));
innerFirst.add(new JLabel("one"));
innerFirst.add(new JLabel("two"));
innerFirst.add(new JLabel("three"));
innerFirst.add(new JLabel("four"));
// put that panel in a scroll pane
JScrollPane firstSP = new JScrollPane(innerFirst);
// make another panel and put our scrolled panel in it
JPanel outerFirst = new JPanel();
outerFirst.setLayout(new BoxLayout(outerFirst, BoxLayout.PAGE_AXIS));
outerFirst.add(firstSP);
// create a GridBagLayout panel with some text fields on it
JPanel innerSecond = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = .25;
gbc.anchor = GridBagConstraints.LINE_START;
innerSecond.add(new JTextField(8), gbc);
gbc.gridx = 0;
gbc.gridy = 1;
innerSecond.add(new JTextField(10), gbc);
gbc.gridx =0;
gbc.gridy = 2;
innerSecond.add(new JTextField(12), gbc);
// put that panel in a scroll pane
JScrollPane secondSP = new JScrollPane(innerSecond);
// make another panel and put our second scrolled panel in it
JPanel outerSecond = new JPanel();
outerSecond.setLayout(new BoxLayout(outerSecond, BoxLayout.LINE_AXIS));
outerSecond.add(secondSP);
JPanel innerThird = new JPanel(new GridBagLayout());
GridBagConstraints gbc3 = new GridBagConstraints();
gbc3.anchor = GridBagConstraints.LINE_END;
gbc.weightx = .25;
gbc3.gridx = 0;
gbc3.gridy = 0;
innerThird.add(new JLabel("1st label"), gbc3);
gbc3.gridy = 1;
innerThird.add(new JLabel("second label"), gbc3);
gbc3.gridy = 2;
innerThird.add(new JLabel("IIIrd label"), gbc3);
gbc3.anchor = GridBagConstraints.LINE_START;
gbc3.gridx = 1;
gbc3.gridy = 0;
innerThird.add(new JTextField(8), gbc3);
gbc3.gridy = 1;
innerThird.add(new JTextField(12), gbc3);
gbc3.gridy = 2;
innerThird.add(new JTextField(14), gbc3);
JScrollPane thirdSP = new JScrollPane(innerThird);
JPanel outerThird = new JPanel();
outerThird.setLayout(new BoxLayout(outerThird, BoxLayout.LINE_AXIS));
outerThird.add(thirdSP);
// put the scrolled panes onto a tabbed pane
JTabbedPane tp = new JTabbedPane();
tp.add("text fields", outerSecond);
tp.add("labels", outerFirst);
tp.add("mixed", outerThird);
// add the tabbed pane to the frame
this.add(tp);
// pack it and ship it.
pack();
setVisible(true);
}
}
上記のコードを実行すると、3つのタブがあるタブ付きペインのあるウィンドウが表示されます。ウィンドウを小さくすると、意図したとおり、すべてのウィンドウにスクロールバーが表示されます。大きくすると、3つの動作が異なります。ラベルのあるタブではウィンドウの左上にのみ表示され、フィールドのあるタブでは左端の垂直方向にのみ中央揃えになり、ラベルとフィールドが混在するグリッドバッグのあるタブでは動作が異なります。拡大されたウィンドウで、それらを水平方向と垂直方向の両方の中央に配置します。
これはアプリケーションには受け入れられません。どういうわけか、すべてのパネルをこのように同じように動作させる必要があります。それらすべてにスクロールバーが必要です。ウィンドウが内部パネルよりも大きくなった場合は、それらすべてを左上に保持してほしいと思います。
もう1つの要件:私のタブはJPanelを拡張するもので占められています。JScrollPaneをタブに直接配置する前に言われましたが、私のアプリケーションではそれもしたくありません。それは、他のものを必要以上に複雑にするだけです。
余分なスペースをすべて右下に配置することに加えて、これら3つの状況が異なる動作をする理由を理解したいと思います。例を左右にコピーして、うまくいくまで試行錯誤するのではなく、自分たちがやっていることの背後にある原則を理解すれば、私たち全員がもっとうまくいくと今でも信じています。
(ちなみに、左上に引き寄せられているように見えるGroupLayoutパネルがありますが、私の質問には必要ないと思いました。これは100行のコードです。)