Swing应用程序中的CDI事件可将UI与事件处理分离
在享受了幾年圍繞CDI構(gòu)建我的代碼的樂趣之后,使用它根據(jù)眾所周知的模式來構(gòu)造我的代碼非常自然。 CDI是一種旨在在Java EE應(yīng)用程序服務(wù)器中使用的依賴項(xiàng)注入機(jī)制,這可能被視為不利。 但是,我想證明它可以在Java SE應(yīng)用程序中使用并且具有巨大的潛力。
CDI的優(yōu)點(diǎn)在于,它不僅僅是注入機(jī)制。 除此之外,它還提供了一種優(yōu)雅而強(qiáng)大的事件傳遞機(jī)制。 該功能可以與Swing很好地結(jié)合起來,以基于MVC模式構(gòu)建GUI應(yīng)用程序。
確實(shí)有可能有效地將CDI和Swing框架結(jié)合起來,以快速,清晰的結(jié)構(gòu)來構(gòu)建Java GUI應(yīng)用程序。 請(qǐng)繼續(xù)關(guān)注以了解如何…
首先,稱為Weld的CDI的參考實(shí)現(xiàn)也作為單獨(dú)的庫分發(fā)。 您可以將其添加到您的項(xiàng)目中并開始使用它。 與運(yùn)行應(yīng)用程序的標(biāo)準(zhǔn)方式唯一的不同是,您需要啟動(dòng)一個(gè)Weld容器,它很簡單:
import org.jboss.weld.environment.se.StartMain; ...public static void main(String[] args) { StartMain.main(args);}要將Weld添加到您的Maven應(yīng)用程序中,只需添加以下依賴項(xià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組件和模型之間實(shí)現(xiàn)綁定。 這個(gè)想法是在應(yīng)該進(jìn)行數(shù)據(jù)更新時(shí)觸發(fā)自定義事件,而不是直接修改數(shù)據(jù)。 控制器觀察觸發(fā)的事件并根據(jù)事件數(shù)據(jù)執(zhí)行操作。 然后,這些操作將操縱數(shù)據(jù)模型,并將有關(guān)數(shù)據(jù)更新的通知發(fā)送到視圖。 參見下圖:
MVC周期從Swing動(dòng)作偵聽器開始,該動(dòng)作偵聽器構(gòu)成一個(gè)動(dòng)作對(duì)象并將其作為CDI事件發(fā)出。 動(dòng)作偵聽器未綁定到任何控制器代碼–控制器已使用CDI機(jī)制綁定到事件。 這將GUI代碼與業(yè)務(wù)邏輯完全分離。 以下代碼段響應(yīng)按鈕單擊事件,并發(fā)出一個(gè)向計(jì)數(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ā)事件的新對(duì)象以及所有依賴項(xiàng)。 我對(duì)MainFrame使用了@ApplicationScoped ,以確保所有代碼都在相同的實(shí)例上運(yùn)行。
這里要提到的一件事:為了使CDI工作,必須由CDI創(chuàng)建MainFrame的實(shí)例,而不是直接使用其構(gòu)造函數(shù)。 這是通過將其注入到已經(jīng)存在的bean中實(shí)現(xiàn)的,例如觀察啟動(dòng)時(shí)發(fā)出的ContainerInitialized事件的bean。
CDI機(jī)制將事件分派給任何偵聽器方法,該方法偵聽此類事件。 我們創(chuàng)建一個(gè)控制器應(yīng)用程序,并將代碼放入觀察者方法中,如下所示:
public class Application { ...public void updateValueWhenChangeValueAction(@Observes final ChangeValueAction action) {... // controller action} ... }最后,控制器更新模型并在必要時(shí)觸發(fā)視圖更新。 如果進(jìn)一步講,我們可能會(huì)觸發(fā)控制器的更新事件,該事件將由視圖(在本例中為MainFrame組件)觀察到。 甚至構(gòu)建模型,該模型在更新時(shí)會(huì)自動(dòng)觸發(fā)CDI事件。 因此,控制器和視圖將完全分離,僅響應(yīng)事件-GUI事件從View到Controller方向流動(dòng),數(shù)據(jù)更新事件從Controller / Model到View流動(dòng)。總而言之,CDI事件機(jī)制對(duì)于構(gòu)建非常方便一個(gè)View與業(yè)務(wù)邏輯分離的MVC Swing應(yīng)用程序。 這可以通過在Weld CDI容器中運(yùn)行應(yīng)用程序(1行代碼),從Swing偵聽器觸發(fā)動(dòng)作(2行代碼)并觀察動(dòng)作(在任何啟用CDI的類上使用單個(gè)方法)來實(shí)現(xiàn)。 這些動(dòng)作采用一種數(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
總結(jié)
以上是生活随笔為你收集整理的Swing应用程序中的CDI事件可将UI与事件处理分离的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 加法结合律的公式 什么是加法结合律
- 下一篇: glassfish5_将Glassfis