Skip to content

8. Einführung in PrimeFaces Mobile

8.1. Die Rolle von PrimeFaces Mobile in einer JSF-Anwendung

Kehren wir zur Architektur einer PrimeFaces-Anwendung zurück, wie wir sie zu Beginn dieses Dokuments betrachtet haben:

Wenn das Ziel ein Handy-Browser ist, müssen wir das Layout anpassen. Tatsächlich muss die Größe eines Smartphone-Bildschirms berücksichtigt und die Benutzerfreundlichkeit der Seiten neu gestaltet werden. Es gibt Bibliotheken, die auf die Erstellung von Webseiten für mobile Geräte spezialisiert sind. Dies ist der Fall bei der PrimeFaces Mobile-Bibliothek, die ihrerseits auf der jQuery Mobile-Bibliothek basiert.

Die Architektur einer mobilen Webanwendung entspricht der vorherigen, mit dem Unterschied, dass wir zusätzlich zu JSF und PrimeFaces die PrimeFaces Mobile (PFM)-Bibliothek verwenden.

Wir werden alle mit JSF und PrimeFaces behandelten Konzepte erneut durchgehen. Nur die [Präsentationsschicht] (vor allem die Seiten) wird sich ändern.

8.2. Die Vorteile von PrimeFaces Mobile

Die PrimeFaces Mobile-Website

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

bietet eine Liste von Komponenten, die in einer PFM-Seite verwendet werden können [1, 2]:

Sie können Smartphone-Simulatoren verwenden, um die oben genannte Demo-Anwendung anzusehen. Einer davon ist für das iPhone 4 unter der URL [http://iphone4simulator.com/] [3] verfügbar. Geben Sie die Adresse der zu testenden Anwendung in [4] ein, und sie wird in iPhone-Abmessungen angezeigt. Solche Simulatoren sind während der Entwicklungsphase nützlich, doch letztendlich muss die Anwendung unter realen Bedingungen auf verschiedenen Mobilgeräten getestet werden.

8.3. PrimeFaces Mobile lernen

PrimeFaces Mobile bietet weitaus weniger Komponenten als PrimeFaces. Die PrimeFaces Mobile-Website

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

enthält eine Liste dieser Komponenten. Hier sind zum Beispiel die Komponenten, die in einem Formular verwendet werden können [1], [2], [3]:

Den Quellcode für die Beispiele können Sie hier herunterladen [4]. Wir stellen fest, dass die PFM-Seite, auf der die oben genannten Komponenten [1], [2] und [3] angezeigt werden, wie folgt aussieht:


<?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">
        <!-- Forms -->
        <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>
  • Zeile 7: Es erscheint ein neuer Namespace, nämlich der der PrimeFaces Mobile-Komponenten mit dem Präfix pm,
  • Zeile 10: definiert eine Seite. Eine Seite besteht aus mehreren Ansichten (Zeile 12). Zu jedem Zeitpunkt ist nur eine Ansicht sichtbar. Dies ist ein Konzept, das wir in unseren PrimeFaces-Beispielen ausgiebig verwendet haben: eine einzelne Seite mit mehreren Fragmenten, die ein- oder ausgeblendet werden können. Hier müssen wir das nicht tun. Wir legen einfach die anzuzeigende Ansicht fest, wobei die anderen automatisch ausgeblendet werden,
  • Zeile 12: eine Ansicht,
  • Zeilen 13–15: definieren die Kopfzeile der Ansicht:

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

Beachten Sie das Tag, das zur Erstellung einer Schaltfläche verwendet wird. Das href-Attribut ermöglicht die Navigation. Sein Wert ist hier der Name einer Ansicht. Wenn Sie auf die Schaltfläche klicken, gelangen Sie zurück (reverse=true) zur Ansicht mit dem Namen „main“ (hier nicht dargestellt).

  • Zeile 16: führt den Inhalt der Ansicht ein,
  • Zeile 17: Erzeugt ein Eingabefeld:

                <p:inputText label="Input:" />
  
  • Zeile 18: ein Eingabefeld mit einem bestimmten Symbol:

                <p:inputText label="Search:" type="search"/>
  
  • Zeile 19: ein Eingabefeld für eine Telefonnummer:

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

Das „type“-Attribut eines <inputText>-Tags hat eine bestimmte Bedeutung: Es legt fest, welche Art von Tastatur dem Benutzer zur Dateneingabe angezeigt wird. Bei „type=‘tel‘“ wird also eine numerische Tastatur angezeigt,

  • Zeile 20: ein mehrzeiliges, erweiterbares Texteingabefeld:

                <p:inputTextarea id="inputTextarea" label="Textarea:"/>
  
  • Zeilen 21–29: ein Feld, das mehrere Komponenten vereint:

                <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>
 
  • Zeile 2: die Bezeichnung für die Komponente in Zeile 3;
  • Zeile 3: eine Dropdown-Liste;
  • Zeilen 4–7: deren Inhalt;
  • Zeile 30: ein Schieberegler:

                <pm:inputRange id="range" minValue="0" maxValue="100" label="Range:" />
  
  • Zeile 31: eine Umschaltfläche:

                <pm:switch id="switch" onLabel="yes" offLabel="no" label="Switch:" />
 
  • Zeile 32: ein Kontrollkästchen:

      <p:selectBooleanCheckbox id="booleanCheckbox" value="false" itemLabel="I agree" label="Checkbox"/>
  
  • Zeilen 33–37: eine Gruppe von Kontrollkästchen:

                  <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>
  
  • Zeilen 38–42: eine Gruppe von Optionsfeldern

                    <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>
  

Beachten Sie, dass die Seite Tags aus den drei Bibliotheken verwendet: JSF, PF und PFM. Wir wissen nun genug, um unser erstes PrimeFaces Mobile-Projekt zu erstellen.

8.4. Ein erstes PrimeFaces Mobile-Projekt: mv-pfm-01

Wir werden das zuvor behandelte Beispiel noch einmal aufgreifen, um es in ein Maven-Projekt zu integrieren. So können wir die für ein PrimeFaces Mobile-Projekt erforderlichen Abhängigkeiten untersuchen.

8.4.1. Das NetBeans-Projekt

Das NetBeans-Projekt sieht wie folgt aus:

Das NetBeans-Projekt beginnt als einfaches Maven-Webprojekt, dem die Abhängigkeiten [2] hinzugefügt wurden. Dies spiegelt sich in der Datei [pom.xml] mit dem folgenden Code wider:


<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>

In den Zeilen 11–16 die Abhängigkeit von PrimeFaces Mobile. Hier haben wir Version 0.9.1 verwendet (Zeile 14). Zusätzlich haben wir Version 3.2 von PrimeFaces verwendet (Zeile 9). Diese Versionsnummern sind wichtig. Tatsächlich bin ich auf einige Probleme mit PFM gestoßen, einer noch unfertigen Bibliothek. Eine Zeit lang gab es eine fehlerhafte Version 0.9.2. Diese wurde inzwischen entfernt. Wir sind auf Version 0.9.1 zurückgegangen. Das PFM-Projekt hat somit einen Rückschritt gemacht. Auch die Tests mit der 1.0-SNAPSHOT-Version der kommenden 1.0-Version (Anfang Juni 2012) sind fehlgeschlagen.

Die Startseite [index.xhtml] [1] ist die Demoseite für PrimeFaces Mobile-Komponenten:


<?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">
 
    <!-- Main View -->
    <pm:view id="main">
      ...
    </pm:view>
 
    <!-- Forms -->
    <pm:view id="forms">
      ...
    </pm:view>
 
 
    <!-- Buttons -->
    <pm:view id="buttons">
      ...
    </pm:view>
 
    ...
  </pm:page>
</f:view>

Es gibt eine einzige Seite (Zeile 10), die aus zwölf Ansichten besteht. Wir werden hier nicht näher darauf eingehen. Das Ziel ist lediglich zu zeigen, wie man ein PrimeFaces Mobile-Projekt erstellt.

Führen wir dieses Projekt aus. Wir erhalten eine Fehlerseite [1]:

Der Grund dafür ist, dass eine PrimeFaces Mobile-Anwendung mit dem Parameter [?javax.faces.RenderKitId=PRIMEFACES_MOBILE] aufgerufen werden muss, wie in [2] gezeigt. Sie können diesen Parameter umgehen, indem Sie die Datei [faces-config.xml] ändern (oder sie erstellen, falls sie nicht vorhanden ist, wie in diesem Fall) [3]:

Der Inhalt lautet wie folgt:


<?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>
  • Zeile 11: Legt den Wert des Parameters [javax.faces.RenderKitId] fest.

Bei der Ausführung erhalten wir dieselbe Seite wie zuvor, jedoch ohne einen Parameter in die URL einfügen zu müssen [4]. Wir überlassen es dem Leser, diese Anwendung zu testen. Wir entdecken einige Fehler: Das <p:selectManyCheckbox>-Tag wird nicht angezeigt, ebenso wenig wie das <p:selectOneRadio>-Tag, und das <pm:range>-Tag funktioniert nicht. Diese Probleme, die auf der Demo-Website nicht auftreten, deuten darauf hin, dass die Demo mit der hier verwendeten Kombination aus PrimeFaces Mobile 0.9.1 und PrimeFaces 3.2 nicht funktioniert. Dennoch dient sie als Ausgangspunkt für die Erkundung der Tags in dieser Bibliothek, die sich noch in der Entwicklung befindet.

Um eine realistischere Darstellung zu erhalten, können Sie die Anwendung auf einem Simulator wie dem iPhone 4-Simulator [http://iphone4simulator.com/] testen. Sie erhalten Folgendes:

Geben Sie [5] ein, dieselbe URL, die der vorherige Browser in [4] verwendet hat.

8.5. Beispiel mv-pfm-02: Formular und Modell

In diesem Projekt demonstrieren wir die Interaktionen zwischen einer PrimeFaces Mobile-Seite und ihrem Modell. Diese Interaktionen folgen den Regeln des JSF-Frameworks, auf dem PrimeFaces Mobile letztlich basiert.

8.5.1. Die Ansichten

Das Projekt umfasst zwei Ansichten

  • Ansicht 1 [1] zeigt ein Formular an, das abgeschickt werden kann [2],
  • Ansicht 2 [3] bestätigt die Eingaben und bietet die Möglichkeit, zum Formular zurückzukehren [4].

Das Projekt veranschaulicht zwei Dinge:

  • die Beziehung zwischen einer Seite und ihrer Vorlage,
  • die Navigation zwischen den Ansichten auf der Seite.

8.5.2. Das NetBeans-Projekt

Das NetBeans-Projekt sieht wie folgt aus:

  • in [1], der PrimeFaces Mobile-Seite,
  • in [2] die entsprechende Vorlage
  • in [3] die Nachrichtendateien, da die Anwendung internationalisiert ist,
  • in [4] die Projektabhängigkeiten.

8.5.3. Projektkonfiguration

Wir stellen die Konfigurationsdateien zur Verfügung, ohne sie zu erläutern. Sie sind mittlerweile Standard.

[web.xml]: Konfiguriert die Webanwendung:


<?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]: konfiguriert die JSF-Anwendung:


<?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]: die französische Sprachdatei:


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. Die Primefaces-Mobilseite

Die Seite [index.xhtml] sieht wie folgt aus:


<?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">
 
    <!-- forms view -->
    <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>
 
    <!-- info view -->
    <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>

Wir haben das Demo-Beispiel von der PrimeFaces Mobile-Website übernommen und es so angepasst, dass es funktioniert:

  • Das <p:selectManyCheckbox>-Tag wurde nicht angezeigt. Wir haben es durch ein <h:selectManyCheckbox>-Tag ersetzt (Zeile 32),
  • das <p:selectOneRadio>-Tag wurde nicht angezeigt. Wir haben es durch ein <p:selectOneRadio>-Tag ersetzt (Zeile 40),
  • Zeile 27: Wir haben das <pm:inputRange>-Tag beibehalten, das einen Schieberegler anzeigt. Dieser Schieberegler weist einen Fehler auf: Man kann den Cursor des Schiebereglers nicht bewegen. Man kann jedoch eine Zahl eingeben, die ihn bewegt,
  • Beachten Sie, dass es nur wenige PFM-spezifische Tags gibt (Zeilen 13, 14, 15, 19, 27 und 28 in der ersten Ansicht). Die anderen Tags sind Standard-JSF- und PF-Tags. PrimeFaces Mobile basiert auf diesen beiden Frameworks.

Beachten Sie die Seitenstruktur:


<?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">
 
    <!-- forms view -->
    <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>
 
    <!-- info view -->
    <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>
  • Zeile 10: definiert eine PFM-Seite. Das Attribut „title“ legt den vom Browser angezeigten Titel fest;
  • eine Seite besteht aus einer oder mehreren Ansichten. Wenn die Seite zum ersten Mal angezeigt wird, wird die erste Ansicht angezeigt. Anschließend navigieren Sie von einer Ansicht zur nächsten. Hier gibt es zwei Ansichten: „forms“ in Zeile 13 und „info“ in Zeile 24,
  • Zeile 14: Das header-Tag definiert die Kopfzeile einer Ansicht,
  • Zeile 15: Das content-Tag definiert den Inhalt einer Ansicht,
  • Zeile 16: Die Ansicht „Forms“ enthält ein JSF-Formular,
  • Zeile 18: Dieses Formular wird über eine Standard-PrimeFaces-Schaltfläche übermittelt. Das Formular wird an das [Form]-Modell gesendet und von der Methode [Form].validate verarbeitet. Diese Methode erledigt ihre Aufgabe. Wir werden sehen, dass sie die Anzeige der Info-Ansicht anfordert. Zuvor wurde die Ansicht über einen AJAX-Aufruf (update-Attribut) aktualisiert,
  • Zeile 26: Wir können mithilfe einer Schaltfläche von der Info-Ansicht zur Formularansicht wechseln. Beachten Sie das Format des href-Attributs [href="#forms?reverse=true"]. Die Notation #forms bezieht sich auf die Formularansicht. Der Parameter reverse=true fordert die Rückkehr zur vorherigen Seite an. Ich habe dieses Attribut aus der Demo übernommen. Wenn man es entfernt, sieht man auf einem Simulator keinen Unterschied... Vielleicht gibt es einen auf echten Smartphones,
  • Beachten Sie schließlich die Verwendung der PrimeFaces Mobile-Bibliothek in Zeile 7.

Auch wenn sie neue Funktionen einführt, ist diese PFM-Seite recht unkompliziert. Das Gleiche gilt für ihre Vorlage [Form.java].

8.5.5. Die Vorlage [Form.java]

Dieses Modell sieht wie folgt aus:


package beans;
 
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
@ManagedBean
@SessionScoped
public class Form implements Serializable {
  // model
 
  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() {
    // we move on to the news view
    return "pm:infos";
  }
 
  public String getManyCheckboxValue() {
    StringBuffer str = new StringBuffer("[");
    for (String checkbox : manyCheckbox) {
      str.append(checkbox);
    }
    str.append("]");
    return str.toString();
  }
 
  // getters and setters
  ...
}

Das ist nichts Neues. Das haben wir alles schon einmal gesehen. Beachten Sie jedoch die Form der vom Formular aufgerufenen Validierungsmethode. Zeile 21: Sie gibt eine Zeichenkette in der Form „pm:viewname“ zurück. Hier wird die Info-Ansicht angezeigt. Die Methode führt nichts anderes als diese Navigation durch. Zuvor haben die Felder in den Zeilen 12–19 die übermittelten Werte empfangen. Diese werden verwendet, um die Info-Ansicht zu aktualisieren (update-Attribut unten):


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

Die Info-Ansicht zeigt dann die übermittelten Werte an:

  

<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. Test-

Führen Sie das NetBeans-Projekt aus. Sobald das Projekt auf Tomcat [1] bereitgestellt wurde, können Sie es auf einem Simulator [http://iphone4simulator.com/] [2] testen:

Wir zeigen Ihnen nun, wie Sie es auf einem echten Smartphone testen können . Wir verbinden den Server, auf dem die Anwendung gehostet wird, und das Smartphone mit demselben WLAN-Netzwerk:

Verbinden Sie den Server mit dem WLAN-Netzwerk. Anschließend können Sie dessen IP-Adresse überprüfen:

Notieren Sie sich die oben angegebene IP-Adresse des Servers: 192.168.1.127. Deaktivieren Sie alle Firewalls und Antivirenprogramme auf dem Server:

 

Starten Sie auf dem Server die Anwendung [mv-pfm-02] in NetBeans [1]:

Verbinden Sie das Smartphone mit demselben WLAN-Netzwerk wie der Server, damit sich die beiden Geräte gegenseitig erkennen können. Öffnen Sie dann einen Browser und geben Sie die URL [http://192.168.1.127:8080/mv-pfm-02/] [2] ein. Sie können die Anwendung nun testen. Sie werden erfreut feststellen, dass der Schieberegler, der im Simulator nicht funktioniert, auf dem Smartphone funktioniert. Es besteht also eine Diskrepanz zwischen Simulatoren und tatsächlichen Geräten.

8.6. Fazit

Wir haben nur die Formular-Tags aus der PrimeFaces Mobile-Bibliothek behandelt, aber das reicht für unsere Beispielanwendung aus.

8.7. Testen mit Eclipse

Importieren Sie die Maven-Projekte [1] in Eclipse und führen Sie sie aus [2],

auf dem Tomcat-Server [3]. Die laufende Anwendung wird dann im internen Browser von Eclipse angezeigt [4].

Beachten Sie, dass die Anwendung [mv-pfm-02] im Eclipse-Browser Fehlfunktionen aufwies. Beim Laden in Firefox- oder IE-Browsern traten diese Probleme nicht mehr auf.