忍者ブログ

軽Lab

 Javaを中心とした、プログラミング関係のナレッジベース

Home > JavaFX入門 > JavaFX セルのカスタマイズ

JavaFX セルのカスタマイズ

 リストや表など、一部のUIコントロールではセルのカスタマイズが可能になっている。セルをカスタマイズしたい場合は、Callbackインターフェースのcall関数をオーバーライドして戻り値をカスタマイズ後のセルとする。このCallbackインターフェースをsetCellFactory関数で登録することで、UIコントロール上にカスタマイズされたセルが表示される。カスタマイズできる代表的な操作を以下に示す。

  1. updateItem関数をオーバーロードし、セルの見た目を変更できる
  2. startEdit関数をオーバーロードし、セル編集開始時の動作を変更できる。commitEdit関数呼び出しで編集の確定、cancelEdit関数呼び出しで編集のキャンセルが可能

 また、セルをカスタマイズできるUIコントロールは以下のとおり。

UIコントロール 対応するセルのクラス
DatePicker DateCell
ComboBox ListCell
ListView ListCell
TreeView TreeCell
TableView TableCell
TableRow
TreeTableView TreeTableCell
TreeTableRow
※ChoiceBoxはセルのカスタマイズ不可

■ セルのカスタマイズ・例1(見た目の変更)

 以下に、セルをカスタマイズするためのサンプルプログラムを示す。サンプルではセルに画像を付与し、文字色を赤色にしている。

◇サンプルコード
package application_fx;

import java.io.File;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TestCellFactory extends Application {

    public static void main(String[] args) 
    {
        launch( args );
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        // シーングラフを作成
        VBox        root    = new VBox( 2.0 );
        
        // コンボボックス
        ComboBox<String>        combo   = new ComboBox<>();
        combo.setItems( FXCollections.observableArrayList( "その1" , "その2" , "その3" ) );
        combo.setEditable( true );
        root.getChildren().add( combo );
        
        // セル・ファクトリを作成
        Callback<ListView<String>,ListCell<String>> cellFactory = p -> 
        {
            // セルを作成
            ListCell<String>    cell    = new ListCell<String>()
            {
                /**
                 * 描画関数
                 * @param item
                 * @param empty
                 */
                @Override public void updateItem( String item , boolean empty )
                {
                    // 元関数を呼び出し
                    super.updateItem(item, empty);
                    
                    // Null対策
                    if( item == null ){ return; }

                    // セルのプロパティを設定
                    // テキスト
                    setText(item);
                    setTextFill( Color.RED );
                    
                    // 画像
                    String      url     = new File( "img/chara_one.png" ).toURI().toString();
                    Image       img     = new Image( url );
                    ImageView   imgView = new ImageView( img );
                    imgView.setFitWidth( 16 );
                    imgView.setFitHeight( 16 );
                    setGraphic( imgView );
                }

            };
            
            return cell;
        };
        combo.setCellFactory( cellFactory );
        
        // シーンを作成
        Scene       scene   = new Scene( root , 500 , 200 , Color.web( "9FCC7F" ) );
        
        // ウィンドウ表示
        primaryStage.setScene( scene );
        primaryStage.show();
    }


}
◇実行結果
  

◇解説
 38行目~70行目でCellFactoryとして登録するCallBack関数を設定している。関数内部では、ListCell::updateItem関数をオーバーロードした匿名クラスを作成・インスタンス化している。


■ セルのカスタマイズ・例2(編集機能を追加)

 以下に編集可能なセルを表示するサンプルコードを示す。

◇サンプルコード
package application_fx;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TestCellFactory2 extends Application {

    public static void main(String[] args) 
    {
        launch( args );
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        // シーングラフを作成
        VBox        root    = new VBox( 2.0 );
        
        // 編集可能なセルを作成するファクトリを定義
        Callback<ListView<String>,ListCell<String>> cellFactory = p -> new EditableCell();
        
        // リストビューを作成
        ListView<String>    listView    = new ListView<>();
        listView.setEditable( true );
        listView.setItems( FXCollections.observableArrayList( "その1" , "その2" , "その3" ) );
        listView.setCellFactory( cellFactory );
        //listView.setCellFactory( TextFieldListCell.forListView() );
        root.getChildren().add( listView );
        
        // シーンを作成
        Scene       scene   = new Scene( root , 500 , 200 , Color.web( "9FCC7F" ) );
        
        // ウィンドウ表示
        primaryStage.setScene( scene );
        primaryStage.show();
    }
    
    /**
     * 編集可能なセル
     * @author tomo
     *
     */
    class EditableCell extends ListCell<String>
    {
        private TextField   textField;
        
        public EditableCell(){}
        
        /**
         * 編集開始時の処理
         */
        @Override
        public void startEdit()
        {
            // 元関数を呼び出し
            super.startEdit();
            
            // 編集フィールドを作成
            textField   = new TextField( this.getItem() );
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
            
            // 編集用フィールドからフォーカスが外れた場合に
            // 編集内容を確定(commit)するようにリスナーを設定
            textField.focusedProperty().addListener(
                    ( ov , old , current ) ->
                    {   if( !current ){ commitEdit( textField.getText() );} }
            );
            
            // 表示を変更
            setText( null );
            setGraphic( textField );
            textField.selectAll();
        }
        
        /**
         * 編集破棄時の処理
         */
        @Override
        public void cancelEdit()
        {
            // 元関数を呼び出し
            super.cancelEdit();
            
            // 編集内容の破棄
            setText( this.getItem() );
            setGraphic( null );
        }
        
        /**
         * セルの更新時処理
         * @param item
         * @param empty
         */
        @Override
        public void updateItem( String item , boolean empty )
        {
            // 元関数を呼び出し
            super.updateItem(item, empty);
            
            // 空の場合
            if( empty )
            {
                setText( null );
                setGraphic( null );
                return;
                
            }

            // 編集中の場合
            if( isEditing() )
            {
                if( textField != null ){ textField.setText( toString() ); }
                setText( null );
                setGraphic( textField );
               return;
           }
            
            // その他の場合
            setText( this.getItem() );
            setGraphic( null );
            
        }
        
    }


}
◇実行結果
 

◇解説
 セル・ファクトリは28行目で設定しており、EditableCellクラスのインスタンスを返すだけの関数である。EditableCellクラスは51行目~131行目で宣言している。EditableCellクラスはListCellクラスを継承し、startEdit(61行目~81行目)・cancelEdit(87行目~95行目)・updateItem(103行目~129行目)の3関数をオーバーライドしている。startEdit関数では編集開始時の処理としてテキストフィールドを表示している。cancelEdit関数では表示を元に戻す処理を、updateItem関数では編集中に表示を変更するように処理している。

 ちなみに、今回はListCellを継承したクラスを作成したが、編集可能なセルはJavaで用意されており、TextFieldListCell.forListView関数(35行目)で取得することができる。同様にJavaであらかじめ用意されているCellクラスは以下のとおりである。それぞれに「クラス名.for○○」という静的(static)な関数が存在し、この関数を呼び出すことでsetCellFactory関数に渡すCallBackインスタンスを作成できる。

UIコントロール セルのクラス 内容
ComboBox
ListView
CheckBoxListCell 
ChoiceBoxListCell 
ComboBoxListCell 
TextFieldListCell 
セル内にチェックボックスを表示
編集モードの場合にChoiceBoxを表示
編集モードの場合にComboBoxを表示
編集モードの場合にTextFieldを表示
TreeView CheckBoxTreeCell 
ChoiceBoxTreeCell 
ComboBoxTreeCell 
TextFieldTreeCell 
セル内にチェックボックスを表示
編集モードの場合にChoiceBoxを表示
編集モードの場合にComboBoxを表示
編集モードの場合にTextFieldを表示
TableView CheckBoxTableCell 
ChoiceBoxTableCell 
ComboBoxTableCell 
ProgressBarTableCell 
TextFieldTableCell 
セル内にチェックボックスを表示
編集モードの場合にChoiceBoxを表示
編集モードの場合にComboBoxを表示
セル内にプログレス・バーを表示
編集モードの場合にTextFieldを表示
TreeTableView CheckBoxTreeTableCell 
ChoiceBoxTreeTableCell 
ComboBoxTreeTableCell 
ProgressBarTreeTableCell 
TextFieldTreeTableCell 
セル内にチェックボックスを表示
編集モードの場合にChoiceBoxを表示
編集モードの場合にComboBoxを表示
セル内にプログレス・バーを表示
編集モードの場合にTextFieldを表示

■ 参照

Home > JavaFX入門 > JavaFX セルのカスタマイズ

- ランダム記事 -
- PR -

コメント

プロフィール

管理者:
 連絡はContactよりお願いします。

PR