今回は、Java Swingの様々なレイアウトの設定方法について解説していきたいと思います。
Javaは様々なアプリやシステムを作っている有名なプログラミング言語です。
GUIの基礎として今回は、レイアウトを作成する方法をマスターしていきましょう。
目次
目次
- レイアウトの概念
- BorderLayout
- BoxLayout
- CardLayout
- FlowLayout
- GridLayout
- GroupLayout
1. レイアウトの概念
そもそも、Panelの講座では、FrameにPanelをadd(追加)して、コンポーネントの配置を行うという一見すると手間ではないか?という作業をしていました。
Panelの講座を忘れちゃった方は、また復習してみてくださいね。
→Panel講座の記事はこちらから
では、実際になぜPanelを使用したのか?まずは、Panelを配置するコードを見てみて、その後Panelを使用しない場合のコードを確認して比較してみましょう。
public class test{ JFrame frame = new JFrame(); public test() { frame = new JFrame("test_sample"); JPanel panel = new JPanel(); frame.add(panel); JLabel label = new JLabel("Hello World!"); panel.add(label); JButton button = new JButton("ボタン"); panel.add(button); frame.setSize(600,600); frame.setVisible(true); frame.setLocationRelativeTo(null); } public static void main(String[] args) { // TODO Auto-generated method stub test gui = new test(); } }

Panelを配置した場合、上のような結果が出力されましたね。これはPanelの講座の復習です。
続いて、Panelを使わない場合のコードを見てみましょう。
public class test{ JFrame frame = new JFrame(); public test() { frame = new JFrame("test_sample"); JLabel label = new JLabel("Hello World!"); frame.add(label); JButton button = new JButton("ボタン"); frame.add(button); frame.setSize(400,400); frame.setVisible(true); frame.setLocationRelativeTo(null); } public static void main(String[] args) { // TODO Auto-generated method stub test gui = new test(); } }

なんと、JLabelとJButtonをadd(追加)したにもかかわらず、ウィンドウ全体にボタンが広がってしまいました。
これは、JFrameとJPanelとでは初期設定のレイアウトが異なることが原因です。
レイアウトは、コンポーネントをどんな風に配置していくのかのルールです。
Swingには様々なレイアウトを設定できるので、これから一つずつ見ていきましょう。
2. BorderLayout
BorderLayoutは、東西南北と中央にコンポ―ネントを配置することが出来ます。
public class test{ JFrame frame = new JFrame(); public test() { frame = new JFrame("test_sample"); JPanel panel = new JPanel(); BorderLayout layout = new BorderLayout(); panel.setLayout(layout); frame.add(panel); JButton button1 = new JButton("Button 1(PAGE_START)"); panel.add(button1, BorderLayout.PAGE_START); JButton button2 = new JButton("Button 2(LINE_START)"); panel.add(button2, BorderLayout.LINE_START); JButton button3 = new JButton("Button 3(CENTER)"); panel.add(button3, BorderLayout.CENTER); JButton button4 = new JButton("Button 4(LINE_END)"); panel.add(button4, BorderLayout.LINE_END); JButton button5 = new JButton("Button 5(PAGE_END)"); panel.add(button5, BorderLayout.PAGE_END); frame.setSize(600,400); frame.setVisible(true); frame.setLocationRelativeTo(null); } public static void main(String[] args) { // TODO Auto-generated method stub test gui = new test(); } }

実行して見ると上のような結果が得られると思います。
このような配置に出来るのがBorederLayoutです。
3. BoxLayout
BoxLayoutは、行列にコンポーネントを順に配置することが出来ます。
public class test{ JFrame frame = new JFrame(); public test() { frame = new JFrame("test_sample"); JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); frame.add(panel); JButton b1 = new JButton("LEFT_ALIGNMENT 1"); JButton b2 = new JButton("LEFT_ALIGNMENT 2"); JButton b3 = new JButton("LEFT_ALIGNMENT 3"); JButton b4 = new JButton("LEFT_ALIGNMENT 4"); JButton b5 = new JButton("LEFT_ALIGNMENT 5"); b1.setAlignmentX(Component.LEFT_ALIGNMENT); b2.setAlignmentX(Component.LEFT_ALIGNMENT); b3.setAlignmentX(Component.LEFT_ALIGNMENT); b4.setAlignmentX(Component.LEFT_ALIGNMENT); b5.setAlignmentX(Component.LEFT_ALIGNMENT); panel.add(b1); panel.add(b2); panel.add(b3); panel.add(b4); panel.add(b5); frame.setSize(400,180); frame.setVisible(true); frame.setLocationRelativeTo(null); } public static void main(String[] args) { // TODO Auto-generated method stub test gui = new test(); } }

上図のように、行列に、配置していくことが出来るのが、BoxLayoutです。
4. CardLayout
コンポーネントを配置したCardを切り替えることのできるレイアウトです。
切り替えには、ボタンやコンボボックスが用いられます。
public class test extends JFrame implements ActionListener{ JPanel cardPanel; CardLayout layout; public static void main(String[] args){ test frame = new test(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10, 400, 300); frame.setLocationRelativeTo(null); frame.setTitle("タイトル"); frame.setVisible(true); } test(){ /* カード1 */ JPanel card1 = new JPanel(); card1.add(new JButton("Button")); /* カード2 */ JPanel card2 = new JPanel(); card2.add(new JLabel("Label")); card2.add(new JTextField("TextField", 10)); /* カード3 */ JPanel card3 = new JPanel(); card3.add(new JCheckBox("checkbox1")); card3.add(new JCheckBox("checkbox2")); cardPanel = new JPanel(); layout = new CardLayout(); cardPanel.setLayout(layout); cardPanel.add(card1, "button"); cardPanel.add(card2, "label"); cardPanel.add(card3, "checkbox"); /* カード移動用ボタン */ JButton button1 = new JButton("button表示"); button1.addActionListener((ActionListener) this); button1.setActionCommand("button"); JButton button2 = new JButton("label&TextField表示"); button2.addActionListener(this); button2.setActionCommand("label"); JButton button3 = new JButton("checkbox表示"); button3.addActionListener(this); button3.setActionCommand("checkbox"); JPanel btnPanel = new JPanel(); btnPanel.add(button1); btnPanel.add(button2); btnPanel.add(button3); getContentPane().add(cardPanel, BorderLayout.CENTER); getContentPane().add(btnPanel, BorderLayout.PAGE_END); } public void actionPerformed(ActionEvent e){ String cmd = e.getActionCommand(); layout.show(cardPanel, cmd); } }

実行して見ると上のような結果が得られると思います。
このように入れ替えて表示出来るのがCardLayoutです。
5. FlowLayout
JPanelのデフォルトのレイアウトで、コンポーネントを単一の行に配置します。
ウィンドウの幅が十分でない場合には、折り返して表示します。
public class test{ JFrame frame = new JFrame(); public test() { frame = new JFrame("test_sample"); JPanel panel = new JPanel(); panel.setLayout(new FlowLayout(FlowLayout.CENTER)); frame.add(panel); JButton b1 = new JButton("Button1"); JButton b2 = new JButton("Button2"); JButton b3 = new JButton("Button3"); JButton b4 = new JButton("Button4"); JButton b5 = new JButton("Button5"); panel.add(b1); panel.add(b2); panel.add(b3); panel.add(b4); panel.add(b5); frame.setSize(400,180); frame.setVisible(true); frame.setLocationRelativeTo(null); } public static void main(String[] args) { // TODO Auto-generated method stub test gui = new test(); } }

上の様にウィンドウサイズを可変することによって、配置が変化していることが分かると思います。
6. GridLayout
等しいサイズのコンポーネントを作成し、指定された行数と列数で表示します。
public class test extends JFrame{ public static void main(String[] args){ test frame = new test(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10, 400, 300); frame.setLocationRelativeTo(null); frame.setTitle("タイトル"); frame.setVisible(true); } test(){ JButton button1 = new JButton("Button1"); JButton button2 = new JButton("Button2"); JButton button3 = new JButton("Button3"); JButton button4 = new JButton("Button4"); JButton button5 = new JButton("Button5"); JPanel p = new JPanel(); p.setLayout(new GridLayout(3, 2)); p.add(button1); p.add(button2); p.add(button3); p.add(button4); p.add(button5); getContentPane().add(p, BorderLayout.CENTER); } }

上図の様に今回は(3,2)に指定しているので指定した行列にButtonが配置されていることが分かると思います。
7. GroupLayout
水平方向のレイアウトと垂直方向のレイアウトを別々に用意して、使用します。
元々GUIビルダーを使用するために開発されたので手動ではかなり実装が大変です。
public class test extends JFrame{ public static void main(String[] args){ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new test(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(600, 300); frame.setVisible(true); } }); } test(){ // 各コンポーネントは垂直グループ、水平グループの両方に属していなければならない JLabel lblName = new JLabel(); lblName.setText("label1"); JTextField txtName = new JTextField(); JButton button1 = new JButton(); button1.setText("button1"); JLabel lblAddress = new JLabel(); lblAddress.setText("label2"); JTextField txtAddress = new JTextField(); JButton button2 = new JButton(); button2.setText("button2"); // GroupLayout の生成 GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); layout.setHorizontalGroup( layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addComponent(lblName) .addComponent(lblAddress)) .addGroup(layout.createParallelGroup() .addComponent(txtName) .addComponent(txtAddress)) .addGroup(layout.createParallelGroup() .addComponent(button1) .addComponent(button2))); layout.setVerticalGroup( layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(lblName) .addComponent(txtName) .addComponent(button1)) .addGroup(layout.createParallelGroup(Alignment.BASELINE) .addComponent(lblAddress) .addComponent(txtAddress) .addComponent(button2))); } }

以上のような配置をそれぞれ水平方向、垂直方向に同じもの同士グループとして配置していきます。
以上レイアウトについてまとめてみました。
今回紹介したもの以外にもあるとは思いますので、気になったときは調べてみてくださいね!
基本的には、今回紹介したものを駆使することで思い描くデザインが可能であると思いますので、やってみてくださいね!