php cdi_Swing应用程序中的CDI事件将UI和事件处理分离
php cdi
在愉快地圍繞CDI構(gòu)建我的代碼幾年之后,使用它根據(jù)眾所周知的模式來構(gòu)造我的代碼非常自然。 CDI是一種旨在在Java EE應(yīng)用程序服務(wù)器中使用的依賴項注入機(jī)制,這可能被視為不利。 但是,我想證明它可以在Java SE應(yīng)用程序中使用并且具有巨大的潛力。
CDI的優(yōu)點在于,它不僅僅是注入機(jī)制。 除此之外,它還提供了一種優(yōu)雅而強(qiáng)大的事件傳遞機(jī)制。 該功能可以與Swing很好地結(jié)合起來,以基于MVC模式構(gòu)建GUI應(yīng)用程序。
確實有可能有效地將CDI和Swing框架結(jié)合起來,以快速,清晰的結(jié)構(gòu)來構(gòu)建Java GUI應(yīng)用程序。 請繼續(xù)關(guān)注以了解如何…
首先,稱為Weld的CDI參考實現(xiàn)也作為獨立的庫分發(fā)。 您可以將其添加到您的項目中并開始使用它。 與運行應(yīng)用程序的標(biāo)準(zhǔn)方式唯一的不同是,您需要啟動一個Weld容器,它很簡單:
import org.jboss.weld.environment.se.StartMain; ...public static void main(String[] args) { StartMain.main(args);}要將Weld添加到您的Maven應(yīng)用程序中,只需添加以下依賴項: org.jboss.weld.se : weld-se : 2.2.9.Final 。 要執(zhí)行您的應(yīng)用程序代碼,應(yīng)將其放入觀察ContainerInitialized事件的方法中:
public void start(@Observes ContainerInitialized startEvent) {// code which would be usually in the main() method }在上面的方法中,您可以初始化應(yīng)用程序,構(gòu)建并顯示GUI并等待Swing事件。
從這里開始有趣的部分。 我將使用CDI事件機(jī)制使用觀察者模式在Swing組件和模型之間實現(xiàn)綁定。 這個想法是在應(yīng)該進(jìn)行數(shù)據(jù)更新時觸發(fā)自定義事件,而不是直接修改數(shù)據(jù)。 控制器觀察觸發(fā)的事件并根據(jù)事件數(shù)據(jù)執(zhí)行操作。 然后,這些操作將操縱數(shù)據(jù)模型,并將有關(guān)數(shù)據(jù)更新的通知發(fā)送到視圖。 參見下圖:
MVC周期從Swing動作偵聽器開始,該動作偵聽器構(gòu)成一個動作對象并將其作為CDI事件發(fā)出。 動作偵聽器未綁定到任何控制器代碼–控制器已使用CDI機(jī)制綁定到事件。 這將GUI代碼與業(yè)務(wù)邏輯完全分離。 以下代碼段響應(yīng)按鈕單擊事件,并發(fā)出一個向計數(shù)器添加值的操作:
@ApplicationScoped class MainFrame extends javax.swing.JFrame {@Inject Event<ChangeValueAction> changeValueAction; ...void addButtonActionPerformed(java.awt.event.ActionEvent evt) {changeValueAction.fire(ChangeValueAction.plus(getValue()));} ... }在這里,我們需要記住,CDI事件的觀察者將被創(chuàng)建為所有觸發(fā)事件的新對象以及所有依賴項。 我對MainFrame使用了@ApplicationScoped ,以確保所有代碼都在相同的實例上運行。
這里要提到的一件事:為了使CDI工作,必須由CDI創(chuàng)建MainFrame的實例,而不是直接使用其構(gòu)造函數(shù)。 這是通過將其注入到現(xiàn)有的bean中實現(xiàn)的,例如觀察啟動時發(fā)出的ContainerInitialized事件的bean。
CDI機(jī)制將事件分派給任何偵聽器方法,該方法偵聽此類事件。 我們創(chuàng)建一個控制器應(yīng)用程序,并將代碼放入觀察者方法中,如下所示:
public class Application { ...public void updateValueWhenChangeValueAction(@Observes final ChangeValueAction action) {... // controller action} ... }最后,控制器更新模型,并在必要時觸發(fā)視圖更新。 如果進(jìn)一步講,我們可能會觸發(fā)控制器的更新事件,該事件將由視圖(在本例中為MainFrame組件)觀察到。 甚至構(gòu)建模型,該模型在更新時會自動觸發(fā)CDI事件。 因此,控制器和視圖將完全分離,僅響應(yīng)事件-GUI事件從View到Controller方向流動,而數(shù)據(jù)更新事件從Controller / Model到View流動。總而言之,CDI事件機(jī)制對于構(gòu)建非常方便一個View與業(yè)務(wù)邏輯分離的MVC Swing應(yīng)用程序。 這可以通過在Weld CDI容器中運行應(yīng)用程序(1行代碼),從Swing偵聽器觸發(fā)動作(2行代碼)并觀察動作(在任何啟用CDI的類上使用單個方法)來實現(xiàn)。 這些動作采用一種數(shù)據(jù)Bean的形式,它本身完全不是太多的代碼行。
- 可以在github上找到完整的示例: https : //github.com/OndrejM/JavaDecoupledUI-CDI
翻譯自: https://www.javacodegeeks.com/2016/02/cdi-events-swing-application-decouple-ui-event-handling.html
php cdi
總結(jié)
以上是生活随笔為你收集整理的php cdi_Swing应用程序中的CDI事件将UI和事件处理分离的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: drill apache_Apache
- 下一篇: php cdi_CDI中的事务异常处理