モジュール javafx.controls
パッケージ javafx.scene.control

クラスCell<T>

  • 型パラメータ:
    T - セル内に含まれるアイテムの型。
    すべての実装されたインタフェース:
    Styleable, EventTarget, Skinnable
    直系の既知のサブクラス:
    DateCell, IndexedCell


    public class Cell<T>
    extends Labeled
    セルAPIは、ListViewTreeViewTableViewなどの仮想コントロールに対して使用されます。 セルは、Labeled Controlであり、ListView、TreeViewまたはTableView内の単一行のレンダリングに使用されます。 セルは、TableView内の個々のセル(つまり、各行/列交差)にも使用されます。 詳細は、各コントロール個別のJavaDocを参照してください。

    各セルは、(itemプロパティで表される)単一のデータ・アイテムに関連付けられています。 セルは、そのアイテムのレンダリング、および該当する場合はアイテムの編集を行います。 セル内のアイテムは、テキスト、その他のコントロール(CheckBoxChoiceBoxなど)、その他のNode(HBoxGridPaneなど)、またはRectangleで表されます。

    TreeView、ListView、TableView、および他のこのようなコントロールは、非常に大規模なデータの表示に使用される可能性があるため、コントロール内の単一アイテムごとに実際のセルを作成することは現実的ではありません。 少数のセルのみを使用して、非常に大規模なデータ・セットを表します。 各セルはリサイクル、つまり再利用されます。 これは、コントロールの仮想化が何を意味しているかを示します。

    セルはコントロールであるため、基本的にはモデルです。 そのスキンは、外観とレイアウトの定義を管理し、一方、動作はすべての入力イベントの処理、およびその情報を使用したコントロールの状態変更を行います。 また、他のコントロールと同様、セルはCSSからスタイル設定されます。 ただし、ほとんどセルの用途では、スキンを実装する必要はありません。 これは、セル・ファクトリを設定できるためであり、詳細は後述します。

    最も一般的なセルのユースケースは、ユーザーへのテキストの表示であるため、このユースケースはセル内で特に最適化されています。 これは、Labeledから拡張されたセルで実行されます。 これは、セルのサブクラスが、個別のLabelを作成し、それをセル内で設定するのではなく、textプロパティのみを設定する必要があることを意味します。 ただし、単なるプレーン・テキストではないものが呼び出される状況では、任意のNodeをセルのgraphicプロパティに配置できます。 グラフィックは、その名前とは異なり、任意のノードになることができ、完全に対話型です。 たとえば、ListCellは、そのグラフィックとしてButtonを使用して構成できます。 その後、このボタン・テキストをセルのitemプロパティにバインドできます。 このようにして、セル内のアイテムが変更されると、ボタン・テキストは自動的に更新されます。

    セルはfocusTraversableをfalseに設定します。

    セル・ファクトリ

    セルitemのデフォルト表現は、レンダリングする様々な仮想化コンテナのスキンによって異なります。 たとえば、ListViewはデフォルトでアイテムを文字列に変換し、この値を使用してLabeled.setText(java.lang.String)を呼び出します。 たとえば、ListViewに使用されるセルを特化する場合は、ListViewで定義されているcellFactoryコールバック関数の実装を指定する必要があります。 同様のAPIが、セルを使用するほとんどのコントロール(TreeViewTableViewTableColumnListViewなど)に存在します。

    セル・ファクトリは、プラットフォームが新しいセルを作成する必要があると判断すると、そのプラットフォームによって呼び出されます。 たとえば、ListViewに1000万のアイテムがあるとします。 1000万セルをすべて作成することは、負荷が非常に高いため、回避する必要があります。 このため、かわりにListViewスキンを実装することで、視覚的なスペースに収まる十分なセルのみを作成できます。 ListViewがサイズ変更されて大きくなると、システムは追加のセルを作成する必要があると判断します。 この場合、cellFactoryコールバック関数(提供されている場合)を呼び出して、使用する必要があるセル実装を作成します。 セル・ファクトリが提供されていない場合は、組込みのデフォルト実装が使用されます。

    この場合、セル・ファクトリの実装は、セル・インスタンスの作成だけでなく、セルの状態の変化に対応したセルの構成も行います。 たとえば、通貨型として表示されるように数値をフォーマットしたカスタム・セルを作成する場合は、次のようになります。

     public class MoneyFormatCell extends ListCell<Number> {
    
         public MoneyFormatCell() {    }
    
         @Override protected void updateItem(Number item, boolean empty) {
             // calling super here is very important - don't skip this!
             super.updateItem(item, empty);
    
             // format the number as if it were a monetary value using the
             // formatting relevant to the current locale. This would format
             // 43.68 as "$43.68", and -23.67 as "-$23.67"
             setText(item == null ? "" : NumberFormat.getCurrencyInstance().format(item));
    
             // change the text fill based on whether it is positive (green)
             // or negative (red). If the cell is selected, the text will
             // always be white (so that it can be read against the blue
             // background), and if the value is zero, we'll make it black.
             if (item != null) {
                 double value = item.doubleValue();
                 setTextFill(isSelected() ? Color.WHITE :
                     value == 0 ? Color.BLACK :
                     value < 0 ? Color.RED : Color.GREEN);
             }
         }
     }
    このクラスは、ListView内で次のように使用できます。
     ObservableList<Number> money = ...;
     final ListView<Number> listView = new ListView<Number>(money);
     listView.setCellFactory(new Callback<ListView<Number>, ListCell<Number>>() {
         @Override public ListCell<Number> call(ListView<Number> list) {
             return new MoneyFormatCell();
         }
     });
    この例では、呼び出されるとMoneyFormatCellのインスタンスを単に返す匿名内部クラスが作成されます。 MoneyFormatCellクラスはListCellを拡張し、updateItemメソッドをオーバーライドします。 このメソッドは、セル内のアイテムが変更されたり(ユーザーがListViewをスクロールした場合など)、基礎となるデータ・モデルのコンテンツが変更(およびListView内の異なるアイテムを表すためにセルが再利用)されると呼び出されます。 このため、バインディングを管理する必要ありません。単に、このメソッドが発生したときに、アイテムの変更に対応します。 前述の例では、アイテムが変更されると、常にセル・テキスト・プロパティが更新され、テキスト埋込みも変更されて、適切なビジュアルが得られるようにします。 また、セルが空の場合(つまり、ListViewのスペースを埋めるために使用されるが、関連付けられているデータがない場合)、空の文字列を単に使用します。

    関連する可能性のある、updateの接頭辞が付いた追加メソッドがあるため、セル、およびセルのサブクラスについてのAPIドキュメントをよく読んでください。

    updateメソッドをオーバーライドするのではなく、バインディングAPIを使用することもできます。 これを実現する方法の非常に簡単な例を次に示します。

     public class BoundLabelCell extends ListCell<String> {
    
         public BoundLabelCell() {
             textProperty().bind(itemProperty());
         }
     }
     

    主な設計の目標

    • 大規模なデータ・セットに対する時間とメモリーの高い効率を実現します。
    • カスタム・セルのライブラリの構築および使用を簡易化します。
    • セルのビジュアルを容易にカスタマイズできるようにします。
    • 表示フォーマットのカスタマイズを簡易化します(12.34を$12.34または1234%などとする)。
    • カスタム・ビジュアルへの拡張を簡易化します。
    • ビジュアルへのデータのパネルの追加を簡易化します。
    • セル・サイズまたはその他のプロパティのアニメーション化を簡易化します。

    主なユースケース

    次に、セルAPI設計の推進に使用される主な複数のユースケース、およびこれらのユースケースをこのAPIで実現する方法を示すコード例を示します。 これは、サポートされている機能の確定したリストではなく、セルAPIの使用方法のガイダンスとして提供しています。 次の例ではListViewに焦点を当てていますが、同じ原理がTreeCellsや他の種類のセルに適用されます。

    セルの色の変更

    これは、JavaFXでは非常に単純になっています。 各セルは、CSSから直接スタイル設定できます。 このため、たとえば、ListView内の各セルのデフォルトの背景を白に変更する場合、次のCSSを実行できます。

     .list-cell {
       -fx-padding: 3 3 3 3;
       -fx-background-color: white;
     }
    選択したListViewセルの色を青に設定する場合は、次の内容をCSSファイルに追加できます。
     .list-cell:selected {
       -fx-background-color: blue;
     }
    ほとんどのセル実装は、CellではなくIndexedCellから拡張されます。 IndexedCellは、その他の2つの擬似クラス状態(oddおよびeven)を追加します。 これを使用すると、CSSファイルで次のようなことを実行して、代替行ストライピングを取得できます。
     .list-cell:odd {
       -fx-background-color: grey;
     }
    これらの各例では、コードを変更する必要がありません。 CSSファイルを単に更新して、色を変えます。 他のコントロールと同様、CSSファイルでhoverおよびその他の擬似クラスを使用することもできます。

    前述の最初の例(数値のリストのフォーマット)に対する別のアプローチは、スタイル・クラスを使用することです。 ListViewに表示する数値のObservableListがあり、負の値はすべて赤で、正の値または0値はすべて黒で表示するとします。 これを実現する1つの方法は、値が負であるか正であるかに基づいて、CellのstyleClassを変更するカスタムcellFactoryを使用することです。 このことは、セル内の数値が負であるかどうかをテストするコードを追加したり、negativeのstyleClassを追加することと同様に単純です。 数値が負でない場合は、negative文字列を削除する必要があります。 このアプローチによって、色をCSSで定義でき、カスタマイズを簡素化できます。 この場合、CSSファイルには次のようなものが含まれます。

     .list-cell {
       -fx-text-fill: black;
     }
    
     .list-cell .negative {
       -fx-text-fill: red;
     }

    編集

    Cellアーキテクチャを使用するほとんどの仮想コントロール(ListViewTreeViewTableViewTreeTableViewなど)では、セルを介して値を直接編集する概念をサポートしています。 コントロール固有の詳細は、前述にリンクされているコントロールのクラスのドキュメントの「編集」の項を参照してください この項の残りの部分では、セルでの編集の詳細をいくつか説明します。

    編集の一般的なフローは、次のとおりです(これらのステップでは、ListViewコントロールが例として使用されていますが、同様のAPIは前述のすべてのコントロールに存在し、通常、プロセスは完全に同じです)。

    1. ユーザーはキーボードまたはマウス・コマンドを介して、セルが編集モードに入ることをリクエストし、開発者はメソッド(ListView editメソッドなど)を呼び出して、セルが編集モードに入ることをリクエストします。 注意: ユーザーがダブルクリックするか、適切なキーボード・コマンドを起動して編集を開始した場合は、実質的には、コントロールで適切な編集メソッドが呼び出されます(つまり、ユーザーが開始する編集と開発者が開始する編集のエントリ・メソッドは同じになります)。
    2. コントロールの表示リージョン内の各セルは、現在のediting cellが変更されたことが通知され、それがそのセル自体であるかどうかをチェックします。 この時点で、次の3つのいずれかが発生する可能性があります。
      1. 編集インデックスがセルと同じインデックスである場合は、このセルでstartEdit()が呼び出されます。 いくつかの指針を次に示します。
        1. CellのサブクラスがstartEdit()メソッドをオーバーライドして、編集状態に入ったときにセルのビジュアルを更新することをお薦めします。 ただし、startEdit()メソッドをオーバーライドするサブクラスは、引き続きsuper.startEdit()を呼び出すため、編集が成功するために必要な追加状態を親クラスが更新できることは非常に重要であることに注意してください。
        2. セルのビジュアルの変更は、startEdit()メソッド内で行うことが最適です。 たとえば(この例は、ListViewなどのUIコントロールのjavadocで、より具体的に示されています)、セルのLabeled.graphicProperty()TextFieldに設定し、Labeled.textProperty()をnullに設定します。 これにより、エンド・ユーザーは、入力したり、データ・モデルに変更を加えることができます。
        3. ユーザーは、編集を完了すると、変更をコミットするか、または取り消します。 このことはプログラミングで([Enter]キーで編集がcommitされるようにしたり、[Esc]キーで編集がcancelされるようにするなど)処理します。 これを実行するには、適切なイベント・リスナーを、編集状態中に表示するノードにアタッチします。
      2. 編集インデックスが、セルと同じインデックスではなく、セルが現在editing stateである場合、cancelEdit()がこのセルで呼び出されます。 startEdit()メソッドと同様、このメソッドをオーバーライドして、セルのビジュアルをクリーンアップし(また、ほとんどの場合Labeled.graphicProperty()をnullに戻し)、Labeled.textProperty()をその(新しい可能性がある)値に設定します。 また、必ずsuper.cancelEdit()を呼び出して、すべての状態が正しく更新されるようにしてください。
      3. 編集インデックスが、セルと同じインデックスではなく、セルが現在isEditing()編集状態でない場合、このセルでは何も発生しません。
    導入されたバージョン:
    JavaFX 2.0
    • プロパティの詳細

      • item

        public final ObjectProperty<T> itemProperty
        このCellに関連付けられているデータ値。 この値は、セルの作成または更新時に、仮想コントロールによって設定されます。 これは、RAWデータ値を表します。

        この値は、Cellクラスで適切に動作する方法を認識している仮想ユーザー・インタフェース・コントロールによって、Cellのサブクラスでのみ設定される必要があります。

        戻り値:
        このセルに関連付けられたデータ値
      • public final ReadOnlyBooleanProperty emptyProperty
        セルにコンテンツが含まれるかどうかを表すために使用されるプロパティ。 trueの場合、セルにはデータが含まれず、仮想コントロールのいずれのデータ・アイテムとも関連付けられていません。

        セルが空の場合、空のCSS擬似クラス状態を介して異なるスタイルを設定できます。 たとえば、代替行のハイライトを受け取らないようにしたり、カーソルを重ねたときにhoverの背景塗りつぶしを受け取らないようにできます。

        関連項目:
        isEmpty()
      • selected

        public final ReadOnlyBooleanProperty selectedProperty
        このセルが選択されたかどうかを示します。 たとえば、ListViewは、ゼロ以上のセルをselectedセルとして定義します。
        関連項目:
        isSelected()
      • editing

        public final ReadOnlyBooleanProperty editingProperty
        このセルが現在編集状態であるかどうかを表すプロパティ。
        関連項目:
        isEditing()
      • editable

        public final BooleanProperty editableProperty
        このセルを編集可能な状態にすることを許可するかどうかを表すプロパティ。 デフォルトでは、editableはCellでtrueに設定されます(ただし、編集状態に入ることが許可されているCellのサブクラスの場合は、追加の基準を満たす必要がある場合があります)。 たとえば、ListCellでは、ListViewのeditableプロパティもtrueである必要があります。
        関連項目:
        isEditable()setEditable(boolean)
    • コンストラクタの詳細

      • Cell

        public Cell​()
        デフォルトのスタイル・クラスcellを持つデフォルトのセルを作成します。
    • メソッドの詳細

      • itemProperty

        public final ObjectProperty<T> itemProperty​()
        このCellに関連付けられているデータ値。 この値は、セルの作成または更新時に、仮想コントロールによって設定されます。 これは、RAWデータ値を表します。

        この値は、Cellクラスで適切に動作する方法を認識している仮想ユーザー・インタフェース・コントロールによって、Cellのサブクラスでのみ設定される必要があります。

        戻り値:
        このセルに関連付けられたデータ値
      • setItem

        public final void setItem​(T value)
        アイテムを指定された値に設定しますが、アイテムは仮想コントロールで管理されているため、直接呼び出すことはできません。
        パラメータ:
        value - このセルに設定する新しいデータ値
      • getItem

        public final T getItem​()
        このセルに関連付けられているデータ値を返します。
        戻り値:
        このセルに関連付けられたデータ値
      • emptyProperty

        public final ReadOnlyBooleanProperty emptyProperty​()
        セルにコンテンツが含まれるかどうかを表すために使用されるプロパティ。 trueの場合、セルにはデータが含まれず、仮想コントロールのいずれのデータ・アイテムとも関連付けられていません。

        セルが空の場合、空のCSS擬似クラス状態を介して異なるスタイルを設定できます。 たとえば、代替行のハイライトを受け取らないようにしたり、カーソルを重ねたときにhoverの背景塗りつぶしを受け取らないようにできます。

        関連項目:
        isEmpty()
      • isEmpty

        public final boolean isEmpty​()
        セルが空であると思われるかどうかを表すブール値を返します。
        戻り値:
        セルが空の場合はtrue、そうでない場合はfalse
      • selectedProperty

        public final ReadOnlyBooleanProperty selectedProperty​()
        このセルが選択されたかどうかを示します。 たとえば、ListViewは、ゼロ以上のセルをselectedセルとして定義します。
        関連項目:
        isSelected()
      • isSelected

        public final boolean isSelected​()
        このセルが現在選択されているかどうかを返します。
        戻り値:
        セルが選択されている場合はtrue、そうでない場合はfalse。
      • isEditing

        public final boolean isEditing​()
        このセルが現在編集状態であるかどうかを表します。
        戻り値:
        このセルが現在編集状態にある場合はtrue、そうでない場合はfalse
      • editingProperty

        public final ReadOnlyBooleanProperty editingProperty​()
        このセルが現在編集状態であるかどうかを表すプロパティ。
        関連項目:
        isEditing()
      • setEditable

        public final void setEditable​(boolean value)
        特定のセルを編集不可にすることができます。 これは、リストにヘッダー行が含まれている場合などに役立ちます。ヘッダー行が編集可能である必要はないため、editableはfalseに設定される必要があります。
        パラメータ:
        value - セルが編集可能であるかどうかを表すブール値。 trueの場合、セルは編集可能で、falseの場合、セルは編集できません。
      • isEditable

        public final boolean isEditable​()
        このセルを編集可能な状態にすることを許可するかどうかを返します。
        戻り値:
        このセルが編集状態になることが許可されている場合はtrue、そうでない場合はfalse
      • editableProperty

        public final BooleanProperty editableProperty​()
        このセルを編集可能な状態にすることを許可するかどうかを表すプロパティ。 デフォルトでは、editableはCellでtrueに設定されます(ただし、編集状態に入ることが許可されているCellのサブクラスの場合は、追加の基準を満たす必要がある場合があります)。 たとえば、ListCellでは、ListViewのeditableプロパティもtrueである必要があります。
        関連項目:
        isEditable()setEditable(boolean)
      • startEdit

        public void startEdit​()
        この関数を呼び出して、セルが編集可能な場合に、非編集状態から編集状態に遷移します。 セルがすでに編集状態である場合は、その状態のままになります。
      • cancelEdit

        public void cancelEdit​()
        この関数を呼び出して、ユーザーによる入力を保存せずに、編集状態から非編集状態に遷移します。
      • commitEdit

        public void commitEdit​(T newValue)
        セル編集ユーザー・インタフェースのユーザー操作要件に基づいて適切な場合に、この関数を呼び出して、次の2つのことを実行します。
        1. 適切なイベントを起動してバッキングUIコントロール(ListViewなど)に戻します。 これにより、この編集をプッシュして関連データ・ソースやプロパティに戻すプロセスが開始されます(ただし、正常終了は保証されません。つまり、使用される特定の編集コミット・ハンドラに依存します)。 詳細は、UIコントロール・クラスのjavadocを参照してください。
        2. 編集状態から非編集状態への遷移を開始します。

        一般的に、カスタム・セル実装でこのメソッドをオーバーライドする必要はありません。必要に応じてこのメソッドを呼び出すのみで十分です(たとえば、ユーザーが[Enter]キーを押したときにcell.commitEdit(converter.fromString(textField.getText()));などを実行できます)。

        パラメータ:
        newValue - エンド・ユーザーが入力した値であり、ユーザー・インタフェースを支援するデータ・ソース、およびUIコントロールのインストール編集コミット・ハンドラで指定された関連する方法で保持される必要があります。
      • layoutChildren

        protected void layoutChildren​()
        このParentの子をレイアウトするレイアウト・パス中に起動されます。 デフォルトでは、管理対象のサイズ変更可能なコンテンツのサイズをその優先サイズに合せて設定するのみで、ノードの配置は行われません。

        サブクラスは必要に応じてこの関数をオーバーライドし、コンテンツをレイアウトする必要があります。

        オーバーライド:
        layoutChildren 、クラス: Control
      • updateItem

        protected void updateItem​(T item,
                                  boolean empty)
        updateItemメソッドは、開発者にとって、呼び出すことはできないが、オーバーライドしてセルのビジュアルをカスタマイズできる、最適なメソッドです。 つまり、開発者は、コードでこのメソッドを呼び出さないようにしてください。このメソッドは、ListViewコントロールなどのUIコントロールによってのみ呼び出されるようにする必要があります。 ただし、updateItemメソッドが存在する理由は、開発者がカスタム・セル・ファクトリ(ListView cell factoryなど)を指定するときに、updateItemメソッドをオーバーライドして、セルを完全にカスタマイズできるようにすることです。

        CellのサブクラスがupdateItemメソッドを適切にオーバーライドすることは非常に重要であり、これは、そのようにしないと、セルが空白になったり、セルに予期しないコンテンツが含まれるなどの問題が発生するためです。 updateItemメソッドを適切にオーバーライドする方法の例を次に示します。

         protected void updateItem(T item, boolean empty) {
             super.updateItem(item, empty);
        
             if (empty || item == null) {
                 setText(null);
                 setGraphic(null);
             } else {
                 setText(item.toString());
             }
         }
         

        このコード・サンプルには次の2つの重要なポイントがあることに注意してください。

        1. super.updateItem(T, boolean)メソッドを呼び出します。 これを行わないと、itemプロパティとemptyプロパティが正しく設定されず、グラフィカルな問題が発生する可能性があります。
        2. empty状態をテストし、trueの場合は、textプロパティとgraphicプロパティをnullに設定します。 これを行わないと、ほぼ確実に、エンド・ユーザーに対して予想外のグラフィカル・アーティファクトがセル内に表示されます。
        パラメータ:
        item - セルの新しいアイテム。
        empty - このセルがリストからのデータを表しているかどうか。 空の場合、いずれのドメイン・データも表しませんが、空の行のレンダリングに使用されるセルとなります。
      • updateSelected

        public void updateSelected​(boolean selected)
        このセルが選択状態であるかどうかを更新します。
        パラメータ:
        selected - このセルが選択されているかどうか。
      • isItemChanged

        protected boolean isItemChanged​(T oldItem,
                                        T newItem)
        このメソッドは、CPUの負荷が高い特定のアクション(具体的にはupdateItem(Object, boolean)を呼び出すアクション)が必要なときにのみ実行されるように、Cellサブクラスによって呼び出されます(つまり、現在設定されているitemが設定を提案される新しいアイテムと異なるとみなされた場合にのみ実行されます)。

        このメソッドのデフォルト実装では等価性のテストが行われますが、開発者はドメインに固有の他の方法でチェックを実行するようにこのメソッドをオーバーライドできます。

        パラメータ:
        oldItem - セルに含まれる、現在設定されているアイテム(getItem()を介して使用可能なアイテムと同じ)。
        newItem - このメソッドがtrueを返す場合にセル内に設定されるアイテム。 このメソッドがfalseを返す場合、これは設定されないことがあります。
        戻り値:
        新しいアイテムが古いアイテムと異なるとみなされた場合、trueを返します。 デフォルトでは、このメソッドは透過性のテストを行いますが、サブクラスによって、ニーズに適したテストが実行されるように実装が変更されることもあります。
        導入されたバージョン:
        JavaFX 8u40
      • getInitialFocusTraversable

        protected Boolean getInitialFocusTraversable​()
        このコントロールの初期フォーカス・トラバーサブル状態を返します。これは、JavaFX CSSエンジンが初期値を正しく設定するために使用します。 このメソッドはオーバーライドされます。既定のUIコントロールでは、フォーカス・トラバーサルがtrueに設定されていますが、このコントロールには適切ではありません。
        オーバーライド:
        クラスControlgetInitialFocusTraversable
        戻り値:
        このコントロールの最初のフォーカス・トラバーサル状態
        導入されたバージョン:
        9