MVC模型中的多线程GUI

时间:2015-12-01 19:48:14

标签: java multithreading swing model-view-controller swingworker

我在MVC模型中经历了大量有关GUI的帖子,以及在哪里放置代码以及在哪个线程中。

MadProgrammer和trashgod让我朝着正确的方向前进,但有些事我还是不明白。

在我的主要课程中,我有以下代码

import java.awt.EventQueue;

import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import common.InitParameters;
import common.OraLogin;
import common.ThresholdValues;


public class cmtNew implements Runnable {
    public static void main(String[] args) {
        EventQueue.invokeLater(new cmtNew());
    }

    @Override
    public void run() {

        // Set look and feel of GUI
        try {
            UIManager.setLookAndFeel(
                    UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException
                | IllegalAccessException | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        // Login to database
        loginDb();  

        // Init system parameters
        initParameters();

        // Set up the application
        CmtModel theModel       = new CmtModel();
        CmtGui theGui           = new CmtGui();
        CmtControl theControl   = new CmtControl(theGui,theModel);

//        Model model           = new Model();
//        View view             = new View(model);
//        Control control       = new Control(model, view);

        // Show GUI
        theGui.setVisible(true);

    }

    /**
     * Login to database
     */
    private static void loginDb(){
        OraLogin login = new OraLogin();
        try {
            login.userLogin();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Unable to log in to database: "+e.getMessage());
            System.exit(0);
        }
    }

    /**
     * Init parameters
     */
    private static void initParameters(){
        try {
            InitParameters initParameters = new InitParameters();
            ThresholdValues thresholdValues = new ThresholdValues();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Unable initialize environment parameters: "+e.getMessage());
            System.exit(0);
        }
    }
}

我在Control的构造函数中启动了许多SwingWorker线程来处理对数据库的慢速查询。

问题:

  1. 初始化模型,视图,控件时注释掉的部分来自于trashgod https://stackoverflow.com/a/3072979/4654417的MVCgame示例,为什么要将模型传递给视图?

  2. GUI更新应该在EDT中完成,但将控件,模型,视图init放在代码中(显然是常见的做法),所有这些都将在EDT上... ,或?

  3. 我已将SwingWorker线程放在Control中。对还是错?好还是坏?

  4. 作为非OO程序员的背景我仍然很难将事件处理的概念包裹起来。 我已经以控制告诉Model查询数据库中的数据的方式实现了MVC。然后控制询问Model for data并将其传递给Update in update方法。我明白了......,这是错误的做法。

  5. 我怎么相信应该工作的是Control以某种方式告诉Model查询数据/读取文件或其他什么。如果Model成功完成,它会触发一个“嘿,我有新数据”的事件。 View(或Control)侦听事件并以某种方式更新EDT线程中的gui。

    我只是无法弄清楚事件流量以及谁(模型,控制,视图)正在做什么以及如何做。而且,我已经研究了Oracle的众多教程,但我仍然没有得到它。

    干杯

1 个答案:

答案 0 :(得分:3)

我希望我并不反对MadProgrammer和trashgod先前曾说过的任何事情。

  

为什么要将模型传递给视图?

模型必须保持对视图的无知。这允许模型与多种类型的视图一起使用(Swing,Web,智能手机)。

但是,视图可以模型中读取。视图最多不更新模型。更新模型是控制器的工作。

  

GUI更新应该在EDT中完成,但是将控件,模型,视图,init放在代码中(显然是常见的做法),所有这些都将在EDT上进行?

构建和更新GUI必须在EDT上完成。通常,您将拥有侦听GUI更改的动作侦听器和/或项侦听器。监听器中的代码将更新模型,并在必要时重新/重新验证GUI。

基本上,你的听众是你的控制者。我建议每个GUI组件使用一个或多个侦听器,而不是尝试处理多个GUI组件的超级侦听器。

  

我已将SwingWorker线程放在Control中。

通常,SwingWorker线程是控制器的一部分。通常,我将线程放在与其他所有类不同的类中。

  

我已经以Control告诉Model查询数据库中的数据的方式实现了MVC。然后控制询问Model for data并将其传递给View in a update method。

以下是我在Swing GUI中实现MVC的方法。

  • 视图可以从模型中读取。
  • 视图可能无法更新模型。
  • 控制器将更新模型。
  • 控制器将重新绘制/重新验证视图。

为了更好地了解如何在Swing应用程序中实现MVC模型,请查看我的Retro Snake Game文章。