[英]MVC - Observer/Observable pattern in Java Swing
我正在嘗試基於MVC構建Swing用戶界面,並且對此主題有兩個問題。 提出問題的最佳方法是借助一個簡單的示例。
假設我們有一個帶有一個JButton和3個JTextField的JDialog。 當按下該按鈕時,我希望關閉此JDialog並打開另一個需要來自3個JTextFields的數據的JDialog。
做到這一點的簡單方法(只需編寫代碼片段,無需過多地煩擾您):
myButton.addMouseListener(new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent evt){
firstFrame.setVisible(false);
secondFrame.setData(jTextField1.getText(),jTextField2.getText(),jTextField3.getText());//just sending the data to the new window, would be this or something similar
secondFrame.setVisible(true);
}});
或類似的東西。
第一個問題:如果我不使用匿名內部類,而是決定為偵聽器使用單獨的類,我如何將數據從3個JTextFields傳遞給mouseListener類? 除了在Listener類中保留視圖的引用之外,還有其他選擇嗎?
繼續進行,給出MVC模式:
第二個問題:我認為在不涉及模型的情況下,偵聽器(根據MVC的控制器)調用另一個窗口是有意義的,這是我的工作。 但是需要從一個窗口傳遞到下一個窗口的數據(來自3JTextFields的數據)不應該通過模型嗎? 就像讓第一個窗口將數據保存在模型中一樣,然后在第二個窗口需要它們時從模型中請求它們。
第三個問題:我正在考慮使用觀察者/可觀察模式。 在此示例中將如何使用它打開最后一個窗口? 我的意思是因為(我認為)Controller是打開第二個窗口的類,這意味着必須監聽監聽器,並且第二個窗口必須是觀察者,以便監聽器說
notifyObservers("openSecondWindow");
然后第二個窗口會看到並打開自己?
最后:我聽說PropertyChangeListener也可以工作,並且有時使用Observer / Observable模式。 您對此有何想法,特別是關於我的例子。
我很困惑..
感謝您的時間。
我不確定Java的特定方面。 但是談論OOP,通過事件驅動的設計使您的應用程序分離是很合理的。 因此,與其直接處理這些組件,不如您編寫代碼那樣觸發事件: notifyObservers("openSecondWindow");
。
但是,您不需要通過模型層即可。 相反,您應該有一個代表給定事件的event
類,並在event
類中設置上述字段的值。
就像是:
exampleEvent.setProperty1('blah').setProperty2('blah2');
notify('openSecondFrame', exampleEvent);
不久前,我已經發布了有關此事件驅動問題的問題:
PHP:我是否將事件驅動的編程與信號感知的接口(信號和插槽/觀察者模式)混合在一起?
您可能對閱讀有幾個鏈接感興趣(它是PHP,但該概念適用於OOP)。
因此,遵循這個概念,創建一個EventHandler
組件來管理那些事件和信號是一個好主意。
但是再次考慮到我不精通Java。 這只是關於OOP。
如果我不使用匿名內部類,而是決定為偵聽器使用單獨的類,該如何將數據從3個JTextFields傳遞給mouseListener類?
您單獨的MouseAdapter
類將具有一個構造函數,您可以在其中將所需的內容從JPanel
類傳遞給MouseAdapter
類。
這段代碼是針對ActionListener
,但是我認為總體思路將向您展示如何編寫MouseAdapter
類。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import com.ggl.project.planner.model.Planner;
import com.ggl.project.planner.model.Project;
import com.ggl.project.planner.view.CreateUpdateProjectDialog;
import com.ggl.project.planner.view.ProjectPlannerFrame;
public class CreateProjectActionListener implements ActionListener {
protected Planner planner;
protected Project project;
protected ProjectPlannerFrame frame;
public CreateProjectActionListener(ProjectPlannerFrame frame,
Planner planner, Project project) {
this.frame = frame;
this.planner = planner;
this.project = project;
}
@Override
public void actionPerformed(ActionEvent event) {
CreateUpdateProjectDialog dialog =
new CreateUpdateProjectDialog(frame, project, true);
if (dialog.isOkPressed()) {
planner.setProjectOpen(true);
}
}
}
我猜想,在不涉及模型的情況下,偵聽器(根據MVC的控制器)可以調用另一個窗口,這是我想的工作。 但是需要從一個窗口傳遞到下一個窗口的數據(來自3JTextFields的數據)不應該通過模型嗎? 就像讓第一個窗口將數據保存在模型中一樣,然后在第二個窗口需要它們時從模型中請求它們。
我不確定我是否理解您的問題。 構建GUI時,我具有一個或多個數據模型,這些數據模型表示GUI中的值。 這些數據模型的實例通過組成GUI的大多數組件傳遞。
應用程序的其余部分通過模型訪問GUI信息。
在我作為第一個問題的答案的一部分發布的ActionListener
類中,有兩個數據模型Project
和Planner
。 Project
特定於特定項目,而Planner
是GUI全局的。
我正在考慮使用Observer / Observable模式。 在此示例中將如何使用它打開最后一個窗口?
Swing已經內置了偵聽器模式。您可以將動作偵聽器用於自己的動作。 您甚至可以將自己的偵聽器類型添加到Swing中,盡管這是一個痛苦的過程。 擴展JPanel
使其成為JCroppingPanel
時,我添加了自己的偵聽器類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.