WisdomSoft - for your serial experiences.

9.7 タブペイン

複数の画面をタブで切り替えるタブペインを作成します。Swing では、タブに表示する内容や、タブの表示位置などを細かく設定できます。

9.7.1 複数のパネルへのアクセス

アプリケーションが、データを表示するためのコンテナなどを多く表示しなければならない場合、タブペインを使うことで、個々のパネルにスマートにアクセスすることができるようになります。タブペインは javax.swing.JTabbedPane クラスで実装され、指定されたタイトルやアイコンを持つタブをクリックすることにより、ユーザがコンポーネントのグループを切り替えられるようにするコンポーネントです。

javax.swing.JTabbedPane クラス
java.lang.Object
  |
  +--java.awt.Component
        |
        +--java.awt.Container
              |
              +--javax.swing.JComponent
                    |
                    +--javax.swing.JTabbedPane
public class JTabbedPane extends JComponent implements Serializable, Accessible, SwingConstants

タブペインにコンポーネントを追加すると、そのコンポーネントに対応するタブが表示されます。そして、対応するタブを選択することで、表示するコンポーネントを切り替えることができます。

表1 JTabbedPane クラスのコンストラクタとメソッド(抜粋)
コンストラクタ 解説
public JTabbedPane() デフォルトのタブ配置で JTabbedPane を作成する。
public JTabbedPane(int tabPlacement) 指定したタブ配置で JTabbedPane を作成する。
public JTabbedPane(int tabPlacement, int tabLayoutPolicy) 指定したタブ配置とレイアウトポリシーで JTabbedPane を作成する。
メソッド
public Component add(Component component) タブタイトルをコンポーネントの名前に設定して component を追加する。
public Component add(String title, Component component) タブタイトルを指定して component を追加する。
public Component add(Component component, int index) タブタイトルをコンポーネントの名前に設定して、指定したタブインデックスに component を追加する。
public void add(Component component, Object constraints) タブタイトルを constraints に設定して、component を追加する。
public void add(Component component, Object constraints, int index) タブタイトルを constraints に設定して、指定したタブのインデックスに component を追加する。
public void addTab(String title, Component component) title で表される (アイコンなし) component を追加する。
public void addTab(String title, Icon icon, Component component) title または icon、あるいはその両方によって表された component を追加する。
public void addTab(String title, Icon icon, Component component, String tip) title または icon、あるいはその両方によって表された component および tip を追加する。
public void removeTabAt(int index) index のタブを削除する。
public void remove(Component component) 指定された Component を JTabbedPane から削除する。
public void remove(int index) 指定されたインデックスに対応するタブとコンポーネントを削除する。
public void removeAll() tabbedpane からすべてのタブおよび対応するコンポーネントを削除する。
public int getTabCount() この tabbedpane のタブの数を返す。
public void setTitleAt(int index, String title) index のタイトルを title に設定する。
public String getTitleAt(int index) index のタブのタイトルを返す。
public void setIconAt(int index, Icon icon) index のアイコンを icon に設定する。
public Icon getIconAt(int index) index のタブのアイコンを返す。
public void setSelectedIndex(int index) タブ区画の選択されたインデックスを設定する。
public int getSelectedIndex() タブ区画で現在選択されているインデックスを返す。
public void setSelectedComponent(Component c) タブ区画の選択コンポーネントを設定する。
public Component getSelectedComponent() タブ区画で現在選択されているコンポーネントを返す。
public void setTabPlacement(int tabPlacement) タブ区画のタブの配置を設定します。
public int getTabPlacement() タブ区画のタブの配置を返します。
public void setTabLayoutPolicy(int tabLayoutPolicy) レイアウトポリシーを設定する。
public int getTabLayoutPolicy() レイアウトポリシーを返す。

表1は JTabbedPane クラスのコンストラクタとタブに関する主なメソッドです。このコンテナにコンポーネントを追加するということは、新しいタブを生成するということを意味します。カードレイアウトを発展させたコンテナと考えてよいでしょう。

タブの追加方法は add() メソッドで追加する方法と addTab() メソッドで追加する方法があります。デフォルトでは、追加されるコンポーネントの getName() メソッドが返す名前がタブ名となりますが、オーバーロードされているメソッドで、タブ名を指示することができます。また、タブにはアイコンを表示することができるため add() メソッドの constraints に Icon オブジェクトを渡すと、そのアイコンが利用されます。

コンストラクタでは、タブの配置方法とレイアウトポリシーを設定することができます。タブ配置とは、タブをコンテナのどこに配置するか設定します。このプロパティに設定できる値は SwingConstants インタフェースの TOP、LEFT、RIGHT、BOTTOM のいずれかです。レイアウトポリシーは、タブの数が多くなり、タブが 1 行で表示しきれなくなったときのレイアウト方法を設定します。デフォルトでは改行を行うことを表す JTabbedPane クラスのフィールド定数 WRAP_TAB_LAYOUT が設定されてますが、スクロールを表す SCROLL_TAB_LAYOUT を設定することもできます。

コード1
import javax.swing.*;

public class Test extends JFrame {
	public static void main(String args[]) {
		String msg = "タブを選択すると\n対応するコンポーネントが表示されます";

		JTabbedPane pane = new JTabbedPane();
		pane.add("Tab 1" , new JLabel("Kitty on your lap"));
		pane.addTab("Tab 2" , new JLabel(new ImageIcon("icon1.jpg")));
		pane.addTab("にこにこ♪" ,
			new ImageIcon("icon2.jpg") , 
			new JOptionPane(msg , JOptionPane.INFORMATION_MESSAGE)
		);

		JFrame win = new Test();
		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		win.setBounds(10 , 10 , 400 , 300);
		win.getContentPane().add(pane);
		win.show();
	}
}
実行結果
コード1 実行結果

コード1では、タブペインにラベルやオプションペインなどのコンポーネントを追加しています。実行結果を見て分かるように、タブを追加するときに指定したタブ名やアイコンは、コンポーネントを選択するためのタブに表示されます。タブを選択すると、それに対応するコンポーネントがパネルに表示されます。

デフォルトでは、実行結果のようにタブがコンテナの上部に表示され、その下にコンポーネントを表示するパネルが配置されます。しかし、Swing のタブは非常に柔軟で、タブは位置を指定することでコンテナの左右や下部にタブを表示することができます。

コード2
import javax.swing.*;

public class Test extends JFrame {
	public static void main(String args[]) {
		JTabbedPane pane = new JTabbedPane(JTabbedPane.RIGHT);
		for(int i = 0 ; i < 5 ; i++) pane.add("Tab " + i , new JPanel());

		JFrame win = new Test();
		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		win.setBounds(10 , 10 , 400 , 300);
		win.getContentPane().add(pane);
		win.show();
	}
}
実行結果
コード2 実行結果

コード2は、JTabbedPane() コンストラクタで、タブの配置を初期化しています。結果から確認できるように、SwingConstants インタフェースの RIGHT フィールドを指定しているため、タブはコンテナの右側に表示されます。

このプログラムのウィンドウサイズを小さく変更し、タブを 1 行で表示できる十分なサイズが得られなくなると、タブは自動的に改行してすべてのタブを表示しようとレイアウトを調整します。しかし、あまりにもタブの数が多くなりすぎると、タブの改行はコンテナ全体のレイアウトを歪めてしまうかもしれません。そこで、タブが表示しきれない場合はスクロールを表示するように設定します。

コード3
import javax.swing.*;

public class Test extends JFrame {
	public static void main(String args[]) {
		JTabbedPane pane = new JTabbedPane();
		pane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		for(int i = 0 ; i < 20 ; i++) pane.add("Tab " + i , new JPanel());

		JFrame win = new Test();
		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		win.setBounds(10 , 10 , 400 , 300);
		win.getContentPane().add(pane);
		win.show();
	}
}
実行結果
コード3 実行結果

コード3は、setTabLayoutPlicy() メソッドからタブのレイアウトポリシーを SCROLL_TAB_LAYOUT に変更しています。そのため、このタブペインは、タブが 1 行で表示しきれなくなるとスクロールボタンを表示してスクロール可能にします。ユーザーの動作によってタブの数が動的に変化するようなアプリケーションでは、こちらの方が安全なレイアウトでしょう。