primefaces

Page 1

Prime Faces Tutorial E. Basri Kahveci, Eren Tunçer Hacettepe Üniversitesi, Bilgisayar Mühendisliği Bölümü 21.01.2011


İçindekiler 1. JSF nedir? 2. Neden JSF ? 3. JSF ve MVC Mimarisi 4. Eclipse‟ te JSF Projesi Kurulumu 4.1. Eclipse Kurulumu 4.2. Apache Tomcat 6.0 Kurulumu 4.3. PrimeFaces Konfigurasyonu 5. Prime Faces 6. PrimeFaces Bileşenleri 6.1. Accordion Panel 6.2. Ajax Status 6.3. Calendar 6.4. Charts 6.5. CommandButton 6.6. CommandLink 6.7. Confirm Dialog 6.8. Datatable 6.9. Dialog 6.10.

Input Mask

6.11.

LightBox

6.12.

OutputPanel

6.13.

Panel

6.14.

Password Strength

6.15.

Growl


1. JSF Nedir ? JEE uygulamalarında kullanılan Java servlet, java server pages ( JSP) , Struts, Apache Wicket gibi, JSF te web uygulamalarının arayüzünü inşa etmek için oluşturulan, yeni nesil web uygulama çatısıdır. Temel olarak; uygulama mimarisi, standart kullanici arayüzü(UI) seti ve uygulama altyapısı olmak üzere 3 katmandan oluşmaktadır. JSF‟nin bileşen altyapısı, kullanıcı arayüzü bileşenleri oluşturmak için ortak bir yol tanımlar. Bu mimari standart JSF UI bileşenleri(hyperlink, button, secme kutulari, text alanlari gibi) yaninda, üçüncü parti bileşenleri için de bir ortam oluşturur. Bileşenler olay tabanlıdır, dolayısıyla JSF istemci tarafında oluşan olayların (örnegin text-box‟in degerinin degiştirilmesi ya da butona tıklanmasi gibi) işlenmesini sağlar. Web uygulamalarinin masaüstü olanlardan farkli olarak genellikle birçok istemciye destek vermesi gerektiğinden, JSF‟ in de kullanıcı arayüzü bileşenlerini değisik yollarla göstermek için güçlü bir mimarisi bulunmaktadır. Kullanıcı girişinin “validate” edilmesi, nesneleri göstermek icin nesnelerin string‟e dönüştürülmesi veya string‟den nesne oluşturulması gibi özelliklere sahiptir. Java Server Faces ya da diğer adıyla “Faces”, otomatik olarak UI bileşenleri ile giriş değerlerini tutan ve cevap üreten Java nesnelerini senkron halde tutabilir. Bu nesnelere “backing beans” adı verilir. Ayrıca güçlü bir navigasyon sistemi veçoklu dil desteği bulunur. Her yeni sistem için gerekli temel yapıtaşlari olan bu özellikler JSF‟nin uygulama altyapisini olusturur. JavaServer Faces tool destegi icin altyapiyi tanimlarken ozellestirilmis tool‟larin gelistirilmesi, Java‟da oldugu gibi yazilim firmalarina birakilmistir. Fakat Faces uygulamaları tasarım araçları olmadan da geliştirilebilmektedir.

Şekil-1 JSF Belirtimi


JavaServer Faces ile swing ya da Standart Widget Toolkit gibi diger masaustu kullanici arayuzu uygulama çatıları arasındaki esas fark ise JSF in sunucu tarafında çalşıyor olmasıdır. Bir Swing ygulamasındaki bir butona tıklandığında uygulama kodunda direk işlenebilecek bir olay oluşur. Oysa ki web tarayıcıları JSF bileşenleri ya da olayları hakkında hiçbirşey bilmezler, sadece HTML sayfasını gösterirler. Dolayısıyla bir Faces uygulamasındaki bir butona tıklandığında bir isteğin web tarayıcıdan sunucuya gönderilmesine yol açar. Ayrıca sunucu tarafında tanımlanan Her UI bileşenin de düzgün gösterilmesinden sorumludur.

Şekill – 2 : JSF Kontrol Akışı Şekil -1 de de görüldüğü gibi, uygulamanın altsistemlere (Enterprise JavaBeans servisleri ya da veritabanı gibi) entegre olabildiği görülebilmektedir. JSF ek olarak daha az efor sarfederek daha güçlü web uygulamaları hazırlamak için birçok servis sunmaktadır. Java ServerFaces‟in esas amaci web gelişimini hızlandırmaktır.Uygulama geliştiricilerin istekler(requestler), cevaplar ve markup dili yerine bileşen, olay, “backing bean” ve bunlarin ilişkileri şeklinde düşünmelerini sağlar. Baska bir deyişle web uygulama geliştirmedeki birçok karmaşıklığı maskeleyerek, sadece uygulama geliştirmeye odaklanılmasını sağlar.


2. Neden JSF ? JSF her şeyden önce bir Java standardıdır.Bunun yanında sektördeki IBM, Oracle gibi önemli firmalar JSF‟i desteklemektedir. Farklı JSF implementasyonları bulunduğundan projenin gereklerine göre geliştirme için seçim yapabilme özürlüğü sağlamaktadır. Aynı zamanda çok sayıda zengin üçüncü parti bileşen kütüphanesi bulunmaktadır. PrimeFaces, IceFaces, RichFaces vb. bunlara örnek verilebilir.

3. JSF ve MVC Mimarisi MVC ; adını Model - View - Controller 'in baş harflerinden alan tasarım desenidir. Sunduğu katmanlı mimari sayesinde, uygulamanın kullanıcı arayüzü ve mantık kısmını birbirinden ayırır. Model: İş mantığı (Business Logic) bölümüdür. Tek katmandan oluşabileceği gibi, birden fazla katmanı da içinde barındırabilir. Tek katmandan oluştuğunda genelde veritabanına kayıt ekleme, kayıt çekme, kayıt silme vb. veritabanı işlemleri için kullanılır. Controller'den gelen değerleri işler ve geriye döndürür. Model katmanında herhangi bir output işlemi yapılmaz. View: Uygulamanın kullanıcıya gösterilen arayüzünün bulunduğu katmandır. Html, Css, Javascript vb. bu katmanda bulunur. Bu bölümde minumum php kodunun yazılması hedeflenmektedir. for, foreach, while vb. döngüler ile birlikte, dinamik değerleri ekrana yazdırmak için output komutları sıklıkla kullanılır. Controller:Uygulamanın karar mekanizmasıdır. Model ile View arasında köprü görevi görür. View katmanından gelen istekleri(request) model'e gönderir ve Model katmanından aldığı verileri view'e aktarır.


Şekill – 3 : JSF ve MVC

4. Eclipse’ te JSF Projesi Kurulumu 4.1 Eclipse Kurulumu Web tarayıcımızla http://www.eclipse.org/downloads/ adresine giderek, Eclipse IDE for JAVA EE Developers sürümünü indiriyoruz. Şu anki güncel sürüm Eclipse Helios olduğundan anlatım Helios üzerinden yapılmıştır.

İndirdiğimiz zip dosyasını uygun bir dizine açıyoruz.


4.2

Apache Tomcat 6.0 Kurulumu

http://tomcat.apache.org/download-60.cgi adresinden Apache Tomcat‟in 6.0 sürümünü bilgisayarımıza indirip kurulumu yapıyoruz. Tomcat’in Eclipse’e Tanıtılması Alt kısımda bulunan görünümlerden Servers sekmesine gelip, boş alana sağ tıklayarak New > Server diyoruz. Açılan pencereden Apache > Tomcat v6.0 Server öğesini seçip devam ediyoruz.


Eclipse bizden Tomcat‟in kurulum dizinini göstermemizi istiyor. Kurulumu bilgisayarımızda nereye yaptıysak, Browse deyip o dizini gösteriyoruz. JRE olarak JRE 6‟yı seçip FINISH butonuna basıyoruz. Yeni Bir JSF Projesi Oluşturalım File > New > Dynamic Web Project menüsüyle yeni bir web projesi başlatıyoruz.


Projemize bir isim verdikten sonra Target runtime olarak Apache Tomcat v6.0, Configuration olarak <custom> seçeneklerini seçiyoruz. Daha sonra Configuration seçiminin yanında bulunan Modify butonuna basalım.

Ekranda gördüğümüz seçimleri yaptıktan sonra OK butonuyla devam ediyoruz. Sonraki adımları Next butonları ile geçtikten sonra JSF Capabilities penceresiyle karşılaşıyoruz.


Sağda bulunan Download Library butonuna tıklayarak JSF 2.0 Mojarra gerçekleştirimini indiriyoruz.

URL Mapping Patterns kısmını *.jsf olarak ayarlayıp FINISH butonuyla projemizi başlatıyoruz. Şimdi yeni bir XHTML dosyası oluşturup JSF Hello World‟ümüzü yazalım.

Dosyayı kaydedelim. Sonra sol tarafta bulunan Project Explorer görünümünden helloworld.xhtml satırına sağ tıklayıp “Run As > Run on Server” diyerek önümüze gelen


pencereden kurulumunu yaptığımız Tomcat v6.0‟ı seçelim. Bu seçimi hatırlamasını istiyorsanız alt tarafta bulunan “Always use this server when running this project” seçeneğini işaretleyebilirsiniz. FINISH butona basıp devam ettiğimizde, Tomcat başlatılıyor ve aşağıdaki görüntü ile karşılaşıyoruz.

Sayfamızı varsayılan olarak Eclipse‟teki dahili web tarayıcı ile görüntüledik. Eclipse‟in projenizi bilgisayarınızda kurulu olan herhangi bir web tarayıcı ile başlatmasını istiyorsanız “Window > Web Browser” kısmından tercihinizi değiştirebilirsiniz. Ben bundan sonra Google Chrome ile devam edeceğim.


Şimdi PrimeFaces kütüphanesini projemize dahil edelim. http://www.primefaces.org/downloads.html adresinden PrimeFaces‟in son sürümünü indirip projemizin WebContent/WEB-INF/lib dizinine atıyoruz. Şu anda son sürüm primefaces-2.1.jar dosyasını ben lib dizinine yerleştirdim. PrimeFaces‟ın JDK 5+ runtime ve JSF 1.2+ gerçekleştirimi dışında herhangi bir bağımlılığı bulunmuyor. Yalnızca, bazı özelliklerini kullanabilmek için ek kütüphanelere ihtiyaç duyabiliyor. Ama biz diğer kütüphaneleri indirmeden devam edeceğiz.

4.3 PrimeFaces Konfigurasyonu PrimeFaces‟i çalıştırmadan önce birkaç küçük ayarlama yapmamız gerekiyor. JSF 2.0‟da göre PrimeFaces 2.x‟in ayarlama işlemlerini de halledip ilk PrimeFaces denememize geçmeye az kaldı. İlk olarak Resource Servlet için gerekli ayarlamayı web.xml dosyamıza aşağıdaki kod parçasını ekleyerek halledelim. <servlet> <servlet-name>Resource Servlet</servlet-name> <servlet-class>org.primefaces.resource.ResourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Resource Servlet</servlet-name> <url-pattern>/primefaces_resource/*</url-pattern> </servlet-mapping>


PrimeFaces‟i Servlet 3.0 ortamında kullanıyorsanız, bu ayarlamayı yapmanız gerekmiyor. Son olarak Mojarra 2.x için bir ayarlama daha yapıyoruz. web.xml‟e aşağıdaki girdiyi ekleyelim. <context-param> <param-name>com.sun.faces.allowTextChildren</param-name> <param-value>true</param-value> </context-param>

Bunu da yaptıktan sonra ayarlama adımını da bitirmiş oluyoruz. Şimdi PrimeFaces‟tan bir bileşeni hello-world sayfamıza ekleyip test edelim. Öncelikle PrimeFaces‟in xml namespace‟ini ekliyoruz. xmlns:p=”http://primefaces.prime.com.tr/ui”

Editör bileşenini daha önceden eklediğimiz butonun altına yerleştirelim.

Dosyayı kaydedip Tomcat‟i başlattığımızda aşağıdaki görüntüyle karşılaşıyoruz. Evet, PrimeFaces‟in editör bileşenini de gördük.


5. Prime Faces PrimeFaces, Java Server Faces 2.0 için yüzün üzerinde zengin kullanıcı deneyimi sunan bileşenlere sahip hafif bir açık kaynak kütüphanedir. Türlü türlü işlevlere sahip çeşitli bileşenlere sahip olmasının yanısıra, standart JSF 2.0 Ajax API‟sine dayanan Ajax desteği vardır. Ayrıca TouchFaces modülü ile akıllı telefonlardan kullanılabilecek web uygulamaları kolaylıkla geliştirilebilir. İlk olarak 2009 Haziran ayında 0.9.0 sürümü ile yayınlanmış olan PrimeFaces‟ın, şu anki son sürümü 2010 Kasım ayında yayınlanan 2.2 RC2 sürümüdür. Çıkarılacak olan bir sonraki sürüm ise PrimeFaces 3‟tür. Aşağıda Prime Faces bileşenlerinden 15 tanesi açıklanmıştır.


5.1

Accordion Panel AccordionPanel, bir dizi sekmeden oluşan, sekmelerin her birine tıklandığında ilgili

sekmenin içeriğini render eden ve o sekme ile ilgili bilgiyi ekrana basan bileşendir. Görünüm itibariye akordiyonun çalışma prensibini andıran accordion panelin içerdiği tablar diğer jsf bileşenleri tarafından sarmalanabilmektedir. <p:accordionPanel autoHeight="false"> <p:tab title="BİL235 Programlama Lab. I (0-5-2)"> <h:panelGrid columns="2" cellpadding="10"> <h:outputText value="Veri yapıları, sistem programlama, veri yönetimi ve istatistik gibi derslerde anlatılan kuramsal bilgilerin, uygulamalı olarak pekiştirilmesi." /> </h:panelGrid> </p:tab> <p:tab title="BİL341 Yazılım Lab. I (0-5-2)"> <h:panelGrid columns="2" cellpadding="10"> <h:outputText value="İkinci ve üçüncü sınıf derslerinde verilen kuramsal bilgilerin uygulamalı olarak pekiştirilmesi ve öğrencinin özgün sorunları çözme yeteneğinin geliştirilmesi amaçlanır." /> </h:panelGrid> </p:tab> <p:tab title="BİL447 Yazılım Mühendisliği Lab. (0-5-2)"> <h:panelGrid columns="2" cellpadding="10"> <h:outputText value="Öğrencilerin var olan orta boy yazılımların tasarım ilkeleri, belgeleme yöntemleri ve yanlış bulma yöntemleri üzerinde deney kazanmaları için uygulamalı çalışmalardır. Yeterli sayıda öğretici nitelikte proje kaynak programı bulunmadığında öğrenciler ara boy yazılımların tasarımı, yazılması, belgelenmesi ve sınanması için sıfırdan başlayan çalışmalar yapabileceklerdir." /> </h:panelGrid> </p:tab> </p:accordionPanel>

ddsd


Accordion Panel Events Accordion panel tanımını başlatan tag alanına effect veya event özelliği set edilerek paneller arası geçişler animasyon şekline dönüştürülebilmektedir. Örneğin; effect="bounceslide" event="hover“ event="mouseover“

<p:accordionPanel autoHeight="false" //tablar </p:accordionPanel >

effect="bounceslide"

>


5.2

AjaxStatus AjaxStatus, PrimeFaces bileşenleri tarafından yapılan AJAX request‟lerin

durumunu gösteren bir bileşendir. Sunucuya bir AJAX request gönderdiğinizde kullanıcıya işlemin yapıldığını göstermek için kullanabilirsiniz.

AjaxStatus, sunucuya giden Ajax request‟in durumunu göstermek için 5 adef facet kullanır: prestart, start, complete, success ve error. Çoğu durumda start ve complete yeterli olacaktır. Örnek kod ile bir deneme yapalım. Sunucumuzda uzun süren bir işlem olduğunu varsayalım ve kullanıcıyı onun adına bu işlemi yaparken işlem durumu hakkında bilgilendirelim. Başlattığımız projeye NopBean adında bir bean ekliyoruz (Nop: no operation ) package beans; import javax.faces.bean.ManagedBean; @ManagedBean public class NopBean { public void doSomeHardwork() { try { Thread.currentThread(); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } }

hello-world sayfamızdaki Editor bileşenini artık kaldırabiliriz. Facet‟ları kullanmak için facet‟ları içeren JSF namespace‟ini önce ekliyoruz. xmlns:f="http://java.sun.com/jsf/core"


hello-world sayfamıza aşağıdaki formu ekleyelim. <h:form> <p:commandButton value="Process" action="#{nopBean.doSomeHardwork}" /> <p:ajaxStatus> <f:facet name="start"> <h:outputText value="Processing. Please wait..." /> </f:facet> <f:facet name="complete"> <h:outputText value="Completed!" /> </f:facet> </p:ajaxStatus> </h:form>

PrimeFaces‟in CommandButton bileşeninden yeri gelmişken kısaca bahsedelim. Kendisi JSF‟in standart CommandButton‟a ek özellikler getiriyor ve varsayılan olarak Ajax request ile çalışıyor. Eklediğimiz CommandButton tıklandığında sunucuya bir Ajax istek gönderecek ve AjaxStatus‟u tetikleyecek. Sunucudan yanıt döndüğünde ise AjaxStatus bunu bize Completed! diyerek bildirecek.

Gördüğünüz gibi butona tıkladığımızda CommandButton AJAX request‟i sunucuya gönderirken AjaxStatus bileşeni de bizi bilgilendiriyor. Burada facet‟larda düz metin kullanmak yerine göze hitap etmesi için hareketli imajlar da kullanabilirsiniz. Facet‟lar haricinde AJAX request‟in durumuna göre JavaScript ile bir şeyler yapmak istiyorsanız; onprestart, onstart, oncomplete, onsuccess, onerror event handler‟ları ile bu durumu ele alabilirsiniz. <p:ajaxStatus onstart="alert('Started!')" oncomplete="alert('Completed')"/>


5.3

Calendar Calendar, bileşeni tarih girdilerini değişik yollarla alabilmeyi sağlayan bir bileşendir.

Paging, localization ve ajax desteği de sağlamaktadır.

import java.util.Date; import javax.faces.bean.ManagedBean; @ManagedBean public class CalendarBean { private Date departureDate; private Date arrivalDate; public Date getDepartureDate() { return departureDate; } public void setDepartureDate(Date departureDate) { this.departureDate = departureDate; } public Date getArrivalDate() { return arrivalDate; } public void setArrivalDate(Date arrivalDate) { this.arrivalDate = arrivalDate; } }

Prime Calendar bileşeninin, inline , popup ve popup buton olmak üzere üç farklı çeşidi bulunmaktadır. Inline Calendar, takvimin normal şekilde gösterimini sağlarken , popup; formda tarih istenen alana tıklandığında takvimin popup şeklinde çıkmasını sağlamaktadır. Aşağıdaki örnekte “gidiş tarihli” alan olarak popup calendar görülmektedir.


Popup buton ise calendarın buton ile tetiklendikten sonra görüntülenmesini sağlamaktadır. Aşağıdaki örnekteki “dönüş tarihli” alan popup buton tipindeki Calendara örnektir.


L11N Calendar bileşeni, dahili tarih dönüştürücü içeridiğinden, mevcut tarih patternlerden birinin set edilmesi, istenen tarih formatında girdi alınması için yeterlidir. <p:calendar value="#{dateController.date1}" pattern="dd.MM.yyyy"/> <p:calendar value="#{dateController.date2}" pattern="yy, M, d"/> <p:calendar value="#{dateController.date3}" pattern="EEE, dd MMM,yyyy"/>

Çoklu dil Desteği Calendar Bileşenin locale özelliği set edilerek desteklenen 52 dilden biri kullanılabilmektedir. <p:calendar value="#{dateController.date}" locale="tr"/>

Kullanılabilir diller ve kodları için; Prime Faces User‟s Guide 2607210 dökümanına bakabilirsiniz. Paging Calendar page özelliği kullanılarak aynı anda gösterilmek istenen ay sayısı belirlenebilmektedir.

<p:calendar value="#{dateController.date}" pages="3"/>


Tarih Aralığı Seçilebilir tarih aralığı “mindate” ve “maxdate” değerlerinin set edilmesiyle belirlenebilmektedir.

<p:calendar value="#{dateController.date}" maxdate="01/26/2011" />

mindate="01/09/2011"


5.4

Chart (Çizelge) Bileşenleri PrimeFaces‟la gelen Chart bileşenleri ile, verilerimizi kullanıcılara daha anlaşılır

bir şekilde sunabiliriz. PrimeFaces bu amaçla; Pie Chart, Line Chart, Column Chart, Stacked Column Chart, Bar Chart, Stacked Bar Chart gibi bir çok bileşeni içeriyor. Ayrıca PrimeFaces Chart bileşenleri gerçek zamanlı verileri gösterebilme ve kullanıcı etkileşimlerine yanıt verebilme yeteneğine sahip. PieChart ile birkaç örnek yapalım. PieChart PieChart bileşeni, java.util.List türünden bir koleksiyondaki verileri gösterebiliyor. Koleksiyondaki nesnelerin hangi değerleri üzerinden çizelgeyi oluşturacağını dataField niteliği ile, değerlerin türlerini ise categoryField niteliği ile alıyor. Örnek olarak Expense isminde bir sınıf oluşturalım.


public class Expense { private String type; private int amount; public Expense() { } public Expense(String type, int amount) { super(); this.type = type; this.amount = amount; } // getters and setters }

type alanı harcama türünü, amount alanı ise harcama miktarını gösteriyor. Bean‟ımızı da yaratalım. @ManagedBean public class ExpensesBean { private List<Expense> expenses = new ArrayList<Expense>(); @PostConstruct private void init() { expenses.add(new expenses.add(new expenses.add(new expenses.add(new }

Expense("Rent", 300)); Expense("Food", 100)); Expense("Bills", 150)); Expense("Transportation", 80));

public List<Expense> getExpenses() { return expenses; } }

@PostConstruct ile notlandırdığımız init() metodumuz, bean yaratıldıktan ve bağımlılıkları ilklendirildikten sonra çağrılıyor. Biz burada bean‟de veriyi hardcoded olarak oluşturduk ama ilklendirme aşamasında bir servis referansını elde edip veriyi init() metodu içerisinde servisten çekebilirdik. Şimdi PieChart bileşenini kullanarak çizelgemizi görelim. <p:pieChart value="#{expensesBean.expenses}" var="expense" categoryField="#{expense.type}" dataField="#{expense.amount}" />


Şöyle bir görüntü ile karşılaştık.

PrimeFaces‟ın sunduğu diğer Chart bileşenlerini de benzer şekilde kullanabiliyoruz. Biz şimdi çizelgemizi gerçek zamanlı yapalım. Bunun için PieChart bileşeninin live ve refreshInterval niteliklerini kullanıyoruz. Live, varsayılan olarak false değerini taşıyor ve true yapıldığında gerçek zamanlı olarak refreshInterval niteliğiyle belirtilen zaman aralıklarında sunucuya giderek veriyi çekiyor. Önce ExpensesBean‟ımızda ufak bir değişiklik yapalım. init() methodunu şöyle yapıyoruz: @PostConstruct private void init() { Random rand = new Random(); expenses.add(new Expense("Rent", rand.nextInt(1000))); expenses.add(new Expense("Food", rand.nextInt(1000))); expenses.add(new Expense("Bills", rand.nextInt(1000))); expenses.add(new Expense("Transportation", rand.nextInt(1000))); }

Bu sayede PieChart için bean‟ımız her yaratıldığında, farklı değerler üretilecek. PieChart‟ımızı da şu şekilde değiştirelim: <p:pieChart value="#{expensesBean.expenses}" var="expense" categoryField="#{expense.type}" live="true" refreshInterval="2000" dataField="#{expense.amount}" />

Sunucuya iki saniyede bir istek gönderilecek ve rastgele üretilen değerlerle çizelge günlenecek. İşte bakın:


İlk görüntü:

İki saniye sonra:

Şimdi, PieChart‟ı kullanıcı ile etkileşimli hale getirelim. Kullanıcı çizelgedeki bir alana tıkladığında o alanın güncel değerini sunucudan çekip kullanıcıya bildirelim. Öncelikle ExpensesBean‟e şu metodu ekleyelim: public void itemSelection(ItemSelectEvent event) { String message = expenses.get(event.getItemIndex()).getType() + "'s current value is " + expenses.get(event.getItemIndex()).getAmount(); FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message)); }

Kullanıcı çizelgeye tıkladığında sunucuda bu metod çağrılıyor. Şimdi PieChart bileşenimizin kodunu da değiştirelim. <p:growl id="msg"/> <h:form> <p:pieChart value="#{expensesBean.expenses}" var="expense" categoryField="#{expense.type}" dataField="#{expense.amount}" itemSelectListener="#{expensesBean.itemSelection}" update="msg"/> </h:form>

Sunucudan gelen iletileri görüntülemek için, Growl bileşenini kullandık. Bu koda göre kullanıcı ekrandaki çizelgede bir alana tıkladığında tıklamaya yönelik bilgi ile ExpensesBean‟e yerleştirdiğimiz itemSelection() metodu çağrılıyor. O metodun içerisinde ise tıklanan alanın güncel değerini geriye FacesMessage ile yolluyoruz.


update=”msg” ise bizim için partial rendering olayını yapıyor. Sunucudan yanıt döndüğünde, msg id‟sine sahip bileşeni ki kendisi Growl oluyor yeniden render ediyor, bu bileşen de geri dönen iletiyi aşağıdaki gibi bize gösteriyor. Arka arkaya birkaç tıklamada

her tıklama ile itemSelection çağrılıp

geri

FacesMessage

döndürülüyor.

Diğer Chart bileşenleri için PrimeFaces‟in referans dökümanına göz atabilirsiniz

5.5

CommandButton PrimeFaces‟ın CommandButton bileşeni, standart JSF CommandButton‟ununu

ekstra ajax ve görünüm özellikleriyle genişletiyor. Varsayılan olarak, sunucu tarafına AJAX ile içinde bulunduğu form değerlerini aktarıyor ve partial rendering olayını az önce PieChart‟ta yaptığımız gibi çok kolay bir şekilde ele alıyor. Şimdi yeni birkaç sınıf ekleyerek CommandButton üzerine denemeler yapalım. Önce Book adında bir sınıf yarattık.


package domain; public class Book { private String title; private String author; public Book() { } public Book(String title, String author) { this.title = title; this.author = author; } // getters and setters }

BookBean sınıfımızı da yazalım. @ManagedBean public class BookBean { private Book book = new Book(); public Book getBook() { return book; } public void saveBook() { String msg = book.getTitle() + " of " + book.getAuthor() + " has been saved."; FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(msg)); } }

Şimdi books.xhtml adında bir sayfa oluşturup içerisine kitap ekleme formunu yerleştirelim.


<!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.prime.com.tr/ui" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>Simple Library</title> </h:head> <h:body> <h1>Books</h1> <p:growl id="msg" /> <h:form> <p:panel header="Save Book"> <h:outputText value="Title: " /> <h:inputText value="#{bookBean.book.title}" /> <br /> <h:outputText value="Author: " /> <h:inputText value="#{bookBean.book.author}" /> <br /> <p:commandButton value="Save Book!" actionListener="#{bookBean.saveBook}" update="msg" /> </p:panel> </h:form> </h:body> </html>

Henüz bahsetmedik ama burda Panel bileşenini de kullandık. Kısaca yaptığımız işlem ise formda bir kitaba ait bilgileri almak ve CommandButton kullanarak sunucuya bir Ajax request gönderip BookBean‟in saveBook() metodunu çağırmak. Dönen yanıt ile birlikte de msg id‟li bileşeni günlemek.


İşte, tam da beklediğimiz gibi çalıştı. Şimdi işi bir adım daha götürelim. Eklenen kitapları formun altında bir listede gösterelim. Bunun için DataTable bileşenini kullanacağız. Öncelikle kitapları saklayan sınıfı ve bean‟ini ekleyelim. public class Library { private static List<Book> books = new ArrayList<Book>(); public static void addBook(Book book) { if(book != null) { books.add(book); } } public static List<Book> books() { return new ArrayList<Book>(books); } }

@ManagedBean public class LibraryBean { public List<Book> getBooks() { return Library.books(); } }

Gördüğünüz gibi gayet basit iki sınıf. Şimdi BookBean.saveBook() metodunu şu şekilde yazıyoruz. public void saveBook() { Library.addBook(book); String msg = book.getTitle() + " of " + book.getAuthor() + " has been saved."; FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(msg)); }

Şimdi kullanıcı formdan kaydet butonuna bastığında sunucuda yeni kitabı Library sınıfının içinde saklamış olduk. Son olarak books.xhtml sayfamızı şu şekilde güncelleyelim:


<p:growl id="msg" /> <h:form> <p:panel header="Save Book"> <h:outputText value="Title: " /> <h:inputText value="#{bookBean.book.title}" /> <br /> <h:outputText value="Author: " /> <h:inputText value="#{bookBean.book.author}" /> <br /> <p:commandButton value="Save Book!" actionListener="#{bookBean.saveBook}" update="msg books" /> </p:panel> </h:form> <p:panel header="Books in the Library" id="booksPanel"> <p:dataTable value="#{libraryBean.books}" var="book" id="books"> <p:column> <f:facet name="header"> <h:outputText value="Title" /> </f:facet> <h:outputText value="#{book.title}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="Author" /> </f:facet> <h:outputText value="#{book.author}" /> </p:column> </p:dataTable> </p:panel>

Burada yeni olarak PrimeFaces‟ın DataTable bileşenini kullandık. Dökümanın ilerleyen kısımlarında DataTable‟dan bahsediyoruz. Burada kısaca bahsetsek yeterli. DataTable bileşenimizi LibraryBean‟in books niteliğine bağladık. DataTable books‟tan aldığı kitapları tek tek ekrana bizim için basıyor. Kitap kaydetme formundan da kitabı eklediğimizde, msg id‟li bileşenin yanısıra, books id‟li bileşeni, yani DataTable‟ı da günlüyoruz. Sistem nasıl çalışıyor? CommandButton‟un gönderdiği Ajax requeste yanıt döndüğünde, buton msg ve books bileşenlerini uyarıyor. DataTable‟da tekrar sunucuya giderek kendi verisini güncellemiş oluyor. Bakın şuna benzer bir görüntü elde ediyoruz.


Bakın kitap bilgilerini girip butona bastığımızda sayfa yenilenmeden sunucuya istek gönderilip kitap ekleniyor ve peşine hemen alttaki tablo güncelleniyor. AjaxStatus bileşenini de kullanabilirdik burada.

5.6

CommandLink PrimeFaces‟ın CommandLink bileşeni de, aynı CommandButton‟da olduğu gibi,

standart JSF CommandLink bileşenini varsayılan Ajax özellikleriyle genişletiyor. Üstteki örneğimizden devam edelim. Library sınıfımıza silme metodunu ekleyelim: public static boolean deleteBookWithTitle(String title) { Book book = null; for(Book b : books) { if(b.getTitle().equals(title)) { book = b; break; } } if(book != null) { books.remove(book); } return book != null; }

BookBean sınıfına da hemen şu kod parçasını yerleştiriyoruz.


private String title; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public void deleteBook() { if(Library.deleteBookWithTitle(title)) { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Book with title " + title + " has been deleted.")); } else { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Book not found.")); } }

Şimdi CommandLink kullandığımız şu formu books.xhtml sayfamıza ekliyoruz. <h:form> <p:panel header="Delete Book"> <h:outputText value="Title: " /> <h:inputText value="#{bookBean.title}" /> <br /> <p:commandLink value="Delete Book!" actionListener="#{bookBean.deleteBook}" update="msg books" /> </p:panel> </h:form>


CommandButton ile aynı mantıkla çalıştı.

5.7

ConfirmDialog Şimdi az önce yaptığımız silme işleminden önce kullanıcıdan onay isteyelim.

Bunu elbette PrimeFaces‟in ConfirmDialog bileşeniyle yapacağız. ConfirmDialog bileşeni JavaScript ile onay almanın yerine kullanabileceğimiz bir bileşen. Klasik JavaScript yöntemine artı olarak özelleştirilebilir, pop-up engelleyicilerden kaçınma gibi özelliklere sahip. Silme işlemini yaptığımız form alanını şu kod parçağı ile değiştirelim. <h:form> <p:panel header="Delete Book"> <h:outputText value="Title: " /> <h:inputText value="#{bookBean.title}" /> <br /> <p:commandLink value="Delete Book!" onclick="cd.show()" /> <p:confirmDialog message="Are you sure to delete the book?" header="Confirm Delete" severity="alert" widgetVar="cd"> <p:commandButton value="Yes" actionListener="#{bookBean.deleteBook}" update="msg books" oncomplete="cd.hide()" /> <p:commandButton value="No" onclick="cd.hide()" type="button" /> </p:confirmDialog> </p:panel> </h:form>

Şimdi işler biraz değişti. Artık “Delete Book!” CommandLink‟imiz sunucuya gitmek yerine ConfirmDialog‟u görünür hale getiriyor. ConfirmDialog‟un içine yerleştirdiğimiz CommandButton ise sunucuya gidip silme işlemini gerçekleştiriyor ve daha sonra ConfirmDialog‟u kapatıyor. ConfirmDialog‟un widgetVar niteliğini, istemci tarafında JavaScript işlemleri için kullandık. ConfirmDialog‟ün gözükmesi esnasında farklı efektler de kullanabiliriz. Hali hazırda blind, bounce, clip, drop, explode, fade, fold, highlight, puff, pulsate, scale, shake, size, slide ve transfer efektleri mevcut. showEffect ve hideEffect niteliklerini kullanarak, ConfirmDialog‟un açılış ve kapanışlarına bu efektlerden birini yerleştirebiliriz. Ayrıca severity niteliğini alert yerine info değeriyle de kullanabiliriz.


5.8

DataTable PrimeFaces‟ın DataTable bileşeni, JSF‟in standart DataTable‟ını, sayfalama,

sıralama, satır seçimi, filtreleme gibi bir çok genel ihtiyaç için sunduğu kolay çözümlerle çok güzel bir şekilde genişletiyor. Daha önceki örneklerimizde DataTable‟ı zaten kullanmıştık. Şimdi de onun üstüne eklemeler yaparak ilerleyelim. Kullandığımız DataTable‟ı, kendimize göre biraz özelleştirmekle başlayalım. books.xhtml sayfasındaki DataTable tanımına, errorMessage=”An error occured while loading books”, loadingMessage=”Books are being loaded” ve emptyMessage=”There are no books in the library!” değerlerini ekleyelim. Bunlar isimlerinden de anlaşılacağı üzere, tabloya verileri yükleme esnasında hata oluştuğunda, tabloya verileri yükleme esnasında ve tabloda gösterilecek veri olmadığı durumlarde gösterilecek iletilerdir. Dinamik ve Dinamik Olmayan DataTable DataTable, iki ana modda çalışır. Varsayılan olarak dinamik olmayan moda ayarlı olup, dinamik olmayan modda çalıştığında, tamamen bir istemci tarafı bileşeni olarak çalışır. Dinamik modda iken ise, DataTable, verileri getirirken arka taraftaki Bean‟a gider. Örneğin dinamik olmayan bir DataTable‟da paging yapıldığında, DataTable veriyi başta çeker ve istemci tarafında tuttuğu veri üzerinde paging yapar. Dinamik DataTable ise, sayfalama yaparken göstereceği veriyi almak için Ajax ile sunucuya gider. DataTable‟ın dinamik olup olmama özelliğini dynamic niteliği ile ayarlayabilirsiniz. Küçük veri setleri için dinamik olmayan DataTable bileşenleri, gayet iyi iş görür.


Sayfalama (Paging) DataTable, (varsayılan olarak kapalı olan) sayfalama özelliği ile birlikte gelir. Sayfalama özelliğini açmak için paginator niteliğine true değeri verilmelidir. Şimdi kitapları listelediğimiz DataTable‟ımızda sayfalamayı açalım. Bunun için şu değerleri books.xhtml‟deki DataTable tanımına ekliyoruz. paginator="true" rows="2"

Her sayfada iki satır gözükecek şekilde ayarladık.

Gördüğünüz gibi, verimiz arttığında DataTable otomatik olarak sayfalamayı yaptı. PrimeFaces DataTable‟ında sayfalama, birçok yönden özelleştirilebiliyor. Sayfalama Şablonu özelliği ile, yukarıdaki ekran görüntüsünde tablonun üstünde yer alan sayfalama alanlarını ihtiyacınıza göre özelleştirebilirsiniz. Bunu yapmak için DataTable‟ın paginatorTemplateOption niteliğini kullanıyoruz. İhtiyacımıza özel paginatorTemplateOption değerini oluştururken, sayfalama alanında gösterilecek olan elemanları, FirstPageLink, LastPageLink, NextPageLink, PageLinks, CurrentPageReport, RowsPerPageDropDown değerleriyle sıralayabiliyoruz. Örneğin varsayılan şekilde düzenlenen sayfalama alanı, “{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}” şeklinde. Ayrıca sayfalama alanının tablonun altında mı, üstünde mi, yoksa hem altında hem de üstünde mi


gösterileceğini paginatorPosition niteliğine verebileceğimiz top, bottom ve both değerleriyle ayarlıyoruz. Satır Seçimi PrimeFaces DataTable, satır seçimini ele almayı kolaylaştıran birçok hazır çözüm içeriyor. Ben bunlardan birtanesini burada ele alacağım. Şimdiye kadarki kısımda, kütüphanemize kitap eklemiş ve kitap silmiştik. Şimdi bir de kütüphanedeki kitapların özelliklerini değiştirmeyi ele alalım. Book sınıfımıza integer türünden id isimli bir nitelik koyup getter, setter metodlarını yazalım.Library sınıfımıza şu metodu ekleyelim: public static Book getBookById(int id) { for(Book b : books) { if(b.getId() == id) { return b; } } return null; }

Library bean sınıfımıza da şu kod kısmını ekleyelim: private Book selectedBook = new Book();

public Book getSelectedBook() { return selectedBook; } public void setSelectedBook(Book selectedBook) { this.selectedBook = selectedBook; } public void modifyBook() { Book book = Library.getBookById(selectedBook.getId()); if(book != null) { book.setAuthor(selectedBook.getAuthor()); book.setTitle(selectedBook.getTitle()); FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Book has been successfully modified.")); } else { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("You have selected an invalid book.")); } }

books.xhtml sayfasında da şu değişiklikleri yapıyoruz:


<p:growl id="msg" /> <h:form> <p:panel header="Save Book" toggleable="true"> <h:outputText value="Title: " /> <h:inputText value="#{bookBean.book.title}" /> <br /> <h:outputText value="Author: " /> <h:inputText value="#{bookBean.book.author}" /> <br /> <p:commandButton value="Save Book!" actionListener="#{bookBean.saveBook}" update="msg :booksPanel" /> </p:panel> </h:form> <h:form> <p:panel header="Delete Book" toggleable="true"> <h:outputText value="Title: " /> <h:inputText value="#{bookBean.title}" /> <br /> <p:commandLink value="Delete Book!" onclick="cd.show()" /> <p:confirmDialog message="Are you sure to delete the book?" header="Confirm Delete" severity="alert" widgetVar="cd"> <p:commandButton value="Yes" actionListener="#{bookBean.deleteBook}" update="msg :booksPanel" oncomplete="cd.hide()" /> <p:commandButton value="No" onclick="cd.hide()" type="button" /> </p:confirmDialog> </p:panel> </h:form> <p:panel header="Books in the Library" id="booksPanel"> <h:form id="booksForm"> <p:dataTable value="#{libraryBean.books}" var="book" id="books" errorMessage="An error occured while loading books" loadingMessage="Books are being loaded" emptyMessage="There are no books in the library!" paginator="true" rows="2" selection="#{libraryBean.selectedBook}" selectionMode="single"> <p:column> <f:facet name="header"> <h:outputText value="Title" /> </f:facet> <h:outputText value="#{book.title}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="Author" /> </f:facet> <h:outputText value="#{book.author}" /> </p:column> </p:dataTable> <p:commandButton value="Modify" oncomplete="mdfyDlg.show()" update="modifyPanel" /> </h:form> </p:panel> <p:dialog header="Modify Book" widgetVar="mdfyDlg"> <p:outputPanel id="modifyPanel"> <h:form> <h:inputHidden value="#{libraryBean.selectedBook.id}" /> <h:outputText value="Title: " /> <h:inputText value="#{libraryBean.selectedBook.title}" /> <br /> <h:outputText value="Author: " /> <h:inputText value="#{libraryBean.selectedBook.author}" /> <br /> <p:commandButton value="Save Modifications" actionListener="#{libraryBean.modifyBook}" update="msg :booksPanel" oncomplete="mdfyDlg.hide()" /> </h:form> </p:outputPanel> </p:dialog>


Books sayfamızda yaptığımız değişiklikliklerden biraz bahsedelim. Öncelikle DataTable bileşenimizi Form bileşeni içerisine aldık. Bunun sebebi kitap listesi üzerinde bir seçim yapıp Modify butonuna bastığımızda seçtiğimiz kitabın sunucuya Ajax ile yapılan bir istekle gönderilmesi. Ek olarak bir de Dialog bileşenini kullandık. Modify butonuna basıldığında Dialog bileşenin içinin seçilen kitap ile güncellenmesini ve Dialog bileşeninin ekranda görüntülenmesini sağlıyoruz. Dialog‟ta kitap bilgilerini günleyip Save Modifications butonuna basıldığında ise LibraryBean‟in modifyBook metoduyla kitap bilgilerini güncelleyip kitap listesinin yeniden görüntülenmesini sağlıyoruz.

5.9

Dialog Dialog, kolay kullanıcı etkileşimi sağlayan, özellikle datatable vb. bileşenlerde bileşen

elemanlarına ait yaratma,günleme,silme gibi işlemlerde kullanılabilen ajax desteği olan panel bileşenidir. Varsayılan olarak görünebilir değildir. Görüntülenebilmesi için çocuk bileşenlere ihtiyaç duymaktadır.


<h:form> <h:panelGrid columns="2" style="margin-top:10px"> <h:outputLabel value="Adınız:" for="name" /> <h:inputText id="name" value="#{dialogDataBean.name}"/> <h:outputLabel value="Soyadınız:" for="surname" /> <h:inputText id="surname" value="#{dialogDataBean.surname}"/> <p:commandButton value="Dialog" update="display" oncomplete="dialog.show()" /> <p:ajaxStatus style="width:16px;height:16px;"> <f:facet name="start"> <h:graphicImage value="../design/ajaxloading.gif" /> </f:facet> <f:facet name="complete"> <h:outputText value="" /> </f:facet> </p:ajaxStatus> </h:panelGrid> <p:dialog header="Bilgiler" widgetVar="dialog" showEffect="fold" hideEffect="fold" height="150"> <h:panelGrid id="display" columns="2" cellpadding="5"> <h:outputText value="Adınız:" /> <h:outputText value="#{dialogDataBean.name}"/> <h:outputText value="Soyadınız:" /> <h:outputText value="#{dialogDataBean.surname}"/> </h:panelGrid> </p:dialog> </h:form>


import javax.faces.bean.ManagedBean; @ManagedBean public class DialogDataBean { private String name; private String surname; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; }

}

Dialog etiketli buton tetiklendiğinde, dialogDataBean a ait name ve surname alanarına değerler atanarak bean güncellenmektedir. Açılan dialog penceresinde de bu bean a ait özellkiler listelenmektedir.


Ajax Etkileşimi Dialog bileşeni ajaxlı işlemleri içinde kullanılabilir. Aşağıdaki örnekte ajax ile dialogun beraber kullanımı görülmektedir. <h:form> <h:panelGrid columns="2" style="margin-top:10px"> <h:outputLabel value="Adınız ve Soyadınız:" for="name" /> <h:outputLabel id="name" value="#{dialogDataBean.name} #{dialogDataBean.surname}" for="name" /> <h:outputLink value="#" onclick="dialog.show()"> Lütfen Adınızı soyadınızı giriniz. </h:outputLink> </h:panelGrid> <p:dialog header="Bilgiler" widgetVar="dialog" showEffect="fold" hideEffect="fold" position="450,500" height="200"> <h:panelGrid id="display" columns="2" cellpadding="5"> <h:outputText value="Adınız:" /> <h:inputText value="#{dialogDataBean.name}"/> <h:outputText value="Soyadınız:" /> <h:inputText value="#{dialogDataBean.surname}"/> <p:commandButton value="Tamam" update="name" oncomplete="dlg.hide();" /> </h:panelGrid> </p:dialog> </h:form>


Dialog gösterildiğinde, kullanıcıdan aldığı form bilgileriyle “Tamam” butonuna basılmasıyla id=”name” olarak tanımlı alanını günlemektedir.


Effect Dailog “showEffect” ve “hideEffect” alanları aşağıdaki değerlere set edilerek dialogun açılması ve gizlenmesi animasyon şeklinde dönüştürülebilmektedir. 

blind

bounce

clip

drop

explode

fade

fold

highlight

puff

pulsate

scale

shake

size

 

slide transfer

Dialog Penceresindeki tüm alanların doldurup doldurulmadığının kontrolü için Javascript kullanabilmektedir. Örneğin; DialogDataBean „ a eklenen ;

public void doRequest(ActionEvent actionEvent) { RequestContext context = RequestContext.getCurrentInstance(); boolean successful = true; if( name == "" || surname == "") successful = false; context.addCallbackParam("successfull", successful); }

metodu; Dialogtaki butonun “actionListener “ olarak set edilir. <p:commandButton value="Tamam" update="name" actionListener="#{dialogDataBean.doRequest}" oncomplete="handleDialogRequest(xhr, status, args)" />


<script type="text/javascript"> function handleDialogRequest(xhr, status, args) { if (args.validationFailed || !args.successfull) { jQuery('#dialog').effect("shake", { times : 3 }, 100); }else { if (args.successfull) dialog.hide(); //else // some codes here.. } } </script>

Scripti dialog tanımının altına koyulduğunda; Dailog ta “Tamam” tuşuna basıldığında istek sunucuya gitmekte ve Bean içinde tanımlanan doRequest metodunda; successful parametresi set edilerek, dialog içerisinde herhangi bir alan boş bırakıldığında pencerenin “shake” efekti görüntüleyerek kapanmadığı, tüm alanların doldurulması durumunda;

if( name == "" || surname == "") successful = false;

Bloğuna dallanmayacağından, istemciye succesful parametresi true dönecek ve scriptte tanımlanan;

if (args.successfull) dialog.hide();

Koşulunu geçerli olacak ve dialog pencersi kapanacaktır.


5.10 InputMask InputMask, inputText gibi alanlara, belirlenen formata göre girdi girilmesini sağlamaktadır. <h:form> <p:panel header="AutoComplete" toggleable="true"> <h:panelGrid columns="2" cellpadding="5"> <h:outputText value="Tarih" /> <p:inputMask value="#{maskBean.phone}" mask="01/01/2010"/> <h:outputText value="Telefon Numarası" /> <p:inputMask value="#{maskBean.phone}" mask="(999) 999-9999"/> <h:outputText value="Vergi Numarası" /> <p:inputMask value="#{maskBean.taxId}" mask="999-99-9999" /> <h:outputText value="Ürün Anahtarı" /> <p:inputMask value="#{maskBean.productKey}" mask="a*-999-a999" /> </h:panelGrid> </p:panel> </h:form>

Mask alanına verilen girdi örüntüsü ile, kullanıcı tanımlanan formatta girdi girmeye zorlanmaktadır.

<p:inputMask

value="#{maskBean.productKey}" mask="a*-999-a999" />

Yukarıdaki örnekte ; mask =”a*-999-a999” örüntüsü “a*” ile , ilk iki girdinin karakter olması gerektiğini ikinci örüntü grubu “999”ile , 3.4. ve 5. Girdi değerlerinin sayı olabileceğini, “a999” örüntüsü ile de, bu örüntünün ilk değerin karakter, sonraki üç değerin ise rakam olması gerektiğini belirtmektedir.

Ör: et-123-s456


5.11 LightBox LightBox , imaj ve multimedya içeriğin gösterilmesi için diğer JSF bileşenlerini örten bir bileşendir. <p:lightBox> <h:outputLink value="../fb1.jpg" title="Fenerbahçe - 1"> <h:outputText> 1

</h:outputText>

</h:outputLink> <h:outputLink value="../fb2.jpg" title="Fenerbahçe – 2 "> <h:outputText> 2

</h:outputText>

</h:outputLink> <h:outputLink value="../fb3.jpg" title="Fenerbahçe - 3"> <h:outputText> 3

</h:outputText>

</h:outputLink> <h:outputLink value="../fb4.jpg" title="Fenerbahçe - 4"> <h:outputText> 4 </h:outputLink> </p:lightBox>

</h:outputText>


Linklerden herhangi birine tıklandığında ilgili multimedya içerik lightBox ile gösterilerek diğer JSF bileşenlerinin arkaplanda kalması sağlanmaktadır.


5.12 OutputPanel OutputPanel, diğer bileşenler için kapsayıcı, yer tutucu (place holder) bir nitelik taşıyor. Kitap örneğimizden devam edelim. Kitap listesini gösterdiğimiz tabloyu ve onu içeren paneli kitap listesi boşken hiç göstermeyip kullanıcı yukarıdan bir kitap eklediğinde görünür kılmak, liste boşalınca tekrar gizlemek isteseydik, muhtemelen, DataTable‟ın rendered değerini kitap listesininin boyuna göre falan atayacaktık. Peki, DataTable‟ı içeren panelde şöyle bir şey olduğunu farzedelim: rendered="#{libraryBean...}"

Şimdi books sayfamızı tekrar çalıştıralım. Yeni bir kitap eklediğinizde kitap sunucudaki listeye eklendiği halde DataTable‟ın görünür hale gelmediğini göreceksiniz. Sayfayı yenilemeyi bir denileyin, eklenen kitap görünecek. Peki neden böyle oldu? Herhangi bir JSF bileşeni render edilmediğinde, Partial Page Rendering mekanizması, sayfada güncellenecek olan markup bulunmayacağı için düzgün çalışmayabilir. Mesela üstteki örnekte, Panel kitap listesi boş iken render edilmeyeceğinden sayfada ona dair bir markup yok, CommandButton da update yapmaya çalışırken sayfada tabloyu bulamadığı için güncelleyemiyor. Bu sorunu çözmek için OutputPanel‟i kullanıyoruz. Az önce rendered niteliği koyduğumuz paneli aşağıdaki kod parçası ile çevreleyelim. <p:outputPanel id="booksPlaceHolder"></p:outputPanel>

Şimdi de Ekleme ve Silme forumlarındaki CommandButton‟ların update değerlerindeki booksPanel‟i booksPlaceHolder ile değiştirelim. Sayfayı şimdi tekrar çalıştırın. Oldu değil mi?

5.13 Panel Panel, diğer JSF bileşenleri için bir gruplandırma bileşenidir. Ajax event listener özelliği ile Ajax desteği de sağlamaktadır. <p:panel> <!-- //Child components here... --> </p:panel>


Header and Footer Header and Footer alanları set edilerek panel a header ve footer metinleri konabilmektedir.

<p:panel header="Panel

Header"

footer="Panel

Footer">

<br/> <br/> <br/> <br/> <br/> </p:panel>

Aşağıda header ve footer alanları set edilmiş çıktı görülmektedir.


Açılır Kapanır Panel (Toggling) Toggleable özelliği true yapılarak panelin açılır kapanır olması sağlanabilmektedir.

<p:panel header="Panel Header" footer="Panel Footer" toggleable="true"> <br/> <br/> <br/> <br/> <br/> </p:panel>

Toogle + ya basıldığında panel içeriği görüntülenmektedir;


Panelin açılıp kapanması durumlarının kontrol edilmesi istendiğinde ; ajax toggleListener özelliği kullanılarak “onToggleUpdate” ile güncellenmek istenen JSF bileşenleri belirlenebilmektedir. <p:panel header="Panel Header" footer="Panel Footer" toggleable="true" toggleListener="#{panelBean.handleToggle}" onToggleUpdate="msg"> </p:panel <p:messages id="msg">

5.14 Password Strength Password Strength bileşeni , şifreyle giriş modülü bulunan sistemlerde kullanılabilen, şifre belirleme için görsel geribildirim sağlayan kullanışlı bileşenlerden biridir.

import javax.faces.bean.ManagedBean; @ManagedBean public class LoginBean { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }


Weak Password;

Good Password;


Strong Password;

5.15 Growl Growl kullanıcıya aynı h:messages gibi geribildirim sağlayan widgetlardır. requiredMessages özelliğine sahip olan JSF bileşenleri için (örneğin inputText ), kolay geri bildirim importsağlanabilir. javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.context.FacesContext; @ManagedBean public class LoginBean { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String doLogin() { if(!(username=="" && password=="")){ FacesMessage fm = new FacesMessage (FacesMessage. SEVERITY_ERROR,"Sisteme giriş yaplıdı", "Sisteme giriş yaplıdı"); FacesContext.getCurrentInstance() .addMessage("Sisteme giriş yaplıdı", fm); } return null; } }


Burada loginBean içinde kullanıcı geçerli giriş yaptığında, growl un görüntüleyeceği mesaj server tarafında belirlenmektedir. <p:panel id="panel" header="Üye Girişi"> <p:growl /> <h:form> <h:panelGrid columns="2"> <h:outputLabel for="username" value="Kullanıcı Adı:" /> <h:inputText id="email" value="#{loginBean.username}" required="true" requiredMessage="Lütfen kullanıcı adınızı girin." /> <h:outputLabel for="password" value="Parola: " /> <h:inputSecret id="password" value="#{loginBean.password}" required="true" requiredMessage="Lütfen parolanızı girin." /> </h:panelGrid> <p:commandButton value="Giriş" action="#{loginBean.doLogin}" ajax="false" /> </h:form> </p:panel>

Aşağıda örnek çıktı görülmektedir.


inputText in required alanı kullanıldığında ise istek sunucuya gitmeden growl ile kullanıcı uyarılabilir.


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.