Eclipse+JSF+JPAで作るアプリ(12)―Primefaces テーマの変更

今回は、Primefacesのテーマの変更です。
PrimefacesのThemeSwitcherというコンポーネントを使います。
PrimeFaces ShowCaseで紹介されています。
Advancedのサムネイルが表示されているほうを試しましたがうまく動作しませんでしたのでBasicで実装しています。

今回の実装を終えると、以下のようにテーマをユーザーごとに保存できるようになります。
f:id:tshix:20150726205617p:plain
f:id:tshix:20150726205629p:plain
f:id:tshix:20150726205638p:plain

今回のセッションでは、以下が分かると思います。

  • テーマを動的に変える方法
  • DBに保存したテーマをどうロードするか?

次回は、ユーザ一覧の複数行選択しての削除、グリッドでの編集を実装する予定です。

Primefaceのテーマのダウンロード

  1. Index of /org/primefaces/themes/all-themesから、All-themesをダウンロードします。バージョンは最新(2015/7現在1.0.10)でよいでしょう。
  2. WebContent/WEB-INF/libの下にコピーします。

データベースのテーブル変更

ユーザーにテーマを保存するフィールドを足します。
SQL Server Management Stdioで、GUIから追加してやります。ツリー上でテーブルの列を選び右クリックメニューの「新しい列」から追加できます。
f:id:tshix:20150726212011p:plain

Userの変更

増やしたカラムに対応したフィールドを追加します。

User.javaの変更

	@Column(name="THEME")
	@Getter @Setter
	private String theme;

クラス名をユーザではなく、会員(Member)に変更したくなってきています。

changeTheme.xhtmlの作成

editUser.xhtmlをコピーし、ui:includeのインポート先を/content/theme.xhtmlに変更します。

changeTheme.xhmtlの内容

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:p="http://primefaces.org/ui">

<ui:composition template="./template/mainTemplate.xhtml">
	<ui:define name="content">
		<ui:include src="./content/theme.xhtml"></ui:include>
	</ui:define>
</ui:composition>

</html>

theme.xhtmlの作成

現在選択されているテーマ、テーマのコンボボックス(ThemeSwitcher)の2つのフィールドを持つビューを定義します。
「適用」ボタンで、テーマを保存するメソッドを1つ追加します。
JSFの開発では、画面、アクションでビューを定義していくことが多いような気がします。

theme.xhtmlの内容

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:p="http://primefaces.org/ui">

<h2>テーマ変更</h2>
<h:form id="changeThemeForm">
	<p:growl showDetail="true" autoUpdate="true" />
	<h:panelGrid columns="2" cellpadding="10">
		<p:outputLabel for="currenttheme" value="現在のテーマ:" />
		<p:outputLabel id="currenttheme" value="#{sessionInfo.loginUser.theme}" />
		
		<p:outputLabel for="changetheme" value="テーマの選択:" />
		<p:themeSwitcher id="changetheme" effect="fold"
			value="#{changeThemeView.selectedTheme}">
			<f:selectItems value="#{changeThemeView.themes}" />
		</p:themeSwitcher>
	</h:panelGrid>
	<p:commandButton value="適用" action="#{changeThemeView.saveTheme}" update=":changeThemeForm:currenttheme"/>

</h:form>
</html>

ChangeThemeViewの作成

最後にビューです。上記の通り、selectedTheme, themesフィールドと saveTheme()メソッドを持たせます。

ChangeThemeView.javaの内容

package sample.yourlibrary.view;

import java.util.TreeMap;

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

import lombok.Getter;
import lombok.Setter;
import sample.yourlibrary.entity.User;
import sample.yourlibrary.logic.UserManager;

@ManagedBean(name="changeThemeView")
@ViewScoped
public class ChangeThemeView {
	@Getter @Setter
	private String selectedTheme;
	
	@Getter @Setter
	private TreeMap<String, String> themes;
	
	@PostConstruct
	public void init()
	{
        themes = new TreeMap<String, String>();
        themes.put("Afterdark", "afterdark");
        themes.put("Afternoon", "afternoon");
        themes.put( "Afterwork", "afterwork");
        themes.put( "Aristo", "aristo");
        themes.put( "Black-Tie", "black-tie");
        themes.put( "Blitzer", "blitzer");
        themes.put( "Bluesky", "bluesky");
        themes.put( "Bootstrap", "bootstrap");
        themes.put( "Casablanca", "casablanca");
        themes.put( "Cupertino", "cupertino");
        themes.put( "Cruze", "cruze");
        themes.put( "Dark-Hive", "dark-hive");
        themes.put( "Delta", "delta");
        themes.put( "Dot-Luv", "dot-luv");
        themes.put( "Eggplant", "eggplant");
        themes.put( "Excite-Bike", "excite-bike");
        themes.put( "Flick", "flick");
        themes.put( "Glass-X", "glass-x");
        themes.put( "Home", "home");
        themes.put( "Hot-Sneaks", "hot-sneaks");
        themes.put( "Humanity", "humanity");
        themes.put( "Le-Frog", "le-frog");
        themes.put( "Midnight", "midnight");
        themes.put( "Mint-Choc", "mint-choc");
        themes.put( "Overcast", "overcast");
        themes.put( "Pepper-Grinder", "pepper-grinder");
        themes.put( "Redmond", "redmond");
        themes.put( "Rocket", "rocket");
        themes.put( "Sam", "sam");
        themes.put( "Smoothness", "smoothness");
        themes.put( "South-Street", "south-street");
        themes.put( "Start", "start");
        themes.put( "Sunny", "sunny");
        themes.put( "Swanky-Purse", "swanky-purse");
        themes.put( "Trontastic", "trontastic");
        themes.put( "UI-Darkness", "ui-darkness");
        themes.put( "UI-Lightness", "ui-lightness");
        themes.put( "Vader", "vader");
        
        selectedTheme = ViewUtil.getSessionInfo().getLoginUser().getTheme();
	}
	
	public String saveTheme()
	{
		SessionInfo sessionInfo = ViewUtil.getSessionInfo();
		User loginUser = sessionInfo.getLoginUser();
		loginUser.setTheme(selectedTheme);
		UserManager.updateUser(loginUser);
		ViewUtil.AddMessage("テーマ変更", "選択されたテーマを適用しました。");
		return "success";
	}
}

web.xmlでのEL式

EL式について説明するのを忘れていました。Expression Languageの略で、基本的には #{ビーン名.メソッド名orフィールド名}で表現しアクセスすることができる式です。not empty、= trueなど「式」としても使用することができます。

Primefacesのテーマは、primefaces.THEMEというコンテキストパラメータで変わります。

web.xmlの変更

  <context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>#{sessionInfo.theme}</param-value>
  </context-param>

SessionInfo(セッションスコープのManagedBean)の変更

テーマの取得時には、ログインしていないorテーマを設定していない可能性があるため、以下のように実装しています。

SessionInfo.javaの変更

	public String getTheme()
	{
		if( loginUser == null || loginUser.getTheme().length() == 0 )
			return "aristo";
		return loginUser.getTheme();
	}

以上で、テーマ変更を動的に変更しDBに保存するところまでの実装を終わります。