[英]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.