簡體   English   中英

MVC-Java Swing中的觀察者/可觀察模式

[英]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類中,有兩個數據模型ProjectPlanner Project特定於特定項目,而Planner是GUI全局的。

第三題

我正在考慮使用Observer / Observable模式。 在此示例中將如何使用它打開最后一個窗口?

Swing已經內置了偵聽器模式。您可以將動作偵聽器用於自己的動作。 您甚至可以將自己的偵聽器類型添加到Swing中,盡管這是一個痛苦的過程。 擴展JPanel使其成為JCroppingPanel時,我添加了自己的偵聽器類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM