JavaServer Faces Olay Model ve Mimarisi: Özelleştirilmiş Eylem ve Değer Değişikliği Dinleyicileri

JavaServer Faces olay model ve mimarisine giriş mahiyetindeki bir önceki yazıda ifade ettiğim gibi, JSF geliştiricisi, bir eylem olayı ve dinleyicisini, yine bir değer değişikliği olayı ve dinleyicisini, anılan eylemlere tepki vermek üzere programlayabilir, ihtiyaç duyuyor ise kendi özel dinleyici sınıflarını da oluşturabilir.

Bu yazıda, JSF geliştiricisinin kendi özel eylem ve değer değişikliği dinleyici sınıflarını nasıl oluşturabileceğini göstermeyi amaçlıyorum.

 

ActionListener Arayüzü

JavaServer Faces, ActionSource arayüzünü implement etmiş, bir eylem başlatan bileşenlerden kaynaklanan olayları yönetmek için bir eylem olayı(ActionEvent) ve buna karşılık gelen bir eylem dinleyicisi(ActionListener) kullanmaktadır.

JSF geliştiricisi, bir ActionEvent’ı yönetmek için kendi özel eylem dinleyici sınıfını oluşturmak istediğinde, oluşturulacak bu sınıf, Faces’ın ActionEvent olaylarını yönetmek için varsayılan olarak hizmete sunduğu ActionListener arayüzünü implement etmelidir.

 

ActionListener.java


public interface ActionListener extends FacesListener {
  public void processAction(ActionEvent ae) throws AbortProcessingException;
}

MyActionListener.java


public class MyActionListener implements ActionListener {

  @Override
  public void processAction(ActionEvent event) throws AbortProcessingException {
    ...
  }
}

ActionListener arayüzünün, kendisini implement etmiş sınıflarca override edilmesi gereken, ActionEvent tipinde parametre alan processAction metodu vardır ve ActionEvent’ın dinleyici sınıfına teslim edilmesiyle birlikte bu metod içine düşülür. Dolayısıyla JSF geliştiricisinin, bir eylem olayı dinleyicisini, bu olaya tepki vermek üzere programlayabilmesi keyfiyeti, tam olarak bu metod içinde gerçekleşmektedir.

Söz konusu processAction metodu, ActionSource bileşenleri kaynaklı ActionEvent’ları alır ve varsa metod bağlamasını etkinleştirir.

Varsayılan ActionListener kullanıldığında, bir bileşenle ilintili eylem olayını yakalamak için hiçbir şey yapması gerekmeyen(böyle bir durumda JSF geliştiricisi sadece, varsayılan ActionListener’ın işleyeceği metodu, bileşenin action ya da actionListener nitelikleri vasıtasıyla kayda geçirir) JSF geliştiricisi, kendi özel eylem dinleyici sınıfını kullanmak istediğinde bu sınıfı kayda geçirmelidir.

Bu kayda geçirme global ya da bileşen odaklı olabilir. Global ile kastettiğim, JSF geliştiricisinin Faces konfigürasyon dosyası ya da programatik olarak özel eylem dinleyici sınıfını kayda geçirerek, ilgili sınıfı eylem olaylarının kendisine teslim edileceği dinleyici sınıf olarak belirlemesidir. Bir başka deyiş ile, bu şekilde kayda geçirilen dinleyici sınıfı, JSF’in varsayılan ActionListener’ının yerini alır ve JSF uygulaması içinde ActionEvent’lar bu dinleyici sınıfa teslim edilir.

 

Özel eylem dinleyici sınıfının kayda geçirilmesi

JavaServer Faces’ın, ActionEvent’ları yönetmek için hizmete sunduğu varsayılan ActionListener yerine, özel bir eylem dinleyicisi sınıfı kullanılmak istendiğinde, bu sınıf Faces konfigürasyon dosyasıyla ya da programatik olarak kayda geçirilmelidir.

faces-config.xml


<application>
    <action-listener>
        com.kodcu.action.listener.MyActionListener
    </action-listener>
</application>

Programatik kayda geçirme


Application app = FacesContext.getCurrentInstance().getApplication();
app.setActionListener(myActionListener);

 

Aşağıda MyGlobalActionListener sınıfı yer almakta.


public class MyGlobalActionListener implements ActionListener {

private ActionListener actionListener;

    public MyGlobalActionListener(ActionListener actionListener) {
        this.actionListener = actionListener;
    }
    
    @Override
    public void processAction(ActionEvent event) throws AbortProcessingException {
        System.out.println("Eylem başlatan bileşen: " + event.getComponent().getClientId());
        actionListener.processAction(event);
    }
}

Override edilen processAction metodu içinde, ActionEvent parametresi üzerinden, olayı başlatan bileşenin clientID’sinin çıktılandığını, ardından da bileşenin metod bağlamasının etkinleştirdiğini görüyoruz. Görünüm tarafında 2 ayrı commandButton bileşenini kullandığımız ve bunlara sırasıyla tıkladığımız bir senaryoda

 

index.xhtml


<h:form id="myGlobalActionListelerForm">
    <h:commandButton id="commandButton1" value="Buton 1" action="#{myBean.test}"/>
    <h:commandButton id="commandButton2" value="Buton 2" action="#{myBean.test}"/>
 </h:form>

aşağıdakine benzer bir çıktı alırız:

Eylem başlatan bileşen: myGlobalActionListelerForm:commandButton1
Eylem başlatan bileşen: myGlobalActionListelerForm:commandButton2

Görüldüğü gibi Faces burada, ActionEvent’ı teslim etmek için, kayda geçirdiğimiz özel eylem dinleyici sınıfını kullanmıştır.

 

Özel eylem dinleyici sınıfının bileşen(ler)e özel kayda geçirilmesi

JSF geliştiricisi, kendi özel eylem dinleyici sınıfını, JavaServer Faces’ın varsayılan ActionListener’ını değiştirmeden, belirlediği bileşen(ler)e özel olarak da kayda geçirip kullanabilir.

Özel bir eylem dinleyici sınıfını, bir bileşenle ilişkilendirmenin yolu, JavaServer Faces’ın çekirdek küpüthanesine ait actionListener imini kullanmaktır. Söz konusu imin type niteliğine, dinleyici sınıfın tam sınıf adı geçirilir ve böylece, imin ebeveyni olan UIComponent ile ilintili eylem olayları için bir eylem dinleyici sınıfı kayda geçirilmiş olur.

 

index.xhtml


<h:commandButton id="commandButton1" value="Buton 1">
   <f:actionListener type="com.kodcu.action.listener.MyActionListener"/>
</h:commandButton>

MyActionListener.java


public class MyActionListener implements ActionListener {

    @Override
    public void processAction(ActionEvent event) throws AbortProcessingException {
        System.out.println("Eylem başlatan bileşen: " + event.getComponent().getClientId());
    }
}

 

ValueChangeListener Arayüzü

JavaServer Faces, EditableValueHolder arayüzünü implement etmiş bileşenlerden kaynaklanan olayları yönetmek için bir değer değişikliği olayı(ValueChangeEvent) ve buna karşılık gelen bir değer değişikliği dinleyicisi(ValueChangeListener) kullanmaktadır.

JSF geliştiricisi, bir ValueChangeEvent’ı yönetmek için kendi özel değer değişikliği dinleyici sınıfını oluşturmak istediğinde, oluşturulacak bu sınıf, Faces’ın ValueChangeEvent olaylarını yönetmek için varsayılan olarak hizmete sunduğu ValueChangeListener arayüzünü implement etmelidir.

 

ValueChangeListener.java


public interface ValueChangeListener extends FacesListener {
   public void processValueChange(ValueChangeEvent vce) throws AbortProcessingException;
}

MyValueChangeListener


public class MyValueChangeListener implements ValueChangeListener {

    @Override
    public void processValueChange(ValueChangeEvent changeEvent) throws AbortProcessingException {
     …
    }
}

ValueChangeListener arayüzünün, kendisini implement etmiş sınıflarca override edilmesi gereken, ValueChangeEvent tipinde parametre alan processValueChange metodu vardır ve ValueChangeEvent’in dinleyici sınıfına teslim edilmesiyle birlikte bu metod içine düşülür. Bir başka deyiş ile bu metod, EditableValueHolder bileşenleri kaynaklı ValueChangeEvent’ları alır. Dolayısıyla JSF geliştiricisinin, bir değer değişikliği dinleyicisini, bu olaya tepki vermek üzere programlayabilmesi keyfiyeti, tam olarak bu metod içinde gerçekleşmektedir.

Varsayılan ValueChangeListener kullanıldığında, bir bileşenle ilintili değer değişikliği olayını yakalamak için hiçbir şey yapması gerekmeyen(böyle bir durumda JSF geliştiricisi sadece, varsayılan ValueChangeListener’ın işleyeceği metodu, bileşenin valueChangeListener niteliği vasıtasıyla kayda geçirir) JSF geliştiricisi, kendi özel değer değişikliği dinleyici sınıfını kullanmak istediğinde bu sınıfı kayda geçirmelidir. ValueChangeListener örneğinde kayda geçirme, dinleyiciyi bir bileşenle ilişkilendirme işlemidir.

Özel bir değer değişikliği dinleyicisini, bir bileşenle ilişkilendirme işlemi, özel bir eylem dinleyicisini, bir bileşenle ilişkilendirmeye benzer. JavaServer Faces’ın çekirdek küpüthanesine ait valueChangeListener imi, bir değer değişikliği dinleyicisini kendisine en yakın ebeveyn UIComponent ile ilişkilendirir.

Söz konusu imin type niteliğine, dinleyici sınıfın tam sınıf adı geçirilir ve böylece, imin ebeveyni olan UIComponent ile ilintili değer değişikliği olayları için bir dinleyici sınıfı kayda geçirilmiş olur.

 

index.xhtml


<h:inputText value="Değer Değişikliği">
    <f:valueChangeListener type="com.kodcu.change.listener.MyValueChangeListener"/>
</h:inputText>

MyValueChangeListener.java


public class MyValueChangeListener implements ValueChangeListener {

    @Override
    public void processValueChange(ValueChangeEvent changeEvent) throws AbortProcessingException {
        System.out.println("*********** " + changeEvent.getNewValue().toString() + " ***********");

    }
}

Çalışma zamanında, inputText bileşenin içinde yer aldığı form post edildiğinde eğer bir değer değişikliği söz konusu ise, JSF yaşam döngüsünün ilgili evresinde MyValueChangeListener’ın processValueChange metodu içine düşülecek ve bileşenin sahip olduğu yeni değer çıktılanacaktır.

No Comments

Post a Comment

Comment
Name
Email
Website