Entwicklung eigener Komponenten Komponente (1/4) - Schnittstelle glossar.xhtml <?xml <?xml version='1.0' encoding='UTFencoding='UTF-8' ?> <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN" Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite"> xmlns:composite="http://java.sun.com/jsf/composite"> • Möglichkeit Komponenten basierend auf anderen Komponenten in XHTML zu realisieren • konfigurierbar über Interface (hier nur Mini-Beispiel) • vor eigener Entwicklung nachdenken: – Realisierung mit Templates oder/und include genauso gut? – gibt es gewünschte Komponente schon? (z. B. nachschauen unter http://jsfcentral.com/) – Reichen nicht Validatoren, Konvertierer und evtl. PhaseListener aus? • Hinweis: Netbeans 8 zeigt ggfls. Fehler, wo keine sind Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker <!-<!-- INTERFACE --> --> <composite:interface> composite:interface> <composite:attribute name="schlagwort" name="schlagwort" required="true"/> required="true"/> <composite:attribute name="detail" name="detail" required="true"/> required="true"/> </composite:interface </composite:interface> composite:interface> 356 Komponente (2/4) - Implementierung Prof. Dr. Stephan Kleuker Prof. Dr. Stephan Kleuker 357 Komponente (3/4) - Beispielnutzung index.xhtml <?xml <?xml version='1.0' encoding='UTFencoding='UTF-8' ?> <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN" Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:h="http://java.sun.com/jsf/html" xmlns:bsp="http://java.sun.com/jsf/composite/beispiel"> xmlns:bsp="http://java.sun.com/jsf/composite/beispiel"> <h:head> h:head> <title>Glossar</title <title>Glossar</title> title>Glossar</title> </h:head </h:head> h:head> <h:body> h:body> <bsp:glossar schlagwort="Adam" schlagwort="Adam" detail="der, detail="der, wo nich allein sein konnte"/> <bsp:glossar schlagwort="Eva" schlagwort="Eva" detail="die, detail="die, wo den Apfel nich lassen konnte"> Wo ist Missing Link? </bsp:glossar </bsp:glossar> bsp:glossar> </h:body </h:body> h:body> </html </html> html> <!-<!-- IMPLEMENTATION --> --> <composite:implementation> composite:implementation> <h:panelGrid columns="2" rules="cols" rules="cols" frame="box"> frame="box"> <h:outputLabel value="#{cc.attrs.schlagwort}"/> value="#{cc.attrs.schlagwort}"/> <h:panelGroup> h:panelGroup> <p> <h:outputText value="#{cc.attrs.detail}"/> value="#{cc.attrs.detail}"/> </p> <composite:insertChildren/> composite:insertChildren/> </h:panelGroup </h:panelGroup> h:panelGroup> </h:panelGrid </h:panelGrid> h:panelGrid> </composite:implementation </composite:implementation> composite:implementation> </html </html> html> Komponentenbasierte SoftwareEntwicklung Komponentenbasierte SoftwareEntwicklung 358 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 359 Komponente (4/4) - Ausgabe, Projektstruktur Ausblick: Komponentenmöglichkeiten • Im Interface wesentlich mehr als nur einfache Parameter (Attribute) definierbar • Attribute können Verknüpfungen zu Action-Methoden bzw. Event-Listenern enthalten methodmethod-signature="java.lang.string f()" • Übergabe weiterer Funktionalität (Methoden) an Komponente möglich für Event-Listener, Konvertierer und Validatoren <composite:actionSource> composite:actionSource> <composite:valueHolder> composite:valueHolder> <composite:editableValueHolder> composite:editableValueHolder> Ordner muss so heißen • Funktionalität kann dann bei inneren Komponenten der Composite-Komponente genutzt werden Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 360 Nutzung von Ajax Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 361 Ajax-Beispiel (1/3) - Bean • Ajax = Asynchronous JavaScript and XML(HTTPRequest) – klassische Webapplikation: • Nutzer macht Eingaben • Nutzer beendet Eingabe (Knopf, Link, <Return>-Taste) • Informationen an Server, der wertet aus • neu berechnete Seite wird Nutzer zur Verfügung gestellt • interaktive Applikation (Jesse James Garret, 2004) – Nutzer macht Eingaben – Eingaben führen auch während der Eingabe zu Reaktionen – Informationen werden zwischenzeitlich auf Server ausgewertet – berechnete Teilergebnisse werden in aktuelle Seite eingeblendet @ManagedBean(name="user") ManagedBean(name="user") @SessionScoped public class Nutzer { Komponentenbasierte SoftwareEntwicklung Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 362 private String name = ""; public String getName() getName() { return name; name; } public void setName(String name) name) { this.name = name; name; } } Prof. Dr. Stephan Kleuker 363 Ajax-Beispiel (2/3) - index.xhtml mit f:ajax Ajax-Beispiel (3/3) - Ausgabe <h:form> h:form> <h:outputText value="Your name: name: " /> <h:inputText id="in" id="in" value="#{user.name}" value="#{user.name}" > <f:ajax render="greeting" render="greeting" event="keyup"/> event="keyup"/> <f:validateLength minimum="1" maximum="10" /> </h:inputText </h:inputText> h:inputText> <h:message for="in"/> for="in"/> <br/> br/> <h:panelGroup id="greeting" id="greeting" > <h:outputText value="Hello, value="Hello, " rendered="#{not empty user.name}" user.name}" /> <h:outputText value="x " rendered="#{empty user.name}" user.name}" /> <h:outputText value="#{user.name}" value="#{user.name}" /> <h:outputText value="!" value="!" rendered="#{not empty user.name}"/> user.name}"/> </h:panelGroup </h:panelGroup> h:panelGroup> </h:form </h:form> h:form> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 364 Granulare Nutzung von f:ajax • render: IDs der Komponenten, die neu gerendert werden sollen (auch @this = dieses Element, @form = umgebende Form, @all = alle Elemente, @none = kein Element) • execute: IDs der Komponmenten, die vollständig JSFLebenszyklus durchlaufen sollen (auch ... s. o.) Prof. Dr. Stephan Kleuker • Nutzer tippt, dann unmittelbare Aktion • (so) keine direkte Validierung • Nutzer drückt Return-Taste Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 365 Interaktionsspielerei (1/3) - index.xhtml • f:ajax kann um Komponenten gelegt werden • f:ajax kann in Komponenten ergänzt werden (z. B. h:commandButton) • f:ajax kann in und um Komponenten genutzt werden, dann ist Effekt die Summe aller spezifizierten Effekte • Mehrere f:ajax-Einträge für eine Komponente ergänzen sich generell Komponentenbasierte SoftwareEntwicklung • Start 366 <h:form> h:form> <h:outputLabel id="be" id="be" value="#{control.beruehrt}"> value="#{control.beruehrt}"> <f:ajax event="mouseover" event="mouseover" render="be pg" pg" listener="#{control.drueber}"/> listener="#{control.drueber}"/> <f:ajax event="mouseout" event="mouseout" render="be pg" pg" listener="#{control.weg}"/> listener="#{control.weg}"/> </h:outputLabel </h:outputLabel> h:outputLabel> <h:panelGrid id="pg" id="pg" columns="2"> <h:outputText value="drueber:"/> value="drueber:"/> <h:outputText value="#{control.dzahl}"/> value="#{control.dzahl}"/> <h:outputText value="weg:"/> value="weg:"/> <h:outputText value="#{control.wzahl}"/> value="#{control.wzahl}"/> </h:panelGrid </h:panelGrid> h:panelGrid> </h:form </h:form> h:form> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 367 Interaktionsspielerei (2/3) - Verwaltungsklasse Interaktionsspielerei (3/3) - Ausgabe @ManagedBean @SessionScoped public class Control { private String beruehrt = "beruehr "beruehr mich"; private int dzahl; dzahl; private int wzahl; wzahl; getBeruehrt() public String getBeruehrt () {return {return beruehrt;} beruehrt;} public int getDzahl() getDzahl() {return {return dzahl;} dzahl;} public int getWzahl() getWzahl() {return {return wzahl;} wzahl;} drueber() public void drueber () { beruehrt = "beruehr "beruehr mich nicht"; dzahl++; dzahl++; } public void weg() { beruehrt = "beruehr "beruehr mich"; wzahl++; wzahl++; } } Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 368 Komponentenbasierte SoftwareEntwicklung X X body X X X X X X X X X X X X X X commandLink X X X X X X X X X X X X X X X X X X X X X X X valueChange unload select mouseup mouseover X X X X X X X X X commandButton dataTable X inputText X X X X X X X X X X X X X X X inputTextArea X X X X X X X X X X X X X X X outputLabel X X X X X X X X X panelGrid X X X X X X X X X X X X X selectManyMenu X X X X X X X X X X X X X X X selectOneRadio X X X X X X X X X X X X X X X Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 369 JSF-Erweiterungen mouseout mousemove mousedown load keyup keypress keydown focus dblclick click change blur action <h: Komponenten> und Events (Ausschnitt) Prof. Dr. Stephan Kleuker 370 • graphische Möglichkeiten in JSF recht schlicht (wesentlich besser als gezeigt !), Erweiterungsbibliotheken sinnvoll • wesentliche Bibliotheken: – RichFaces: http://www.jboss.org/richfaces – Primefaces: http://www.primefaces.org/ – IceFaces: http://www.icefaces.org/main/home/ – Apache MyFaces: http://myfaces.apache.org/ – Apache MyFaces Trinidad (ehemals Oracle ADF-Faces): http://myfaces.apache.org/trinidad/index.html • kritisch: Bibliotheken nur teilweise kompatibel • kritisch: in Details teilweise deutliche Darstellungsunterschiede in verschiedenen Browsern • noch nicht gesamte Funktionalität auf JSF 2.0 umgestellt Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 371 RichFaces Ideen (bis Version 3.3 nur bis JSF 1.2) Mini-Beispiel: Kalender - kleiner Ausschnitt (1/3) • • erweiterte graphische Komponenten eigene Integration von Ajax (ohne es nutzen zu müssen, es aber zu können) • RichFaces integriert Frameworks und Bibliotheken – Prototype [http://prototypejs.org] – jQuery [http://jquery.com] – Script.aculo.us [http://script.aculo.us] benötigte Bibliotheken mit Versionsnummern beachten: commons-beanutils-1.7.0.jar, commons-collections-3.2.jar, commonsdigester-1.8.jar, commons-logging-1.0.4.jar, jhighlight-1.0.jar einleitender Artikel: http://www.ibm.com/ developerworks/java/library/j-richfaces/index.html • • Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 372 Mini-Beispiel: Kalender - kleiner Ausschnitt (2/3) <body> <f:view> f:view> <a4j:form> <rich:calendar id="cal" value="#{modul.start value="#{modul.start}" modul.start}" popup="false“ popup="false“ datePattern=" datePattern="dd.MM.yyyy ="dd.MM.yyyy"> dd.MM.yyyy"> <a4j:support event="onchanged event="onchanged" onchanged" reRender="o"/> reRender="o"/> </rich:calendar </rich:calendar> rich:calendar> <br> br> <h:commandButton action="#{modul.show action="#{modul.show}" modul.show}" value="Ü value="Übernehmen"/> bernehmen"/> <br <br> br> <h:outputLabel value="ausgew value="ausgewä ausgewählt: hlt: "/> <h:outputText id="o" value="#{modul.start value="#{modul.start}" modul.start}" /> </a4j:form> </f:view </f:view> f:view> </body> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 373 Mini-Beispiel: Kalender - kleiner Ausschnitt (3/3) public class Modul implements Serializable {... private Date start=new Date();... public Date getStart() getStart() { return start; } public void setStart(Date start) { this.start = start; } public String show(){ show(){ System.out.println("Datum: System.out.println("Datum: " +new SimpleDateFormat("dd.MM.yyyy").format(start)); SimpleDateFormat("dd.MM.yyyy").format(start)); return "X"; } <managed<managed-bean> <managed<managed-beanbean-name>modul name>modul</managed modul</managed</managed-beanbean-name> <managed<managed-beanbean-class>entities.Modul class>entities.Modul</managed bean-class> entities.Modul</managed</managed-bean<managed<managed-beanbean-scope>session</managedscope>session</managed-beanbean-scope> </managed</managed-bean> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 374 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 375 Nutzung von PrimeFaces 2 Beispiel: Editorspielerei (1/4) - Managed Bean @ManagedBean @SessionScoped public class Text { • unterstützt JSF 2, recht junges Projekt ab November 2008 • Installationsergänzung in web.xml: <servletservlet-mapping> mapping> <servletservlet-name>Faces Servlet</servletServlet</servlet-name> name> <urlurl-pattern>/faces/*</urlpattern>/faces/*</url-pattern> pattern> </servlet </servletservlet-mapping> mapping> <servlet> servlet> <servletservlet-name>Resource Servlet</servletServlet</servlet-name> name> <servletservlet-class> class> org.primefaces.resource.ResourceServlet </servlet </servletservlet-class> class> </servlet </servlet> servlet> <servletservlet-mapping> mapping> <servletservlet-name>Resource Servlet</servletServlet</servlet-name> name> <urlurl-pattern>/primefaces_resource/*</urlpattern>/primefaces_resource/*</url-pattern> pattern> </servlet </servletmapping> servlet-mapping> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker private String inhalt; inhalt; public String getInhalt() getInhalt() { return inhalt; inhalt; } public void setInhalt(String inhalt) inhalt) { this.inhalt = inhalt; inhalt; } } 376 Beispiel: Editorspielerei (2/4) - index.xhtml Prof. Dr. Stephan Kleuker Prof. Dr. Stephan Kleuker 377 Beispiel: Editorspielerei (3/4) - h: (Seite lädt neu) <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.prime.com.tr/ui"> xmlns:p="http://primefaces.prime.com.tr/ui"> <h:head> h:head> <title>Editor</title> title>Editor</title> </h:head </h:head> h:head> <h:body> h:body> <h:form > <p:editor id="ed" id="ed" width="600px" height="120px" value="#{text.inhalt}" value="#{text.inhalt}" widgetVar="editor"/> widgetVar="editor"/> <p:commandButton update="o1,o2" async="true" async="true" value="p Uebernehmen" Uebernehmen" onclick="editor.saveHTML()"/><br/> onclick="editor.saveHTML()"/><br/> <h:commandButton value="h Uebernehmen"/><br/> Uebernehmen"/><br/> <h:outputText id="o1" escape="true" escape="true" value="Inhalt: value="Inhalt: #{text.inhalt}"/><br #{text.inhalt}"/><br/> text.inhalt}"/><br/> <h:outputText id="o2" escape="false" escape="false" value="Inhalt: value="Inhalt: #{text.inhalt #{text.inhalt}"/> text.inhalt}"/> </h:form </h:form> h:form> </h:body </h:body> h:body> </html </html> html> Komponentenbasierte SoftwareEntwicklung Komponentenbasierte SoftwareEntwicklung 378 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 379 Beispiel: Editorspielerei (4/4) - p: (Aktualisierung) Anmerkungen zum Beispiel • Normalerweise unterstützt p:commandButton Ajax direkt (nur bei p:editor Problem, deshalb Workaround mit widgetVar) • statt f:ajax müsste p:ajax (mit anderen Attributen genutzt werden) • Warum andere Ergebnisse angezeigt werden, ist mir unklar • <h:head> h:head> immer benötigt • Generell: Genaue Analyse der oft sehr vielen Attribute einer Komponente notwendig • Mischung von h: und p: oft (nicht immer) möglich • Man muss mit Eigenarten der Komponenten leben (bei Großprojekten und Auswahlentscheidungen schwierig) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 380 Polling (1/2) Prof. Dr. Stephan Kleuker 381 Polling (2/2) <?xml <?xml version='1.0' encoding='UTFencoding='UTF-8' ?> <!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN" Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1"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:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.prime.com.tr/ui"> xmlns:p="http://primefaces.prime.com.tr/ui"> <h:head> h:head> <title>Poller</title> title>Poller</title> </h:head </h:head> h:head> <h:body> h:body> <h:form> h:form> <h:outputText id="o1" value="#{zeit.datum}"/><br/> value="#{zeit.datum}"/><br/> <h:outputText id="o2" value="#{zeit.anzahl}"/> value="#{zeit.anzahl}"/> <p:poll interval="3" update="o1,o2"/> </h:form </h:form> h:form> </h:body </h:body> h:body> </html </html> html> Komponentenbasierte SoftwareEntwicklung Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 382 @ManagedBean @SessionScoped public class Zeit { private int anzahl; anzahl; public String getDatum() getDatum() { anzahl++; anzahl++; return new Date().toString(); Date().toString(); } public int getAnzahl() getAnzahl() { return anzahl; anzahl; } } Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 383 Design-Tests JSF - es geht noch weiter • JSF Expression Language – einfacher Zugriff auf Maps, die Umgebungsdaten, wie param, requests, cookies und initParam haben – Nutzung von flash-Variable als Zwischenspeicher • Erweiterung der Expression Language • Möglichkeit GET zu nutzen (und damit Bookmarks) – <h:button> und <h:link> • JSF 2.0 hat klare Regeln wie Ressourcen verwaltet werden (Bilder, Templates, ...) • integrierte, nutzbare JavaScript-API • Viele weitere JavaScript-Möglichkeiten (u. a. h:outputScript) • weitere Möglichkeiten des Event-Handlings, z. B. eigene Klasse reagiert auf Event (z. B. Phasenwechsel) • Ergänzung/Erweiterung des Exception Handlings • Lokalisierung, Mehrsprachlichkeit • Browser stellen identische Inhalte leicht verändert da • technisch überflüssig, aber wichtig für den Zeitgeist: modische Design-Anpassungen • Für IT-Profi: Sisyphus-Arbeit; Test mit unterschiedlichen Browsern • Direkte Hilfsmittel: – Lunascape: ein Browser, bei dem man zwischen drei Maschinen umschalten kann IE (Trident)+Firefox (Gecko)+Chrome, Safari (Webkit) – Windows: USB-portable Browser ohne Installationsnotwendigkeit (verändern keine Einstellungen): Firefox, Chrome, Opera • Capture & Replay mit Selenium zum inhaltlichen Test Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 384 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 385