LoginSignup
2
5

More than 5 years have passed since last update.

ControlsFX / Validationを使用する

Posted at

環境

  • JDK 1.8.0_121
  • ControlsFX 8.40.12

ControlsFXにおけるバリデーション

JavaFXアプリケーションに入力チェック機能を実装するためにControlsFXのバリデーション機能を使ってみます。以下のような見た目になります。

0.png

エラーアイコンにカーソルを合わせるとエラーメッセージがツールチップ表示されます。(ちょっと気づきにくい感じはします)

0e.png

準備

ControlsFXを使用するのでGradleやMavenのdependencyにControlsFXを追加します。直接インポートする場合はこちらからダウンロードしてください。

Validator

Validatorは入力内容をチェックするための基本的な仕組みを提供しており、自分で条件を定義することもできます。以下の4つのメソッドを使ってバリデーターを作成できます。

Validator<T>:: 動作
createEmptyValicator 空入力をERRORにする
createEqualsValidator リストにない入力をERRORにする
createRegexValidator 正規表現に合わない入力をERRORにする
createPredicateValidator 指定したPredicate<S>に合わない入力をERRORにする

Predicate<S>コントロールのvalueを受け取ってbooleanを返す関数型インタフェースです。好きな条件をラムダ式を使って実装できるのですっきり書けますし応用が利きます。また、引数にはエラーレベル(Severity.ERRORSeverity.WARNING)やエラーメッセージを指定します。
Validator (ControlsFX): API Document

複数のバリデーターを一つのコントロールにセットするにはValidator<T>::combineを使ってバリデーターを合成する必要がありますがここでは触れません。(「~の形式で入力してください」を空チェックの兼用とするなど、一つで済ませる方法もあります)

バリデーションのコード例は次で触れます。

ValidationSupport

ValicatorValidationSupportクラスに登録して使用します。あとは入力内容が変更される度に自動的にバリデーションが行われるので、以下の例だけでバリデーションが全て機能します。

バリデーターの登録にはValidationSupport::registerValidatorを使用します。登録時に入力必須アイコンの表示可否を指定できます。

initialize内などで
ValidationSupport support = new ValidationSupport();
support.registerValidator(textField1, false, Validator.createEmptyValidator(
                "Text is required",
                Severity.WARNING));
support.registerValidator(textField2, Validator.createEqualsValidator(
                "A or B or C is required",
                Arrays.asList("A", "B", "C")));
support.registerValidator(textField3, Validator.createRegexValidator(
                "Number is required",
                Pattern.compile("^[0-9]+$"), Severity.ERROR));
support.registerValidator(checkBox, Validator.createEqualsValidator(
                "Check is required",
                Collections.singletonList(true)));
support.registerValidator(comboBox, Validator.createEqualsValidator(
                "First item is required",
                Collections.singletonList(comboBox.getItems().get(0))));
support.registerValidator(colorPicker, Validator.createEqualsValidator(
                "WHITE or BLACK is required",
                Arrays.asList(Color.WHITE, Color.BLACK)));
support.registerValidator(slider, Validator.createPredicateValidator(
                (Double value) ->  value > 0.0,
                "Positive number is required"));

// スタティックインポートを使用して
// import static org.controlsfx.validation.Validator.*;
// とすると毎回 Validator. を書かなくて済みます

5.png

ValidationSupportクラスはバリデーション結果全体に関するプロパティを持っているので、結果全体に追従する仕組みを実装するのに便利です。

// 全ての結果がvalidな場合だけ有効なボタン
Button buttonValidated= new Button();
buttonValidated.disableProperty().bind(support.invalidProperty());

// エラーメッセージを全て表示するListView
ListView<ValidationMessage> listView = new ListView<>();
support.validationResultProperty().addListener((o, oldValue, newValue) ->
                listView.getItems().setAll(newValue.getMessages()));

ValidationSupport (ControlsFX): API Document

CSSによってエラー表示を変更したい場合

上記の例はデフォルトアイコンによるエラー表示のみ行っていますがこれを変更できます。StyleClassValidateionDecorationを使用すると警告時にはwarning、エラー時にはerrorというスタイルクラスをコントロールに追加してくれます。実装者はSceneに適用するCSSファイルにエラー時のスタイルを記述する必要があります。アイコン表示との併用もできます。

// CSSのみの場合
support.setValidationDecorator(new StyleClassValidationDecoration());
// アイコンとCSSを併用する場合
support.setValidationDecorator(new CompoundValidationDecoration(
    new GraphicValidationDecoration(), 
    new StyleClassValidationDecoration()));
Main.css
.warning{
    -fx-border-color: orange;
    -fx-border-width: 2;
}
.error{
    -fx-border-color: red;
    -fx-border-width: 2;
}
FXMLを読み込むところ等で
scene.getStylesheets().addAll(getClass().getResource("Main.css").toExternalForm());

以下はアイコンとCSSを併用する場合の画面表示です。

5e.png

CSSのみの場合ツールチップを表示する方法がないのでエラー内容を伝える工夫が必要です。

アイコンやツールチップをデザイン変更したい場合

アイコンやツールチップのデザイン変更は、GraphicValidationDecorationを継承して対応するメソッドをオーバーライドする方法があります。

GraphicValidationDecoration:: 説明
createErrorNode エラーアイコン
createWarningNode 警告アイコン
createRequireDecorations 入力必須アイコン
createTooltip ツールチップ

オリジナルのソースを参考にして一部書き換える感じでやると簡単かと思います。
GraphicValidationDecoration (ControlsFX): API Document
bitbucket: GraphicValidationDecoration

継承したクラスをセットするコード
support.setValidationDecorator(new YourGraphicValidationDecoration());

カスタムコントロールをバリデーションするときの注意

ControlsFXのバリデーターはあなたが作成したカスタムコントロールのどのプロパティをチェックするべきかを知りません。JavaFX標準ではないコントロールをバリデーションする場合は次のようなコードで教えてあげる必要があります。公式の説明はこちら

// YourControlコントロールについて、someプロパティの値をバリデーションして欲しいとき
ValueExtractor.addObservableValueExtractor( 
        c -> c instanceof YourControl, 
        c -> ((YourControl)c).someProperty());

参考

ControlsFX: sample
ソース: GIT
FXML,CSS: GIT

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5