読者です 読者をやめる 読者になる 読者になる

Challenge Java EE !

Java EEを中心に趣味や仕事における開発メモを書いています。

PrimeFacesのDataTableを探る ~DynamicColumn~

NetBeans PrimeFaces JSF DataTable

業務系のシステムって、どうして一覧で色々なことをしたがるのだろうか…(お客様だけでなく、身内の設計者含めて)(-_-;と思う今日この頃。

Windows Formで開発をしていた頃も、GrapeCityさんのMultiRowにお世話になったりしたのですが、標準のテーブルコンポーネントはどんなことができて、サードバーティやOSS使うと、さらにどんなことができるようになるのか?

こうしたことは設計段階で把握しておくことが大事だよなぁと思います。

そんなこんな思いつつ、今日からPrimeFacesのDataTableを色々探る(不定期)連載みたいなことしようかなと思います。

実際の開発でも利用しているのですが、PrimeFacesのDataTableはかなり色々なことができるので、少しでも参考になれば幸いです(^^;

まずPrimeFacesを使う環境を整える必要がありますが、過去に書いた以下エントリで最低限の手順をまとめてます。

NetBeansで始める初めてのPrimeFaces ~Maven編~

現時点ですとバージョン3.5が最新です。

一覧に出すデータはデータベースから取得することが多いと思うので、以下の手順で準備しました。ちょっと準備が長いです(^^;

書籍テーブルを準備

DBはNetBeansにバンドルされたJava DBを用いた例で書きます。
もちろん他のDBでも全然問題ないです(^^;
カラムはすごく雑ですがID,TITLE,AUTHOR,CREATE_DATEとかにしました。

f:id:kikutaro777:20130325221628j:plain

雑すぎる…(^^;

パッケージを準備

ソースパッケージとして以下4つを作ります。

  • bean … BackingBean(管理対象Bean)を格納
  • db … データベース操作のクラスを格納
  • entity … Entityクラスを格納
  • ui … 画面コンポで使うクラスを格納

一応、階層設けて以下のような感じに。

f:id:kikutaro777:20130325221710j:plain

Entityを自動生成

Entityのパッケージを右クリックして「新規」->「その他」から「持続性」「データベースからのエンティティ・クラス」を選択して、あとは次へで進みます。

f:id:kikutaro777:20130325221738j:plain
f:id:kikutaro777:20130325221743j:plain

Entityクラスができました。

f:id:kikutaro777:20130325221754j:plain

NetBeansで自動生成されたコードは以下のようなものです。

package jp.co.hoge.entity;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(name = "BOOK")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Book.findAll", query = "SELECT b FROM Book b"),
    @NamedQuery(name = "Book.findById", query = "SELECT b FROM Book b WHERE b.id = :id"),
    @NamedQuery(name = "Book.findByTitle", query = "SELECT b FROM Book b WHERE b.title = :title"),
    @NamedQuery(name = "Book.findByAuthor", query = "SELECT b FROM Book b WHERE b.author = :author"),
    @NamedQuery(name = "Book.findByCreateDate", query = "SELECT b FROM Book b WHERE b.createDate = 

:createDate")})
public class Book implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 128)
    @Column(name = "ID")
    private String id;
    @Size(max = 512)
    @Column(name = "TITLE")
    private String title;
    @Size(max = 256)
    @Column(name = "AUTHOR")
    private String author;
    @Column(name = "CREATE_DATE")
    @Temporal(TemporalType.DATE)
    private Date createDate;

//setter,getter,hashCode,equalsなどは省略
DBの処理クラスを自動生成

dbパッケージを右クリックして「新規」->「その他」から「持続性」「エンティティ・クラスのセッションBean」を選択して、あとはEntityを選択後、次へで進みます。

f:id:kikutaro777:20130325221821j:plain
f:id:kikutaro777:20130325221828j:plain

AbstractFacadeとBookFacadeクラスができました。

f:id:kikutaro777:20130325221833j:plain

JSF管理対象Beanクラスを生成

beanパッケージを右クリックして「新規」->「その他」から「JavaServer Faces」「JSF管理対象Bean」を選択します。

f:id:kikutaro777:20130325221850j:plain

名前は「BookBean」とかにして、スコープは「view」を選びます。

f:id:kikutaro777:20130325221900j:plain

以下、自動生成されたコードです。

package jp.co.hoge.bean;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class BookBean {

    public BookBean() {
    }
}

とりあえず、このまま置いておきます。

Dynamic Column用のクラスを定義

初回の今日は、Dynamic Columnを使います。

PrimeFacesのDataTableで一番シンプルなのは、JSFのビューで1つ1つカラムを記述するものです。以下のShowcaseからxhtmlが見れます。

Dynamic Columnはこのカラムを動的に生成できる仕組みで、柔軟性が上がります。

ここでは、まず、以下のようなColumnModelクラスを定義します。

package jp.co.hoge.ui;

import java.io.Serializable;

public class ColumnModel implements Serializable{
    private String header;
    private String property;
    
    public ColumnModel(String header, String property){
        this.header = header;
        this.property = property;
    }

    public String getHeader() {
        return header;
    }

    public String getProperty() {
        return property;
    }
}

カラムのヘッダ名称と、プロパティ(属性名)を定義するようなクラスです。
これがカラムの基本情報となります。

では、JSF管理対象Beanを書いてみましょう。
今回のサンプルは以下のようなものです。

package jp.co.hoge.bean;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import jp.co.hoge.db.BookFacade;
import jp.co.hoge.entity.Book;
import jp.co.hoge.ui.ColumnModel;

@ManagedBean
@ViewScoped
public class BookBean {
    
    //書籍エンティティのリスト
    private List<Book> bookList;
    
    //DataTableのカラムリスト
    private List<ColumnModel> columns;
    
    //DB操作
    @EJB
    BookFacade bookFacade;

    /**
     * コンストラクタ
     */
    @PostConstruct
    public void init(){
        //全件取得
        bookList = bookFacade.findAll();
        
        //カラム生成
        columns = new ArrayList<>();
        createDynamicColumns();
    }
    
    /**
     * カラム生成
     */
    public void createDynamicColumns(){
        columns.clear();
        
        //ヘッダとエンティティの属性である変数名を記述
        columns.add(new ColumnModel("書籍タイトル", "title"));
        columns.add(new ColumnModel("著者", "author"));
    }

    //getter,setter
    
    public List<Book> getBookList() {
        return bookList;
    }

    public void setBookList(List<Book> bookList) {
        this.bookList = bookList;
    }

    public List<ColumnModel> getColumns() {
        return columns;
    }

    public void setColumns(List<ColumnModel> columns) {
        this.columns = columns;
    }
}

エラー処理とか細かいのは省きます(^^;

JSFのビュー(とりあえずindex.xhtmlに書いてしまいます)は

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form id="dtFrm">
            <p:dataTable id="dt" var="book" value="#{bookBean.bookList}" >
                <p:columns id="colBook" var="col" value="#{bookBean.columns}">
                    <f:facet name="header">
                        #{col.header}
                    </f:facet>
                    <h:outputText value="#{book[col.property]}" />
                </p:columns>
            </p:dataTable>
        </h:form>
    </h:body>
</html>

Dynamic Columnではこのように、columnsタグを用いて記述し、各カラムに関する情報はviewの定義上は含まれません。

そして上記のようにEntityのプロパティで紐づきが行われて一覧に値が表示されます。

実行すると(デフォルトだと文字とかテーブルがでかいです)
f:id:kikutaro777:20130325222821j:plain
と、カラムとデータが表示されました。

とりあえず今日はこれくらいにして、ここから色々触っていこうと思いますー。
が、ホント不定期になると思います(^^;

にほんブログ村 IT技術ブログへ
にほんブログ村
にほんブログ村 IT技術ブログ Javaへ
にほんブログ村