Skip to content

8. Wprowadzenie do Primefaces Mobile

8.1. Rola Primefaces Mobile w aplikacji JSF

Wróćmy do architektury aplikacji Primefaces, którą omówiliśmy na początku tego dokumentu:

Gdy docelowym urządzeniem jest przeglądarka telefonu komórkowego, musimy zmienić sposób prezentacji. Należy bowiem uwzględnić rozmiar ekranu smartfona i na nowo przemyśleć ergonomię stron. Istnieją biblioteki specjalizujące się w tworzeniu stron internetowych dla urządzeń mobilnych. Tak jest w przypadku biblioteki Primefaces Mobile, która sama opiera się na bibliotece JQuery Mobile.

Architektura aplikacji internetowej na urządzenia mobilne będzie identyczna jak poprzednio, z tą różnicą, że oprócz bibliotek JSF i Primefaces wykorzystamy bibliotekę Primefaces mobile (PFM).

Omówimy wszystkie zagadnienia, które przerobiliśmy w ramach modułu JSF oraz Primefaces. Zmianie ulegnie jedynie warstwa [présentation] (głównie strony).

8.2. Możliwości Primefaces Mobile

Strona internetowa Primefaces Mobile

[http://www.primefaces.org/showcase-labs/mobile/showcase.jsf?javax.faces.RenderKitId=PRIMEFACES_MOBILE]

zawiera listę komponentów, które można wykorzystać na stronie PFM [1, 2]:

Można skorzystać z symulatorów smartfonów, aby wyświetlić powyższą aplikację demonstracyjną. Jeden z nich jest dostępny dla iPhone'a 4 pod adresem URL [http://iphone4simulator.com/] [3]. Wystarczy wpisać adres testowanej aplikacji w [4], a zostanie ona wyświetlona w rozmiarze dostosowanym do iPhone'a. Takie symulatory są przydatne na etapie tworzenia aplikacji, jednak ostatecznie aplikację należy przetestować w rzeczywistych warunkach na różnych urządzeniach mobilnych.

8.3. Nauka korzystania z Primefaces Mobile

PrimeFaces Mobile oferuje znacznie mniej komponentów niż PrimeFaces. Strona PrimeFaces Mobile

[http://www.primefaces.org/showcase-labs/mobile/showcase.jsf?javax.faces.RenderKitId=PRIMEFACES_MOBILE]

zawiera ich listę. Oto na przykład komponenty, których można używać w formularzu [1], [2], [3]:

Można pobrać kod źródłowy przykładów [4]. W ten sposób dowiadujemy się, że strona PFM, na której wyświetlane są powyższe komponenty [1], [2], [3], wygląda następująco:


<?xml version="1.0" encoding="windows-1250"?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:p="http://primefaces.org/ui"
        xmlns:pm="http://primefaces.org/mobile"
        contentType="text/html">

    <pm:page title="Components">
        <!-- Formularze -->
        <pm:view id="forms">
            <pm:header title="Forms">
                <f:facet name="left"><p:button value="Back" icon="back" href="#main?reverse=true"/></f:facet>
            </pm:header>
            <pm:content>
                <p:inputText label="Input:" />   
                <p:inputText label="Search:" type="search"/>
                <p:inputText label="Phone:" type="tel"/>
                <p:inputTextarea id="inputTextarea" label="Textarea:"/>
                <pm:field>
                    <h:outputLabel for="selectOneMenu" value="Dropdown: "/>
                    <h:selectOneMenu id="selectOneMenu">
                        <f:selectItem itemLabel="Select One" itemValue="" />
                        <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                        <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                        <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                    </h:selectOneMenu>
                </pm:field>
                <pm:inputRange id="range" minValue="0" maxValue="100" label="Range:" />
                <pm:switch id="switch" onLabel="yes" offLabel="no" label="Switch:" />
                <p:selectBooleanCheckbox id="booleanCheckbox" value="false" itemLabel="I agree" label="Checkbox"/>
                <p:selectManyCheckbox id="checkbox" label="Checkboxes: ">
                    <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                    <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                    <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                </p:selectManyCheckbox>
                <p:selectOneRadio id="radio" label="Radios: ">
                    <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                    <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                    <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                </p:selectOneRadio>
            </pm:content>
        </pm:view>
    </pm:page>
</f:view>
  • wiersz 7: pojawia się nowa przestrzeń nazw – przestrzeń nazw komponentów PrimeFaces Mobile o prefiksie pm,
  • wiersz 10: definiuje stronę. Strona będzie składać się z kilku widoków (wiersz 12). W danym momencie widoczny jest tylko jeden widok. Jest to koncepcja, z której szeroko korzystaliśmy w naszych przykładach dotyczących Primefaces – pojedyncza strona z wieloma fragmentami, które można wyświetlać lub ukrywać. Tutaj nie będziemy musieli tego robić. Po prostu wskażemy widok, który ma być wyświetlony, a pozostałe będą z konieczności ukryte,
  • wiersz 12: widok,
  • wiersze 13–15: definiują nagłówek widoku:


<pm:header title="Forms">
    <f:facet name="left"><p:button value="Back" icon="back" href="#main?reverse=true"/></f:facet>
</pm:header>
  

Warto zwrócić uwagę na tag służący do wygenerowania przycisku. Atrybut href umożliwia nawigację. Jego wartość to tutaj nazwa widoku. Kliknięcie przycisku spowoduje powrót (reverse=true) do widoku o nazwie main (nieprzedstawionego tutaj).

  • wiersz 16: wprowadza zawartość widoku,
  • wiersz 17: generuje pole wprowadzania danych:

                <p:inputText label="Input:" />
  
  • wiersz 18: pole wprowadzania danych z określoną ikoną:

                <p:inputText label="Search:" type="search"/>
  
  • wiersz 19: pole wprowadzania numeru telefonu:

                <p:inputText label="Phone:" type="tel"/>
  

Atrybut „type” tagu <inputText> ma określone znaczenie: określa on typ klawiatury, która zostanie wyświetlona użytkownikowi do wprowadzenia danych. Tak więc dla typu „tel” zostanie wyświetlona klawiatura numeryczna,

  • wiersz 20: wielowierszowe i rozszerzalne pole wprowadzania danych:

                <p:inputTextarea id="inputTextarea" label="Textarea:"/>
  
  • wiersze 21–29: pole zawierające kilka elementów:

                <pm:field>
                    <h:outputLabel for="selectOneMenu" value="Dropdown: "/>
                    <h:selectOneMenu id="selectOneMenu">
                        <f:selectItem itemLabel="Select One" itemValue="" />
                        <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                        <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                        <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                    </h:selectOneMenu>
</pm:field>
 
  • wiersz 2: nazwa elementu z wiersza 3;
  • wiersz 3: lista rozwijana;
  • wiersze 4–7: jej zawartość,
  • wiersz 30: suwak:

                <pm:inputRange id="range" minValue="0" maxValue="100" label="Range:" />
  
  • wiersz 31: przycisk z dwiema wartościami:

                <pm:switch id="switch" onLabel="yes" offLabel="no" label="Switch:" />
 
  • wiersz 32: pole wyboru:

      <p:selectBooleanCheckbox id="booleanCheckbox" value="false" itemLabel="I agree" label="Checkbox"/>
  
  • wiersze 33–37: grupa pól wyboru:

                  <p:selectManyCheckbox id="checkbox" label="Checkboxes: ">
                    <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                    <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                    <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                </p:selectManyCheckbox>
  
  • wiersze 38–42: grupa przycisków opcji

                    <p:selectOneRadio id="radio" label="Radios: ">
                    <f:selectItem itemLabel="Option 1" itemValue="Option 1" />
                    <f:selectItem itemLabel="Option 2" itemValue="Option 2" />
                    <f:selectItem itemLabel="Option 3" itemValue="Option 3" />
                </p:selectOneRadio>
  

Warto zauważyć, że strona wykorzystuje tagi z trzech bibliotek: JSF, PF oraz PFM. Mamy już wystarczającą wiedzę, aby stworzyć nasz pierwszy projekt mobilny w Primefaces.

8.4. Pierwszy projekt mobilny Primefaces: mv-pfm-01

Wykorzystamy omówiony wcześniej przykład, aby zintegrować go z projektem Maven. W ten sposób poznamy zależności niezbędne dla projektu mobilnego Primefaces.

8.4.1. Projekt NetBeans

Projekt NetBeans wygląda następująco:

Projekt NetBeans jest początkowo podstawowym projektem internetowym opartym na Maven, do którego dodano zależności [2]. W pliku [pom.xml] przekłada się to na następujący kod:


<dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-impl</artifactId>
      <version>2.1.8</version>
    </dependency>
    <dependency>
      <groupId>org.primefaces</groupId>
      <artifactId>primefaces</artifactId>
      <version>3.2</version>
    </dependency>
    <dependency>
      <groupId>org.primefaces</groupId>
      <artifactId>mobile</artifactId>
      <version>0.9.1</version>
      <type>jar</type>
    </dependency>
  </dependencies>
  <repositories>
    <repository>
      <url>http://download.java.net/maven/2/</url>
      <id>jsf20</id>
      <layout>default</layout>
      <name>Repository for library Library[jsf20]</name>
    </repository>
    <repository>
      <url>http://repository.primefaces.org/</url>
      <id>primefaces</id>
      <layout>default</layout>
      <name>Repository for library Library[primefaces]</name>
    </repository>
  </repositories>

W wierszach 11–16 znajduje się zależność od Primefaces Mobile. W tym przypadku wybraliśmy wersję 0.9.1 (wiersz 14). Ponadto zastosowaliśmy wersję 3.2 biblioteki Primefaces (wiersz 9). Numery tych wersji są istotne. Napotkałem bowiem sporo problemów z biblioteką PFM, która nie jest wersją ostateczną. Przez pewien czas istniała wersja 0.9.2, która zawierała błędy. Została ona już wycofana. Powrócono do wersji 0.9.1. Projekt PFM uległ zatem regresji. Testy zakończyły się niepowodzeniem również w przypadku wersji 1.0-SNAPSHOT, będącej częścią tworzonej obecnie wersji 1.0 (początek czerwca 2012 r.).

Strona główna [index.xhtml] [1] jest stroną demonstracyjną komponentów PrimeFaces Mobile:


<?xml version="1.0" encoding="windows-1250"?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:p="http://primefaces.org/ui"
        xmlns:pm="http://primefaces.org/mobile"
        contentType="text/html">

  <pm:page title="Components">

    <!-- Widok główny -->
    <pm:view id="main">
      ...
    </pm:view>

    <!-- Formularze -->
    <pm:view id="forms">
      ...
    </pm:view>


    <!-- Przyciski -->
    <pm:view id="buttons">
      ...
    </pm:view>

    ...
  </pm:page>
</f:view>

Istnieje jedna strona (wiersz 10) złożona z dwunastu widoków. Nie będziemy ich szczegółowo omawiać. Celem jest tutaj po prostu pokazanie, jak zbudować projekt PrimeFaces Mobile.

Uruchommy ten projekt. Pojawi się strona błędu [1]:

Powodem tego jest fakt, że aplikacja mobilna Primefaces musi być wywoływana z parametrem [?javax.faces.RenderKitId=PRIMEFACES_MOBILE], tak jak w przypadku [2]. Można pominąć ten parametr, modyfikując plik [faces-config.xml] (lub tworząc go, jeśli nie istnieje, jak w tym przypadku) [3]:

Jego zawartość jest następująca:


<?xml version='1.0' encoding='UTF-8'?>

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="2.0"
              xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">

  <application>
    <default-render-kit-id>PRIMEFACES_MOBILE</default-render-kit-id>
  </application>
</faces-config>
  • wiersz 11: ustawia wartość parametru [javax.faces.RenderKitId].

Po uruchomieniu otrzymujemy tę samą stronę co poprzednio, ale bez konieczności podawania parametrów URL i [4]. Testowanie tej aplikacji pozostawiamy czytelnikowi. Można w niej dostrzec błędy: tag <p:selectManyCheckbox> nie wyświetla się, podobnie jak tag <p:selectOneRadio>, a tag <pm:range> nie działa. Te nieprawidłowości, których nie ma na stronie demonstracyjnej, sugerują, że aplikacja nie działa z zastosowaną tutaj kombinacją Primefaces Mobile 0.9.1 i Primefaces 3.2. Jest to jednak punkt wyjścia do zapoznania się z tagami tej biblioteki, która jest w trakcie tworzenia.

Aby uzyskać bardziej realistyczny efekt, można przetestować aplikację na symulatorze, takim jak ten dla iPhone'a 4 [http://iphone4simulator.com/]. Otrzymujemy następujący wynik:

Wpisujemy [5], czyli ten sam identyfikator URL, który został użyty przez poprzednią przeglądarkę w [4].

8.5. Przykład mv-pfm-02: formularz i model

W tym projekcie pokazujemy interakcje między stroną Primefaces Mobile a jej modelem. Interakcje te są zgodne z zasadami frameworka JSF, na którym ostatecznie opiera się Primefaces Mobile.

8.5.1. Widoki

W projekcie występują dwa widoki

  • widok 1 [1] zawiera formularz, który można zatwierdzić w widoku [2],
  • widok 2 [3] potwierdza wprowadzone dane i umożliwia powrót do formularza [4].

Projekt pokazuje dwie rzeczy:

  • związek między stroną a jej szablonem,
  • nawigację między widokami strony.

8.5.2. Projekt NetBeans

Projekt NetBeans wygląda następująco:

  • w [1], strona mobilna PrimeFaces,
  • w [2] – jej szablon
  • w [3] – pliki komunikatów, ponieważ aplikacja jest zinternacjonalizowana,
  • w [4] – zależności projektu.

8.5.3. Konfiguracja projektu

Podajemy pliki konfiguracyjne bez ich wyjaśniania. Są one obecnie standardowe.

[web.xml]: konfiguruje aplikację internetową:


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

[faces-config.xml]: konfiguruje aplikację JSF:


<?xml version='1.0' encoding='UTF-8'?>

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="2.0"
              xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">

  <application>
    <resource-bundle>
      <base-name>
        messages
      </base-name>
      <var>msg</var>
    </resource-bundle>
    <message-bundle>messages</message-bundle>
    <default-render-kit-id>PRIMEFACES_MOBILE</default-render-kit-id>
  </application>
</faces-config>

[messages_fr.properties]: plik z komunikatami w języku francuskim:


forms=Formulaire
input=Saisie de texte
textarea=Saisie multi-lignes
dropdown=Liste d\u00e9roulante
range=Slider
switch=Switch
checkbox=Case \u00e0 cocher
checkboxes=Cases \u00e0 cocher
radios=Boutons radio
valider=Valider
confirmations=Confirmations
back=Retour

8.5.4. Strona Primefaces mobile

Strona [index.xhtml] wygląda następująco:


<?xml version="1.0" encoding='UTF-8'?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:p="http://primefaces.org/ui"
        xmlns:pm="http://primefaces.org/mobile"
        contentType="text/html">

  <pm:page title="mv-pfm-02">

    <!-- widok Forms -->
    <pm:view id="forms" swatch="b">
      <pm:header title="#{msg['forms']}"/>
      <pm:content>
        <h:form id="formulaire">
          <p:inputText id="inputText" label="#{msg['input']}" value="#{form.inputText}"/>
          <p:inputTextarea id="inputTextArea" label="#{msg['textarea']}" value="#{form.inputTextArea}"/>
          <pm:field>
            <h:outputLabel for="selectOneMenu" value="#{msg['dropdown']}"/>
            <h:selectOneMenu id="selectOneMenu" value="#{form.selectOneMenu}">
              <f:selectItem itemLabel="Option 1" itemValue="1" />
              <f:selectItem itemLabel="Option 2" itemValue="2" />
              <f:selectItem itemLabel="Option 3" itemValue="3" />
            </h:selectOneMenu>
          </pm:field>
          <pm:inputRange id="range" minValue="0" maxValue="100" label="#{msg['range']}" value="#{form.range}"/>
          <pm:switch id="switch" onLabel="yes" offLabel="no" label="#{msg['switch']}" value="#{form.bswitch}"/>
          <p:selectBooleanCheckbox id="booleanCheckbox" itemLabel="I agree" label="#{msg['checkbox']}" value="#{form.booleanCheckbox}"/>
          <pm:field>
            <h:outputLabel for="manyCheckbox" value="#{msg['checkboxes']}"/>
            <h:selectManyCheckbox id="manyCheckbox" value="#{form.manyCheckbox}">
              <f:selectItem itemLabel="Option 1" itemValue="1" />
              <f:selectItem itemLabel="Option 2" itemValue="2" />
              <f:selectItem itemLabel="Option 3" itemValue="3" />
            </h:selectManyCheckbox>
          </pm:field>
          <pm:field>
            <h:outputLabel for="radio" value="#{msg['radios']}"/>
            <h:selectOneRadio id="radio" value="#{form.radio}">
              <f:selectItem itemLabel="Option 1" itemValue="1" />
              <f:selectItem itemLabel="Option 2" itemValue="2" />
              <f:selectItem itemLabel="Option 3" itemValue="3" />
            </h:selectOneRadio>
          </pm:field>
          <p:commandButton inline="true" value="#{msg['valider']}" update=":infos" action="#{form.valider}"/>
        </h:form>
      </pm:content>
    </pm:view>

    <!-- widok informacji -->
    <pm:view id="infos" swatch="b">
      <pm:header title="#{msg['confirmations']}">
        <f:facet name="left"><p:button value="#{msg['back']}" icon="back" href="#forms?reverse=true"/></f:facet>
      </pm:header>
      <pm:content>
        <ul>
          <li>#{msg['input']} : ${form.inputText}</li>
          <li>#{msg['textarea']} : ${form.inputTextArea}</li>
          <li>#{msg['dropdown']} : ${form.selectOneMenu}</li>
          <li>#{msg['range']} : ${form.range}</li>
          <li>#{msg['switch']} : ${form.bswitch}</li>
          <li>#{msg['checkbox']} : ${form.booleanCheckbox}</li>
          <li>#{msg['checkboxes']} : ${form.manyCheckboxValue}</li>
          <li>#{msg['radios']} : ${form.radio}</li>
        </ul>
      </pm:content>
    </pm:view>
  </pm:page>
</f:view>

Wykorzystaliśmy przykład demonstracyjny ze strony Primefaces mobile, dostosowując go tak, aby działał:

  • tag <p:selectManyCheckbox> nie był wyświetlany. Zastąpiliśmy go tagiem <h:selectManyCheckbox> (wiersz 32),
  • tag <p:selectOneRadio> nie był wyświetlany. Zastąpiliśmy go tagiem <p:selectOneRadio> (wiersz 40),
  • wiersz 27: zachowaliśmy tag <pm:inputRange>, który wyświetla suwak. Suwak ten zawiera błąd: nie można przesuwać suwaka. Można jednak wpisać liczbę, która spowoduje jego przesunięcie,
  • warto zauważyć, że jest niewiele tagów charakterystycznych dla PFM (wiersze 13, 14, 15, 19, 27, 28 w pierwszym widoku). Pozostałe tagi to standardowe tagi JSF i PF. Primefaces mobile opiera się na tych dwóch frameworkach.

Zwróćmy uwagę na strukturę strony:


<?xml version="1.0" encoding='UTF-8'?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:p="http://primefaces.org/ui"
        xmlns:pm="http://primefaces.org/mobile"
        contentType="text/html">

  <pm:page title="mv-pfm-02">

    <!-- widok Forms -->
    <pm:view id="forms" swatch="b">
      <pm:header ...>
      <pm:content>
        <h:form id="formulaire">
          ...
          <p:commandButton inline="true" value="#{msg['valider']}" update=":infos" action="#{form.valider}"/>
        </h:form>
      </pm:content>
    </pm:view>

    <!-- widok informacji -->
    <pm:view id="infos" swatch="b">
      <pm:header title="#{msg['confirmations']}">
        <f:facet name="left"><p:button value="#{msg['back']}" icon="back" href="#forms?reverse=true"/></f:facet>
      </pm:header>
      <pm:content>
        ...
      </pm:content>
    </pm:view>
  </pm:page>
</f:view>
  • wiersz 10: definiuje stronę PFM. Atrybut title określa tytuł wyświetlany przez przeglądarkę,
  • strona składa się z jednego lub kilku widoków. Przy pierwszym wyświetleniu strony wyświetlany jest pierwszy widok. Następnie przechodzi się między widokami za pomocą nawigacji. Tutaj są dwa widoki: „forms” w wierszu 13 i „infos” w wierszu 24,
  • wiersz 14: tag header definiuje nagłówek widoku,
  • wiersz 15: tag „content” określa zawartość widoku,
  • wiersz 16: widok „forms” zawiera formularz JSF,
  • wiersz 18: formularz ten zostanie zatwierdzony za pomocą klasycznego przycisku Primefaces. Formularz zostanie wysłany do modelu [Form] i przetworzony przez metodę [Form].valider. Metoda ta wykona swoje zadanie. Zobaczymy, że metoda ta powoduje wyświetlenie widoku „infos”. Wcześniej widok ten został zaktualizowany przez wywołanie AJAX (atrybut „update”),
  • wiersz 26: za pomocą przycisku będzie można przejść z widoku infos do widoku forms. Zwróćmy uwagę na formę atrybutu href [href="#forms?reverse=true"]. Notacja #forms oznacza widok formularzy. Parametr reverse=true powoduje powrót do poprzedniego widoku. Przejąłem ten atrybut z wersji demonstracyjnej. Po jego usunięciu nie widać żadnej różnicy na symulatorze... Być może różnica jest widoczna na prawdziwych smartfonach,
  • na koniec warto zwrócić uwagę na wykorzystanie biblioteki Primefaces mobile w linii 7.

Mimo że wprowadza ona pewne nowości, strona PFM jest całkowicie zrozumiała. To samo dotyczy jej szablonu [Form.java].

8.5.5. Szablon [Form.java]

Ten szablon wygląda następująco:


package beans;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class Form implements Serializable {
  // szablon

  private String inputText = "bonjour";
  private String inputTextArea = "ligne1\nligne2";
  private String selectOneMenu = "2";
  private int range = 4;
  private boolean bswitch = true;
  private boolean booleanCheckbox = false;
  private String[] manyCheckbox = {"1", "3"};
  private String radio = "3";

  public String valider() {
    // przechodzimy do widoku informacji
    return "pm:infos";
  }

  public String getManyCheckboxValue() {
    StringBuffer str = new StringBuffer("[");
    for (String checkbox : manyCheckbox) {
      str.append(checkbox);
    }
    str.append("]");
    return str.toString();
  }

  // metody pobierające i ustawiające
  ...
}

Nie ma tu nic nowego. Wszystko to już znamy. Warto jednak zwrócić uwagę na formę metody valider wywoływanej przez formularz. Wiersz 21: zwraca ona ciąg znaków o postaci „pm:nazwawidoku,którymawyświetlić”. W tym przypadku wyświetlony zostanie więc widok infos. Metoda ta nie wykonuje nic poza tym przekierowaniem. Wcześniej pola w wierszach 12–19 otrzymały wartości przesłane metodą POST. Zostaną one wykorzystane do aktualizacji widoku „infos” (atrybut „update” poniżej):


<p:commandButton inline="true" value="#{msg['valider']}" update=":infos" action="#{form.valider}"/>

Widok informacyjny wyświetli wówczas przesłane wartości:

  

<pm:view id="infos" swatch="b">
      <pm:header title="#{msg['confirmations']}">
        <f:facet name="left"><p:button value="#{msg['back']}" icon="back" href="#forms"/></f:facet>
      </pm:header>
      <pm:content>
        <ul>
          <li>#{msg['input']} : ${form.inputText}</li>
          <li>#{msg['textarea']} : ${form.inputTextArea}</li>
          <li>#{msg['dropdown']} : ${form.selectOneMenu}</li>
          <li>#{msg['range']} : ${form.range}</li>
          <li>#{msg['switch']} : ${form.bswitch}</li>
          <li>#{msg['checkbox']} : ${form.booleanCheckbox}</li>
          <li>#{msg['checkboxes']} : ${form.manyCheckboxValue}</li>
          <li>#{msg['radios']} : ${form.radio}</li>
        </ul>
      </pm:content>
    </pm:view>

8.5.6. y testowe

Uruchamiamy projekt w NetBeans. Po wdrożeniu projektu na serwerze Tomcat [1] można go przetestować na symulatorze [http://iphone4simulator.com/] [2]:

Teraz pokażemy, jak przetestować go na prawdziwym smart . Podłączymy serwer, na którym znajduje się aplikacja, oraz smart do tej samej sieci:

Podłączamy serwer do sieci Wi-Fi. Następnie możemy sprawdzić jego adres: IP:

Zapiszmy powyższy adres serwera IP: 192.168.1.127. Wyłączamy ewentualne zapory sieciowe i programy antywirusowe na serwerze:

 

Na serwerze uruchamiamy aplikację [mv-pfm-02] w środowisku NetBeans [1]:

Podłączamy smartfon do tej samej sieci Wi-Fi co serwer, aby oba urządzenia mogły się wzajemnie wykryć. Następnie otwieramy przeglądarkę i wpisujemy adres URL [http://192.168.1.127:8080/mv-pfm-02/] [2]. Teraz możemy przetestować aplikację. Z radością odkryjemy, że suwak, który nie działa w symulatorze, działa na smartfonie. Istnieje więc rozbieżność między symulatorami a rzeczywistymi urządzeniami.

8.6. Conclusion

Przedstawiliśmy jedynie tagi formularzy z biblioteki Primefaces Mobile, ale to wystarczy dla naszej przykładowej aplikacji.

8.7. Testy w Eclipse

Importujemy do Eclipse projekty Maven [1] i uruchamiamy je: [2],

na serwerze Tomcat [3]. Uruchomiona aplikacja pojawia się wówczas w przeglądarce wewnętrznej programu Eclipse [4].

Należy zauważyć, że aplikacja [mv-pfm-02] wykazywała nieprawidłowości w przeglądarce Eclipse. Po załadowaniu jej w przeglądarkach Firefox lub IE problemy te zniknęły.