『
JavaFX UIコントロール(全体像)』に引き続き、UIレイアウトの詳細な使い方を見ていく。今回はプログラムを参照しながら、UIコントロールの表示方法とイベント・ハンドラの利用方法を見る。
■ サンプルコード
以下にUIコントロールを利用するサンプルコードと解説を示す。サンプル中で利用されている要素技術については、以下のリンクにて解説している。
◇サンプルの実行結果
◇サンプルプログラム
package application_fx;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.PasswordField;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.Separator;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TestUIControl1 extends Application {
public static void main(String[] args)
{
launch( args );
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void start(Stage primaryStage) throws Exception
{
// フォント色がおかしくなることへの対処
System.setProperty( "prism.lcdtext" , "false" );
// シーングラフを作成
VBox root = new VBox( 2.0 );
// ラベルとツールチップを登録
Label label = new Label( "ラベル。ココにマウスをあわせてください(ツールチップ機能の確認)" );
label.setTooltip( new Tooltip( "ツールチップとは、オンマウス時に表示されるテキストのことです。" ) );
root.getChildren().add( label );
// ハイパーリンク
Hyperlink link = new Hyperlink();
link.setText( "ハイパーリンク" );
link.setOnAction( e -> System.out.println( "ハイパーテキストをクリック" ) );
root.getChildren().add( link );
// テキスト・フィールド
// copy,cut,selectAll,paste関数などが使える
TextField text = new TextField();
text.setTooltip( new Tooltip( "text field" ) );
text.setPromptText( "please input your name" );
root.getChildren().add( text );
text.textProperty().addListener( ( ov , old , current ) -> System.out.println( "テキストフィールドの値:" + text.getText() ) );
// パスワード・フィールド
PasswordField password = new PasswordField();
password.setPromptText( "please input password" );
root.getChildren().add( password );
password.textProperty().addListener( ( ov , old , current ) -> System.out.println( "パスワードフィールドの値:" + password.getText() ) );
// ボタンを登録
Button button = new Button( "ボタン" );
root.getChildren().add( button );
button.addEventHandler( ActionEvent.ACTION , e -> System.out.println( "Button Click" ) );
// トグルボタンを登録
ToggleButton toggle = new ToggleButton( "トグルボタン" );
root.getChildren().add( toggle );
toggle.selectedProperty().addListener( ( ov , old , current ) -> System.out.println( "トグルボタンの状態:" + toggle.isSelected() ) );
// セパレータ
Separator sep = new Separator();
sep.setOrientation( Orientation.HORIZONTAL );
sep.setMaxWidth( 200 );
root.getChildren().add( sep );
// ラジオボタンを登録
ToggleGroup radioGroup = new ToggleGroup();
RadioButton radio1 = new RadioButton( "ラジオボタン1" );
RadioButton radio2 = new RadioButton( "ラジオボタン2" );
radio1.setToggleGroup( radioGroup );
radio2.setToggleGroup( radioGroup );
radio1.setUserData( "ラジオボタン1が選択されました" );
radio2.setUserData( "ラジオボタン2が選択されました" );
radio1.setSelected( true );
root.getChildren().add( radio1 );
root.getChildren().add( radio2 );
radioGroup.selectedToggleProperty().addListener( ( ov , old , current ) -> System.out.println( radioGroup.getSelectedToggle().getUserData() ) );
// チェックボックス
CheckBox check1 = new CheckBox("チェックボックス1");
check1.setAllowIndeterminate( true );
root.getChildren().addAll( check1 );
check1.indeterminateProperty().addListener( ( ov , old , current ) -> System.out.println( "チェックボックスの状態:indeterminate:" + check1.isIndeterminate() + "/" ) );
check1.selectedProperty().addListener( ( ov , old , current ) -> System.out.println( "チェックボックスの状態:selected:" + check1.isSelected() ) );
// 選択ボックス
ChoiceBox choice = new ChoiceBox( FXCollections.observableArrayList( "Zero" , new Separator() , "First" , "Second" , "Third" ));
choice.setTooltip( new Tooltip("select order") );
root.getChildren().add( choice );
choice.getSelectionModel().selectedItemProperty().addListener( ( ov , old , current ) -> System.out.println( "選択ボックス:" + choice.getSelectionModel().getSelectedItem() ) );
// コンボボックス
ComboBox combo = new ComboBox();
combo.setItems( FXCollections.observableArrayList( "その1" , "その2" , "その3" ) );
combo.setEditable( true );
Callback<ListView<String>,ListCell<String>> cellFactory = p ->
{
// セルを作成
ListCell<String> cell = new ListCell<String>(){
{
super.setPrefWidth(100);
}
@Override public void updateItem( String item , boolean empty )
{
// 元関数を呼び出し
super.updateItem(item, empty);
// セルのプロパティを設定
if( item == null ){ return; }
setText(item);
setTextFill( Color.RED );
}
};
return cell;
};
combo.setCellFactory( cellFactory );
root.getChildren().add( combo );
combo.getSelectionModel().selectedItemProperty().addListener( ( ov , old , current ) -> System.out.println( "コンボボックス:" + combo.getSelectionModel().getSelectedItem() ) );
// リスト・ビュー
ListView<String> list = new ListView<String>();
list.setItems( FXCollections.observableArrayList( "1st" , "2nd" , "3rd" ) );
list.setPrefSize( 100 , 60 );
list.getSelectionModel().setSelectionMode( SelectionMode.MULTIPLE );
root.getChildren().add( list );
list.getSelectionModel().selectedItemProperty().addListener( ( ov , old , current ) -> System.out.println( "リストビュー:" + list.getSelectionModel().getSelectedItems() ) );
// 日付ピッカー
DatePicker datePicker = new DatePicker();
root.getChildren().add( datePicker );
datePicker.valueProperty().addListener( ( ov , old , current ) -> System.out.println( "日付ピッカー:" + datePicker.getValue() ) );
// カラーピッカー
ColorPicker colorPicker = new ColorPicker();
root.getChildren().add( colorPicker );
colorPicker.valueProperty().addListener( ( ov , old , current ) -> System.out.println( "カラーピッカー:" + colorPicker.getValue() ) );
// スクロールバー
Rectangle rect1 = new Rectangle( 30 , 15 , Color.BLACK );
ScrollBar scroll = new ScrollBar();
scroll.setMin( 0 );
scroll.setMax( 100 );
scroll.setValue( 30 );
scroll.setUnitIncrement( 1 ); // 矢印ボタンを押下した場合の増加量
scroll.setBlockIncrement( 10 ); // バーを押下した場合の増加量
root.getChildren().addAll( rect1 , scroll );
scroll.valueProperty().addListener( ( ov , old , current ) -> rect1.setWidth( scroll.getValue() ) );
// スクロール・ペイン
ScrollPane sp = new ScrollPane();
sp.setContent( new Label( "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n" ) );
sp.setPannable( true );
sp.setPrefSize( 100 , 60 );
sp.setHbarPolicy( ScrollBarPolicy.NEVER );
sp.setVbarPolicy( ScrollBarPolicy.ALWAYS );
root.getChildren().add( sp );
// スライダ
Rectangle rect2 = new Rectangle( 50 , 15 , Color.BLACK );
Slider slider = new Slider();
slider.setMin( 0 );
slider.setMax( 100 );
slider.setValue( 50 );
slider.setShowTickLabels( true );
slider.setShowTickMarks( true );
slider.setMajorTickUnit( 20 );
slider.setMinorTickCount( 5 );
slider.setBlockIncrement( 5 );
root.getChildren().addAll( rect2 , slider );
slider.valueProperty().addListener( ( ov , old , current ) -> rect2.setWidth( slider.getValue() ) );
// 進行状況バー/インジケータ
ProgressBar pb = new ProgressBar( 0.5 );
ProgressIndicator pi = new ProgressIndicator( 0.5 );
root.getChildren().addAll( pb , pi );
slider.valueProperty().addListener( ( ov , old , current ) -> { pb.setProgress( slider.getValue() / 100.0 ); pi.setProgress( slider.getValue() / 100.0 ); } );
// シーンを作成
Scene scene = new Scene( root , 500 , 600 , Color.web( "9FCC7F" ) );
// ウィンドウ表示
primaryStage.setScene( scene );
primaryStage.show();
}
}
■ 解説
◇ ラベル (57行目~59行目)
表示テキストを指定してラベルを作成。テキスト変更時はsetText関数を利用する。
◇ ツールチップ (58行目)
表示テキストを指定してツールチップを作成し、setTooltip関数でUIコントロールに適用。適用すると、オンマウス状態がしばらく続くとツールチップが表示される。すべてのUIコントロールで設定可能。
◇ ハイパーリンク (62行目~65行目)
ハイパーリンクの使い方はラベルとほぼ同じ。異なる点は、デフォルトの見た目とオンマウス時のカーソル形状のみ。クリック時の動作はイベント・ハンドラで設定する。サンプルではラムダ式を利用し、クリック時に標準出力に文字をするように設定している。
◇ テキスト・フィールド (69行目~73行目)
setPromptText関数で何も入力されていない場合に表示される文字を設定できる。デフォルト値の設定はsetText関数で行う。textPropertyにバインディングを設定することで、文字の変化毎に処理を設定することが可能。また、サンプルでは利用していないがテキストを操作する以下のような関数も用意されている。
- selectAll関数 ・・・すべてのテキストを選択
- deselect関数 ・・・選択範囲を解除
- copy関数 ・・・現在選択されているテキストをクリップボードに転送
- cut関数 ・・・現在選択されているテキストを削除し、クリップボードに転送
- paste関数 ・・・現在選択されているテキストを削除し、クリップボードの値を貼付
◇ パスワード・フィールド (76行目~79行目)
テキストフィールドと使い方は同じ。異なるのは入力文字が『●●●』で表現されることのみ。
◇ ボタン (82行目~84行目)
表示テキストを指定してボタンを作成できる。コンストラクタの第2引数にImageViewを指定することでイメージボタンを作成可能。ボタン押下時のイベント処理は、ActionEvent.Actionに対して、イベント・ハンドラを設定することで処理可能。
◇ トグルボタン (87行目~89行目)
ボタンと異なるのは、クリックにより押下状態/未押下状態の2状態を行き来するということ。押下状態の場合はisSelected関数がtrueを返し、未押下状態の場合はfalseを返す。状態が変わった際の処理は、selectProperty変数へのバインディングを設定することで処理可能。
◇ セパレータ (92行目~95行目)
セパレータの方向は以下の2つが設定可能。
- Orientation.HORIZONTAL ・・・横方向のセパレータ
- Orientation.VERTICAL ・・・縦方向のセパレータ
◇ ラジオ・ボタン (98行目~108行目)
ToggleGroupクラスはラジオボタンが属するグループを表す。トグルグループ内のラジオボタンが選択状態になると、トグルグループ内の他のラジオボタンは非選択状態となる。トグルグループ内で選択されたラジオボタンはToggleGroup::getSelectedTogle関数で取得できる。サンプルではsetUserData関数でラジオボタンに対応するテキストを宣言し、getUserData関数で選択されたテキストを取得している。
◇ チェックボックス (111行目~115行目)
チェックボックスでは、選択状態/非選択状態/無効状態の3状態が選択できる。無効状態はsetAllowIndeterminate関数にtrueを設定することで選択可能になる。無効状態かどうかはisIndeterminate関数で取得でき、選択状態/非選択状態はisSelected関数で取得できる。選択が変わったタイミングはgetSelectedProperty変数へのバインディングで取得できる。
◇ 選択ボックス (118行目~121行目)
単一選択のみ可能。選択ボックスに表示する選択肢はFXCollections.observableArrayList型の配列で定義する。選択されたテキストはgetSelectionModel().selectedItem関数で取得可能。選択が変わったタイミングはgetSelectionModel().selectedItemProperty変数へのバインディングで取得できる。
◇ コンボボックス (124行目~150行目)
単一選択のみ可能。コンボボックスに表示する選択肢はFXCollections.observableArrayList型の配列で定義する。選択ボックスと利用方法は同じ。サンプルでは、セルのカスタマイズにより文字色を赤色に設定している。
◇ リスト・ビュー (153行目~158行目)
単一選択と複数選択の両方が利用可能。setSelectionMode関数に以下の定数を渡すことで変更可能。初期値は単一選択
- 単一選択 ・・・SelectionMode.SINGLE
- 複数選択 ・・・SelectionMode.MULTIPLE
複数選択時、選択した値はgetSelectionModel().getSelectedItems関数で一覧取得可能。
◇ 日付ピッカー (161行目~163行目)
選択された日付は、getValue関数によりLocalDate型の変数として返される。
◇ カラーピッカー (166行目~168行目)
選択された色は、getValue関数によりColor型の変数として返される。
◇ スクロールバー (171行目~179行目)
スクロールバーを利用するには、最低限以下の項目を定義する。
- 最小値 ・・・スクロールバーの左限値。setMin関数で設定
- 最大値 ・・・スクロールバーの右限値。setMax関数で設定
- 選択値 ・・・値を表すの位置。setValue関数で設定
- 矢印ボタン増減値 ・・・矢印ボタンを押した場合の増減値。setUnitIncrement関数で設定
- トラック押下時増減値 ・・・トラックを押した場合の増減値。setBloackIncrement関数で設定
また、スクロールバーの方向は以下の2つから選択可能。デフォルトは水平方向。setOrientation関数で変更可能。
- 水平方向 ・・・Orientation.HORIZONTAL
- 垂直方向 ・・・Orientation.VERTICAL
スクロール・バーの値はgetValue関数により取得する。スクロール・バーの移動に対応して処理を行いたい場合は、valueProperty変数へのバインディングを利用する。サンプルでは四角形の横幅をスクロール・バーの移動に連動して変化させている。
◇ スクロール・ペイン (182行目~188行目)
setContent関数で設定したノードを、指定したサイズで表示視するペイン。はみ出した部分はスクロールにて見ることができる。サイズの指定はsetPrefSize関数で指定する。スクロールバーの表示設定はsetHbarPolicy関数(横方向)、setVbarPolicy関数(縦方向)で設定可能。表示は以下の3つから設定可能。
- 常に表示 ・・・ScrollBarPolicy.ALWAYS
- 必要に応じて表示 ・・・ScrollBarPolicy.AS_NEEDED
- 常に非表示 ・・・ScrollBarPolicy.NEVER
また、マウスをドラッグすることによりスクロールすることをパンといい、パンを許可するかどうかはsetPannable関数で設定する。
◇ スライダ (191行目~202行目)
スライダを利用するには、最低限以下のものを設定する。
- 最小値 ・・・スライダの最小値。setMin関数で設定
- 最大値 ・・・スライダの最大値。setMax関数で設定
- スライダ値 ・・・スライダが示す値。setValue関数で設定
- 増減値 ・・・矢印キーを押した場合の増減値。setBlockIncrement関数で設定
また、スライダの目盛表示は以下の関数で設定する。
- 目盛 ・・・setShowTickMarks関数で表示/非表示を設定
- 目盛上の数字 ・・・setShowTickLables関数で表示/非表示を設定
- 主目盛の間隔 ・・・setMajorTickUnit関数で主目盛の間隔を設定
- 補助目盛の間隔 ・・・setMinorTickCount関数で副目盛の間隔を設定
スライダの値はgetValue関数により取得する。スライダの移動に連動して処理を行う際は、valueProperty変数へのバインディングを利用する。サンプルでは四角形の横幅をスライダ値に連動して変更している。
◇ 進捗バー/進行状況インジケータ (204行目~208行目)