1. 序章

JavaFX は、さまざまなプラットフォーム用のアプリケーションUIを構築するために設計された強力なツールです。 UIコンポーネントだけでなく、プロパティや監視可能なコレクションなどのさまざまな便利なツールを提供します。

ListView コンポーネントは、コレクションを管理するのに便利です。 つまり、DataModelを定義したりListView要素を明示的に更新したりする必要はありませんでした。 ObjervableList で変更が発生すると、ListViewウィジェットに反映されます。

ただし、このようなアプローチでは、カスタムアイテムをJavaFX ListViewで表示する方法が必要です。 このチュートリアルでは、ListViewでドメインオブジェクトがどのように表示されるかを設定する方法について説明します。

2. セルファクトリー

2.1. デフォルトの動作

デフォルトでは、JavaFXの ListView は、 toString()メソッドを使用してオブジェクトを表示します。

したがって、明らかなアプローチはそれをオーバーライドすることです。

public class Person {
    String firstName;
    String lastName;

    @Override
    public String toString() {
        return firstName + " " + lastName;
    }
}

このアプローチは、学習と概念の例では問題ありません。 ただし、これは最善の方法ではありません。

まず、ドメインクラスがディスプレイの実装を行います。 したがって、このアプローチは単一責任の原則と矛盾します。

次に、他のサブシステムが toString()を使用する場合があります。 たとえば、 toString()メソッドを使用して、オブジェクトの状態をログに記録します。 ログには、ListViewのアイテムよりも多くのフィールドが必要な場合があります。 したがって、この場合、単一の toString()実装では、すべてのモジュールのニーズを満たすことはできません。

2.2. ListViewにカスタムオブジェクトを表示するセルファクトリ

カスタムオブジェクトをJavaFXListViewで表示するためのより良い方法を考えてみましょう。

ListView の各アイテムは、ListCellクラスのインスタンスとともに表示されます。 ListCell には、textというプロパティがあります。 セルにtextの値が表示されます。

したがって、 ListCell インスタンスのテキストをカスタマイズするには、そのtextプロパティを更新する必要があります。 どこでできますか? ListCell には、updateItemという名前のメソッドがあります。 アイテムのセルが表示されると、updateItemが呼び出されます。 updateItem メソッドは、セルが変更されたときにも実行されます。 したがって、デフォルトのListCellクラスから独自の実装を継承する必要があります。 この実装では、updateItemをオーバーライドする必要があります。

しかし、 ListView にデフォルトの実装の代わりにカスタム実装を使用させるにはどうすればよいでしょうか?

ListViewにはセルファクトリがある場合があります。 セルファクトリはデフォルトでnullです。 ListViewがオブジェクトを表示する方法をカスタマイズするように設定する必要があります。

例としてセルファクトリを説明しましょう。

public class PersonCellFactory implements Callback<ListView<Person>, ListCell<Person>> {
    @Override
    public ListCell<Person> call(ListView<Person> param) {
        return new ListCell<>(){
            @Override
            public void updateItem(Person person, boolean empty) {
                super.updateItem(person, empty);
                if (empty || person == null) {
                    setText(null);
                } else {
                    setText(person.getFirstName() + " " + person.getLastName());
                }
            }
        };
    }
}

CellFactoryはJavaFXコールバックを実装する必要があります。 JavaFXのCallbackインターフェースは、標準のJava Functionインターフェースに似ています。 ただし、JavaFXは、歴史的な理由からCallbackインターフェースを使用します。

updateItemメソッドのデフォルトの実装を呼び出す必要があります。 この実装は、セルをオブジェクトに接続したり、空のリストの行を表示したりするなど、デフォルトのアクションをトリガーします。

メソッドupdateItemのデフォルトの実装も、setTextを呼び出します。 次に、セルに表示されるテキストを設定します。

2.3. カスタムウィジェットを使用してJavaFXListViewにカスタムアイテムを表示する

ListCell は、カスタムウィジェットをコンテンツとして設定する機会を提供します。 ドメインオブジェクトをカスタムウィジェットに表示するには、 setCell()。の代わりに setGraphics()を使用するだけです。

各行をCheckBoxとして表示する必要があるとします。 適切なセルファクトリを見てみましょう。

public class CheckboxCellFactory implements Callback<ListView<Person>, ListCell<Person>> {
    @Override
    public ListCell<Person> call(ListView<Person> param) {
        return new ListCell<>(){
            @Override
            public void updateItem(Person person, boolean empty) {
                super.updateItem(person, empty);
                if (empty) {
                    setText(null);
                    setGraphic(null);
                } else if (person != null) {
                    setText(null);
                    setGraphic(new CheckBox(person.getFirstName() + " " + person.getLastName()));
                } else {
                    setText("null");
                    setGraphic(null);
                }
            }
        };
    }
}

この例では、textプロパティをnullに設定します。 textプロパティとgraphicプロパティの両方が存在する場合、テキストはウィジェットの横に表示されます。

もちろん、カスタム要素データに基づいて、CheckBoxコールバックロジックやその他のプロパティを設定できます。 ウィジェットのテキストを設定するのと同じように、コーディングが必要です。

3. 結論

この記事では、JavaFX ListViewでカスタムアイテムを表示する方法を検討しました。 ListView を使用すると、非常に柔軟に設定できることがわかりました。 ListViewセルにカスタムウィジェットを表示することもできます。

いつものように、例のコードはGitHubから入手できます。