SwingのJPanelとJTabbed

2021-07-31

こんにちは。

今回はSwingのJPanelとJTabbedを使ってみました。

以下のソースを雛形として使います。

ソース
import javax.swing.JFrame;

public class Test extends JFrame {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(350, 250);

        init();

        setVisible(true);

    }

    private void init() {
        // 設置処理
    }

}

JPanel

JPanelは汎用的なコンテナです。

FlowLayoutで3つ設置

JFrameのレイアウトマネージャーにFlowLayoutを指定し、JPanelを3つ配置して見ました。デフォルトコンストラクタを使いインスタンスを生成して、JFrameに追加しています。ただし、そのままだと透明で設置されているのかわからないため、境界線を引いています。境界線はsetBorder()メソッドを使って指定することができます。

ソース
import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class Test2 extends JFrame {

    public static void main(String[] args) {
        new Test2();
    }

    public Test2() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(350, 250);

        init();

        setVisible(true);

    }

    private void init() {
        setLayout(new FlowLayout());

        JPanel panel_01 = new JPanel();
        panel_01.setBorder(new LineBorder(Color.RED));
        add(panel_01);

        JPanel panel_02 = new JPanel();
        panel_02.setBorder(new LineBorder(Color.BLUE));
        add(panel_02);

        JPanel panel_03 = new JPanel();
        panel_03.setBorder(new LineBorder(Color.GREEN));
        add(panel_03);
    }

}
JPanel01FlowLayout01

FlowLayoutを指定しているので左から順番に設置されました。各JPanelには中身を設定していないので、何も表示されません。

JPanelにJButtonを追加

JPanelはContainerクラスの子クラスです。Containerクラスにはadd()メソッドが定義されているため、JPanelがこのメソッドを呼び出すことができます。引数にはComponentオブジェクトを指定します。

以下ではJButtonをいくつか追加してみました。

ソース
import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class Test3 extends JFrame {

    public static void main(String[] args) {
        new Test3();
    }

    public Test3() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(350, 250);

        init();

        setVisible(true);

    }

    private void init() {
        setLayout(new FlowLayout());

        JPanel panel_01 = new JPanel();
        panel_01.setBorder(new LineBorder(Color.RED));
        panel_01.add(new JButton("Button 1-1"));
        panel_01.add(new JButton("Button 1-2"));
        add(panel_01);

        JPanel panel_02 = new JPanel();
        panel_02.setBorder(new LineBorder(Color.BLUE));
        panel_02.add(new JButton("Button 2-1"));
        panel_02.add(new JButton("Button 2-2"));
        panel_02.add(new JButton("Button 2-3"));
        add(panel_02);

        JPanel panel_03 = new JPanel();
        panel_03.setBorder(new LineBorder(Color.GREEN));
        panel_03.add(new JButton("Button 3-1"));
        add(panel_03);
    }

}
JPanel01FlowLayout02

JPanelのレイアウトマネージャーは、初期値がFlowLayoutです。panel1.getLayout()をコンソールに出力してみた結果、以下のように表示されました。

ソース
System.out.println(panel_01.getLayout());
結果
java.awt.FlowLayout[hgap=5,vgap=5,align=center]

alignの値がcenterであるため、コンポーネントは中央寄せで配置されますJFrameのレイアウトマネージャーを初期値のままにして、JPanelを設置すると中央寄せの様子が分かります。

ソース
    private void init() {
        JPanel panel1 = new JPanel();
        panel1.setBorder(new LineBorder(Color.RED));
        panel1.add(new JButton("Button 1-1"));
        panel1.add(new JButton("Button 1-2"));
        panel1.add(new JButton("Button 1-3"));
        panel1.add(new JButton("Button 1-4"));
        panel1.add(new JButton("Button 1-5"));
        add(panel1);
    }
JPanel01FlowLayout03

JFrameのレイアウトマネージャーの初期値はBorderLayoutです。JPanelをaddメソッドでJFrameに追加しています。この場合、JPanelは中央に配置されます。配置したJPanelの高さと幅はJFrameと同じになるようです。そのため、JButtonが次の行に折り返されて配置されます。

この配置方法を変えるには、例えば、以下のように新しいFlowLayoutを設定します。

ソース
import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class Test5 extends JFrame {

    public static void main(String[] args) {
        new Test5();
    }

    public Test5() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(350, 250);

        init();

        setVisible(true);

    }

    private void init() {
        JPanel panel1 = new JPanel();
        panel1.setBorder(new LineBorder(Color.RED));
        panel1.setLayout(new FlowLayout(FlowLayout.LEFT));
        panel1.add(new JButton("Button 1-1"));
        panel1.add(new JButton("Button 1-2"));
        panel1.add(new JButton("Button 1-3"));
        panel1.add(new JButton("Button 1-4"));
        panel1.add(new JButton("Button 1-5"));
        add(panel1);
    }

}
JPanel01FlowLayout04

FlowLayout.LEFTを設定したことで、JButtonが左寄せで配置されます。2行目のJButtonが左寄せで配置されているのが確認できます。

JTabbedPane

JTabbedPaneクラスはコンポーネントを切り替えるタブを持つコンポーネントです。addメソッドはいくつかありますが、次のメソッドが使いやすいと思います。

  • Component add(String title, Component component)

上記の第1引数はタブに表示する文字列で、第2引数はComponentオブジェクトを指定しますが、JPanelを指定するのが基本的だと思います。

タブを追加

以下ではJLabelとJPanelをタブの内容にしてみた例です。

ソース
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class Test6 extends JFrame {

    public static void main(String[] args) {
        new Test6();
    }

    public Test6() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(350, 250);

        init();

        setVisible(true);

    }

    private void init() {
    	JPanel panel_01 = new JPanel();
    	panel_01.add(new JLabel("My JLabel 01"));

    	JPanel panel_02 = new JPanel();
    	panel_02.add(new JButton("My JButton 01"));

    	JTabbedPane tabbedPane = new JTabbedPane();
    	tabbedPane.add("My Tab 01", panel_01);
    	tabbedPane.add("My Tab 02", panel_02);

    	add(tabbedPane);
    }

}
JTabbedPane01Tab01
JTabbedPane01Tab02

2つ目のタブではタブの内容にJPanelを設定しています。そのJPanelにJButtonが追加されているのが分かります。

setTabLayoutPolicy

タブが画面内に収まらない場合の処理をsetTabLayoutPolicy()メソッドで設定することができます。

引数には以下の2つを指定することができます。

  • JTabbedPane.WRAP_TAB_LAYOUT
  • JTabbedPane.SCROLL_TAB_LAYOUT

JTabbedPaneにはprivateフィールドtabLayoutPolicyが定義されていて、その値を変更するメソッドがsetTabLayoutPolicy()メソッドです。API仕様書によると、tabLayoutPolicyの初期値はJTabbedPane.WRAP_TAB_LAYOUTです。

以下、タブを10個追加してみました。tabLayoutPolicyは変更していません。

ソース
private void init() {
    JTabbedPane tabbedPane = new JTabbedPane();
    for (int i = 0; i < 10; i++) {
        String s = "tab " + i;
        tabbedPane.add(s, new JLabel("the content of " + s));
    }
    add(tabbedPane);
}
JTabbedPane01TabLayoutPolicy01

JFrameの幅に収まらないところで折り返して表示されました。

次に上記のソースにSCROLL_TAB_LAYOUTの設定を1行追加して実行してみました。

ソース
    private void init() {
        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

        for (int i = 0; i < 10; i++) {
            String s = "tab " + i;
            tabbedPane.add(s, new JLabel("the content of " + s));
        }

        add(tabbedPane);
    }
JTabbedPane01TabLayoutPolicy02-01
JTabbedPane01TabLayoutPolicy02-02

左右矢印のアイコンが表示され、スクロールできるように表示されました。

以上、参考になれば幸いです。

同じカテゴリーの前後の記事