将GUI与Jav​​a中的逻辑分开

时间:2015-04-10 18:56:00

标签: java user-interface model-view-controller controller

我浏览了大量文章和(非常复杂的)如何将GUI与Jav​​a中的其他程序逻辑分开的示例,并且完全诚实,我仍然没有线索。

有人可以只用一个按钮就这个简单的例子给我一个如何做到这一点的提示吗?

让我们说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,包括按钮,收音机盒和其他东西,以及它的属性。而已。我想让所有听众都在另一个班级,让我们说控制器,从这个班级我会调用所有需要的方法。

有人能举例说明如何使用这个简单的按钮吗?非常感谢你。

6 个答案:

答案 0 :(得分:2)

你正在划分程度,而不是善意。您的GUI代码不能完全与程序逻辑分离,否则它将是现代艺术的静态工作。

各种AWT / Swing监听器类 将GUI从逻辑分离到完全独立的类中。但是,您不需要将侦听器实现为匿名内部类;也许你觉得把它们作为普通的顶级类来实现会更好。或者,您可能会发现通过实现Action接口的类来模拟程序行为是合适的。然后,您可以通过控件'setAction()方法将这些行为分配给控件(按钮,菜单项)。

然而,任何方式,设置GUI的代码必须以某种方式了解GUI组件和需要连接到它们的逻辑,否则它无法完成它的工作。

答案 1 :(得分:1)

我的项目遇到了同样的问题,但最后我决定使用我在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);

    }
}

答案 2 :(得分:0)

这是新类的构造函数:

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

你可以创建一个类:

public class ActionListenerTest实现ActionListener { ... }

然后做这样的事情:

firstButton.addActionListener(new ActionListenerTest());

答案 3 :(得分:0)

你应该做的是编写一个适当的方法来访问datamodel(假设你有一个)并在那里完成工作,然后从按钮点击调用方法。

firstButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
      logicClass.addEmployeeToFirm();
   }
});

或者您可以编写一个自定义侦听器来调用/执行该逻辑(实现ActionListener的类)。

答案 4 :(得分:0)

在控制器内部,创建一个方法

Action获取[Operation] Handler(); //填写[操作]将按钮功能应该做什么

返回一个实现正确功能的内部类。

然后,在您的GUI代码中,执行

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

答案 5 :(得分:0)

你总是可以实现类似的东西:

Controller.handleActionEvent(ActionEvent e);

并将您的按钮委托给它。如果你不希望你的控制器知道Swing,你总是可以创建一些接口并将Swing ActionEvent包装在你创建的某种事件中。

或者只是在UI类中实现一个Observer(Listener)模式(或者你可以有一个位于中间的“注册表”类)。单击该按钮时,UI会将事件委派给所有已注册的侦听器(实现您定义的某个接口)。所以Controller(客户端)只会告诉用户界面“点击按钮X时通知我”,UI只会委托给所有感兴趣的各方。

因此,UI不需要知道明确调用谁。但是控制器必须知道他想听谁。