29 UIコントロールのカスタマイズ
この章では、UIコントロールのカスタマイズの特徴について説明するとともに、UIコントロールの外観と動作を変更するために用意されているヒントやテクニックの概要を示します。
Cascading Style Sheet (CSS)の適用、デフォルトの動作の再定義、およびセル・ファクトリの使用によってUIコントロール・サンプル・プロジェクト内のサンプル・アプリケーションのコントロールをカスタマイズする方法について学習できます。javafx.scene.control
パッケージのクラスを使用しても実装できない特別な機能がアプリケーションのタスクに必要になる特定のケースについては、Control
クラスを拡張して独自のコントロールを作成してください。
CSSの適用
JavaFX modena
スタイル・シートのスタイル定義を再定義することにより、UIコントロールの外観を変更できます。スタイルを変更してJavaFXアプリケーションで有効にする方法やその一般的な概念は、「CSSによるJavaFXアプリケーションのスキニング」を参照してください。
JavaFXフォーラムで開発者によって頻繁にリクエストされる特定のタスクについて考えてみます。
Tooltip
クラスにはツールチップのデフォルトの色を変更するためのプロパティやメソッドはありませんが、例29-1に示すように、.tooltip
CSSクラスの-fx-background-color
を変更できます。
例29-1 ツールチップの背景色の変更
.tooltip { -fx-background-color: linear-gradient(#e2ecfe, #99bcfd); } .page-corner { -fx-background-color: linear-gradient(from 0% 0% to 50% 50%,#3278fa,#99bcfd); }
.page-corner
CSSクラスは、ツールチップの右下隅の色を定義します。例29-1のコードをTooltipSampleのスタイル・シートに追加し、このスタイル・シートをシーンに適用すると、ツールチップの色は青に変更されます。図29-1を参照してその効果を評価してください。
ツールチップのデフォルトのスタイルを変更すると、新しい外観がアプリケーション内のすべてのツールチップに適用されることに注意してください。
もう1つの一般的な設計タスクとして、コントロールのデフォルトのマークを変更するタスクがあります。たとえば、CheckBox
クラスのデフォルトのスタイルは、選択した状態の通常のチェック・マークを定義します。例29-2に示すように、マークの形状のみでなく色も再定義できます。
例29-2 別のチェック・ボックスのマーク
.check-box .mark { -fx-shape: "M2,0L5,4L8,0L10,0L10,2L6,5L10,8L10,10L8,10L5,6L2,10L0,10L0,8L4,5L0,2L0,0Z"; } .check-box:selected .mark { -fx-background-color: #0181e2; }
-fx-shape
プロパティはマークに新しいSVGパスを設定し、-fx-background-color
はその色を定義します。変更したスタイル・シートをCheckBoxSampleアプリケーションで有効にすると、図29-2に示すように、選択したチェック・ボックスにはチェック・マークのかわりにXマークが表示されます。
多くの開発者から、TableView
およびListView
コントロールの視覚スタイルの制限を超える方法についての質問が寄せられています。デフォルトでは、これらのコントロールのすべての行が空であるかどうかとは関係なく表示されます。適切なCSS設定を使用すると、空の行すべてに対して特定の色を設定できます。例29-3では、このタスクをTableView
コントロールに対して実装しています。
例29-3 表ビュー内の空の行に対する色の設定
.table-row-cell:empty { -fx-background-color: lightyellow; } .table-row-cell:empty .table-cell { -fx-border-width: 0px; }
最初のCSSスタイルにより、偶数と奇数のどちらであるかとは関係なく、空の行すべての背景色を淡黄色にすることを決定します。table-row-cellがemptyである場合、2番目のCSS文により、表のセルすべての右側に描画されている縦の枠線が削除されます。
例29-3のCSSスタイルをTableViewSampleアプリケーションで有効にすると、「Address Book」表は図29-3のようになります。
空のセルの背景色にnull
値を設定することもできます。この場合、スタイル・シートでは表示ビューのデフォルトの背景色が使用されます。図29-4を参照してその効果を評価してください。
UIコントロールにCSSプロパティを追加設定することにより、その形状、色スキーム、および適用した効果を変更できます。使用可能なCSSのプロパティおよびクラスの詳細は、JavaFX CSSリファレンス・ガイドを参照してください。
デフォルトの動作の変更
多くの開発者から、テキスト・フィールドでの入力を制限(たとえば、数値の使用のみを許可)できる特定のAPIがリクエストされています。例29-4に、数値テキスト・フィールドがある単純なアプリケーションを示します。
例29-4 テキスト・フィールドでの文字の禁止
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.geometry.Insets; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.stage.Stage; public class CustomTextFieldSample extends Application { final static Label label = new Label(); @Override public void start(Stage stage) { Group root = new Group(); Scene scene = new Scene(root, 300, 150); stage.setScene(scene); stage.setTitle("Text Field Sample"); GridPane grid = new GridPane(); grid.setPadding(new Insets(10, 10, 10, 10)); grid.setVgap(5); grid.setHgap(5); scene.setRoot(grid); final Label dollar = new Label("$"); GridPane.setConstraints(dollar, 0, 0); grid.getChildren().add(dollar); final TextField sum = new TextField() { @Override public void replaceText(int start, int end, String text) { if (!text.matches("[a-z, A-Z]")) { super.replaceText(start, end, text); } label.setText("Enter a numeric value"); } @Override public void replaceSelection(String text) { if (!text.matches("[a-z, A-Z]")) { super.replaceSelection(text); } } }; sum.setPrefColumnCount(10); GridPane.setConstraints(sum, 1, 0); grid.getChildren().add(sum); Button submit = new Button("Submit"); GridPane.setConstraints(submit, 2, 0); grid.getChildren().add(submit); submit.setOnAction((ActionEvent e) -> { label.setText(null); }); GridPane.setConstraints(label, 0, 1); GridPane.setColumnSpan(label, 3); grid.getChildren().add(label); scene.setRoot(grid); stage.show(); } public static void main(String[] args) { launch(args); } }
TextField
クラスのデフォルトの実装を再定義するには、TextInputControl
クラスから継承されたreplaceText
およびreplaceSelection
メソッドをオーバーライドする必要があります。
ユーザーが「Sum」テキスト・フィールドに文字を入力しようとすると、記号は表示されず、警告メッセージが表示されます。図29-5に、この状況を示します。
ただし、ユーザーが数値を入力しようとすると、図29-6に示すように、これらの数値がフィールドに表示されます。
セル・ファクトリの実装
セル・ファクトリのメカニズムを使用することにより、4つのUIコントロールの外観のみでなく動作も完全にカスタマイズできます。セル・ファクトリは、TableView
、ListView
、TreeView
およびComboBox
に適用できます。セル・ファクトリを使用して、これらのコントロールの単一の項目を表すために使用できるセル・インスタンスを生成できます。
Cell
クラスはLabeled
クラスを拡張します。このクラスには、テキストの表示や編集という最も一般的なユースケースを実装するために必要なプロパティおよびメソッドがすべて用意されています。ただし、アプリケーションのタスク上、リストまたは表内にグラフィカル・オブジェクトを表示することが必要である場合、graphic
プロパティを使用し、セル内にNode
を配置できます(カスタム・セルの詳細は、セル・クラスのAPI仕様を参照してください)。
たとえば、例29-5のコード・フラグメントでは、リスト・ビューのセル・ファクトリを作成し、updateItem
メソッド内のセルのコンテンツを再定義することにより、リストの様々な色の四角形が表示されるようにしています。
例29-5 ListViewコントロールのセル・ファクトリの実装
list.setCellFactory((ListView<String> l) -> new ColorRectCell()); ... static class ColorRectCell extends ListCell<String> { @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); Rectangle rect = new Rectangle(100, 20); if (item != null) { rect.setFill(Color.web(item)); setGraphic(rect); } else { setGraphic(null); } } }
図29-7に、カスタマイズしたこのリストがUIコントロール・サンプル・プロジェクトのListViewSampleでどのように表示されるかを示します。
このチュートリアルでは、セル・ファクトリのメカニズムを広範囲にわたって使用してUIコントロールをカスタマイズします。これらのコントロールをカスタマイズするには、セル・ファクトリのメカニズムを使用するか、視覚化の基礎となる特定のデータ・モデルを提供する事前作成済のセル・エディタの実装を使用できます。表29-1に、JavaFX APIで使用できる対応するクラスをリストします。
表29-1 リスト・ビュー・コントロール、ツリー・ビュー・コントロールおよび表ビュー・コントロールのセル・エディタ・クラス
コントロール | セル・エディタ・クラス |
---|---|
リスト・ビュー |
|
ツリー・ビュー |
|
表ビュー |
|
ツリー表ビュー |
|
各セル・エディタ・クラスにより、セル内に特定のノードが描画されます。たとえば、CheckBoxListCell
クラスにより、リスト・セル内にCheckBox
ノードが描画されます。
別のセル・ファクトリやセル・エディタのユースケースを評価するには、「表ビュー」、「ツリー・ビュー」および「コンボ・ボックス」の各章を参照してください。
関連ドキュメントとリソース