WisdomSoft - for your serial experiences.

6.8 スクロールバー

単純にコンポーネントとしてスクロールバーを表示します。スクロールバーは JScrollBar クラスで表されます。

6.8.1 コンテンツ領域とバー

コンポーネントが表示している何らかの内容のサイズが、そのコンポーネントのサイズを超えている場合に考えられる処理は 2 つです。1 つはその内容をコンポーネントのサイズに伸縮して表示することです。画像ファイルなどであればこの方法が用いられるでしょう。そしてもう 1 つは、スクロールバーをコンポーネントの端に表示して、コンポーネントをスクロール可能にすることです。

スクロールバーコンポーネントは機能的にスライダーと同じです。最大値、最小値、現在の値、内側の幅を表す 4 つの値がデータモデルとして採用されています。スクロールバーを移動させることで、現在の値が変更されることもスライダーと同じです。しかし、スクロールバーの役割はユーザーに値を入力してもらうことではなく、事実上はコンポーネントのコンテンツを移動させるために利用されます。

Swing のスクロールバーは javax.swing.JScrollBar クラスで実装されています。

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

このクラスのコンストラクタと主なメソッドは表1に表します。

表1 JScrollBar クラスのコンストラクタとメソッド(抜粋)
コンストラクタ 解説
public JScrollBar() デフォルトの垂直スクロールバーを作成する。
public JScrollBar(int orientation) 方向を指定してスクロールバーを作成する。
public JScrollBar(int orientation, int value, int extent, int min, int max) 方向、値、長さ、最小値、最大値を指定してスクロールバーを作成する。
メソッド
public void addAdjustmentListener(AdjustmentListener l) AdjustmentListener を追加する。
public void removeAdjustmentListener(AdjustmentListener l) AdjustmentEvent リスナーを削除する。
public AdjustmentListener[] getAdjustmentListeners() 設定されているすべての AdjustmentListener の配列を返す。
public void setMaximum(int maximum) 最大値を設定する。
public int getMaximum() 最大値を返す。
public void setMinimum(int minimum) 最小値を設定する。
public int getMinimum() 最小値を返す。
public void setValue(int value スクロールバーの値を設定する。
public int getValue() スクロールバーの値を返す。
public void setVisibleAmount(int extent) スクロールバーの長さを設定する。
public int getVisibleAmount() スクロールバーの長さを返す。
public void setModel(BoundedRangeModel newModel) 最小値、最大値、値、長さを処理するデータモデルを設定する。
public BoundedRangeModel getModel() 最小値、最大値、値、長さを処理するデータモデルを返す。
public void setOrientation(int orientation) スクロールバーの方向を水平または垂直に設定する。
public int getOrientation() コンポーネントの方向 (水平または垂直) を返す。

JScrollBar のデフォルトの値は最大値が 100、最小値が 0、現在の値が 0、内側の幅が 10 に設定されています。スクロールバーは、方向によって垂直スクロールバーと水平スクロールバーに分かれます。この設定はコンストラクタの orientation パラメータか、setOrientation() メソッドで設定することができます。方向を表すのは java.awt.Adjustable インタフェースです。このインタフェースが公開している定数フィールドが方向を表し、Adjustable.HORIZONTAL 水平方向を、Adjustable.VERTICAL 垂直方向を表しています。

setVisibleAmount() メソッドは Adjustable インタフェースで宣言されている関係でこのような命名になっていますが、このプロパティは内側の幅を表す Extent プロパティを設定するものです。Adjustable インタフェースは AWT のスクロールバーも実装しているため、Swing の JScrollBar は AWT のスクロールバーと互換性があると考えられます。この部分はスライダーと大きく異なるポイントです。

JScrollBar クラスのコンストラクタはデータモデルとなるオブジェクトを受けませんが、setModel() メソッドから BoundedRangeModel インタフェースのオブジェクトを設定することができます。

スクロールバーのつまみを移動させると java.awt.event.AdjustmentListener インタフェースのオブジェクトが呼び出されます。このインタフェースは何らかの調整用の値が変更されたときに呼び出される adjustmentValueChanged() メソッドが宣言されてます。

AdjustmentListener インタフェース adjustmentValueChanged() メソッド
public void adjustmentValueChanged(AdjustmentEvent e)

このメソッドが受ける java.awt.event.AdjustmentEvent クラスのオブジェクトは、変更された調整値の値を提供します。

java.awt.event.AdjustmentEvent クラス
java.lang.Object
  |
  +--java.util.EventObject
        |
        +--java.awt.AWTEvent
              |
              +--java.awt.event.AdjustmentEvent
public class AdjustmentEvent extends AWTEvent

このクラスで重要なのは、イベントを発生させた Adjustable インタフェースを実装するオブジェクトを取得する getAdjustable() メソッドと、調整の結果となる値を返す getValue() メソッドでしょう。リスナーからイベントを発生させたオブジェクトを制御するには Adjustable オブジェクトから行うことができます。

AdjustmentEvent クラス getAdjustable() メソッド
public Adjustable getAdjustable()
AdjustmentEvent クラス getValue() メソッド
public int getValue()

Adjustable インタフェースには、最小値、最大値、現在の値、スクロールバーの長さを制御するメソッドが提供されているため、ここからスクロールバーオブジェクトの実体を制御することができるでしょう。

コード1
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame implements AdjustmentListener {
	public static void main(String args[]) {
		JFrame win = new Test();
		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		win.setBounds(10 , 10 , 400 , 300);
		win.show();
	}

	private JScrollBar bar1 = new JScrollBar(Adjustable.VERTICAL);
	private JScrollBar bar2 = new JScrollBar(Adjustable.HORIZONTAL);
	private JLabel label = new JLabel("つまみを動かしてください");
	public Test() {
		bar1.addAdjustmentListener(this);
		bar2.addAdjustmentListener(this);

		getContentPane().add(bar1 , BorderLayout.EAST);
		getContentPane().add(bar2 , BorderLayout.SOUTH);
		getContentPane().add(label);
	}

	public void adjustmentValueChanged(AdjustmentEvent e) {
		label.setText(
			"垂直バー = " + bar1.getValue() +
			",水平バー = " + bar2.getValue()
		);
	}
}
実行結果
コード1 実行結果

コード1は、多くのプラットフォームで共通するスクロールバーの配置方法で垂直スクロールバーと水平スクロールバーを表示しています。一般的な GUI プラットフォームでは、垂直スクロールバーはコンテナの右側に、水平スクロールバーはコンテナの下部に表示するのが常識です。このプログラムでは BorderLayout レイアウトマネージャの性質を利用して EAST と SOUTH にそれぞれのコンポーネントを配置しています。

スクロールバーはデフォルトの値で作成しているため最小値が 0、最大値が 100 に設定されています。Test クラスは AdjustmentListener インタフェースを実装しているため、スクロールバーの調整イベントをリスナとして受けることができます。コンストラクタの先頭で addAdjustmentListener() メソッドを呼び出し、スクロールバーにリスナを登録しているため、スクロールバーを調整すると adjustmentValueChanged() が呼び出されるでしょう。イベントが発生すると、コンテナの中央に配置されているラベルにスクロールバーの現在の値を表示します。

しかし、スクロールバーの役割はスライダーと大きな違いはなく、結局のところは特定範囲内の値を提供するに過ぎません。開発者はこの値を使ってスクロールバーが関連しているコンポーネントのコンテンツを正しく制御しなければならないのですが、個々のコンポーネントに対してスクロールバーをプログラムするのはオブジェクト指向として効率的ではありません。

幸い、Swing ではコンテンツに応じてスクロールバーを表示してくれるコンテナが存在します。Swing のコンテナについては後述します。