簡體   English   中英

將 GUI 與 Java 中的邏輯分離

[英]Separating GUI from logic in Java

我瀏覽了大量關於如何將 GUI 與 Java 中的其余程序邏輯分開的文章和(imo 太復雜)示例,老實說,我仍然沒有任何線索。

有人可以在這個簡單的例子中提示我如何做到這一點,只需一個按鈕嗎?

假設 Window 類中有一個按鈕:

JButton firstButton = new JButton("My first button");      
btnCreateProject.setBounds(100, 100, 80, 30);
frame.getContentPane().add(firstButton);

假設這個按鈕將調用 Employee 類的構造函數。 所以,我可以這樣做:

JButton firstButton = new JButton("My first button");
firstButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
      .....constructor calling, and rest of the code....
   }
});
btnCreateProject.setBounds(100, 100, 80, 30);
frame.getContentPane().add(firstButton);

但這正是我想要的。 我希望我的 Window 類只是純粹的 GUI,帶有按鈕、單選框和其他東西,以及它的屬性。 而已。 我希望在另一個類中擁有所有偵聽器,比如說 Controller,並且從這個類中我將調用所有需要的方法。

有人能給我一個例子來說明如何用這個簡單的按鈕來做到這一點嗎? 非常感謝。

你是在區分程度,而不是種類。 您的 GUI 代碼不能與程序邏輯完全分離,否則它將成為現代藝術的靜態作品。

各種 AWT/Swing 偵聽器類確實將 GUI 與邏輯分離成完全獨立的類。 但是,您不需要將偵聽器實現為匿名內部類; 也許將它們實現為普通的頂級類對您來說會更好。 或者,您可能會發現它適合您通過實現Action接口的類對程序行為進行建模。 然后您可以通過控件的setAction()方法將這些行為分配給控件(按鈕、菜單項)。

然而,無論如何,設置您的 GUI 的代碼必須以某種方式了解 GUI 組件和需要連接到它們的邏輯,否則它無法完成它的工作。

這是一個新類的構造函數:

new ActionListener() {
   public void actionPerformed(ActionEvent e) {
      .....constructor calling, and rest of the code....
   }
}

你可以創建一個類:

公共類 ActionListenerTest 實現 ActionListener { ... }

然后做這樣的事情:

firstButton.addActionListener(new ActionListenerTest());

您應該做的是在適當的地方編寫一個方法來訪問數據模型(假設您有一個)並在那里完成工作,然后從按鈕單擊調用該方法。

firstButton.addActionListener(e -> logicClass.addEmployeeToFirm());

或者您可以編寫一個自定義偵聽器來調用/執行該邏輯(實現 ActionListener 的類)。

我的項目也遇到了同樣的問題,但最終我決定使用我在 android 編程中學到的一個概念。 下面是它的工作原理:

我為我的對象添加了一個標識(對於按鈕、菜單等,我使用 setActionCommand 方法),因此我可以對不同組件的相同操作使用相同的標識符。

我的所有對象都使用它們的 getActionCommand 作為cmd和對象本身調用一個控制器。 在控制器中,我控制 cmd 並從中調用正確的方法。

控制 GUI 和程序的其余部分要容易得多。

它像魅力一樣對我有用。

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;

/**
 *
 * @author Pasban
 */
public class ActionListenerTest {

    public static void main(String[] args) {
        JButton b1 = new JButton("My first button");
        JButton b2 = new JButton("My first button");

        b1.setActionCommand("BTN_1");
        b2.setActionCommand("BTN_2");

        //put this in another class
        ActionListener controller = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String cmd = e.getActionCommand().toUpperCase().trim();
                System.out.println(cmd);

                //System.out.println(e.getSource()); // cast to anything you have in your mind about the caller

                if (cmd.equals("BTN_1")) {
                    System.out.println("BUTTON 1 is clicked");
                } else if (cmd.equals("BTN_2")) {
                    System.out.println("BUTTON 2 is clicked");
                }
            }
        };

        b1.addActionListener(controller);
        b2.addActionListener(controller);

        JDialog frame = new JDialog();
        frame.setSize(new Dimension(300, 300));
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);


        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(b1);
        frame.getContentPane().add(b2);

        frame.setVisible(true);

    }
}

你總是可以實現類似的東西:

Controller.handleActionEvent(ActionEvent e);

並將您的按鈕點擊委托給那個。 如果你不想讓你的控制器知道 Swing,你總是可以創建一些接口並將 Swing ActionEvent 包裝在你創建的某種事件中。

或者只是在 UI 類中實現一個觀察者(監聽器)模式(或者你可以有一個位於中間的“注冊”類)。 單擊按鈕時,UI 會將事件委托給所有已注冊的偵聽器(實現您定義的某些接口)。 因此,控制器(客戶端)只會告訴 UI“在單擊按鈕 X 時通知我”,而 UI 只會委托給所有相關方。

因此,UI 不需要知道要顯式調用誰。 但管制員必須知道他想聽誰的話。

在您的控制器中,創建一個方法

操作get[Operation]Handler(); //填寫[Operation]將你的按鈕功能應該做什么

它返回一個實現適當功能的內部類。

然后,在您的 GUI 代碼中,執行

JButton b = ...;
b.setAction(controller.get[Operation]Handler());

暫無
暫無

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

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