【问题标题】:App design to MVC pattern应用程序设计到​​ MVC 模式
【发布时间】:2013-08-23 13:46:00
【问题描述】:

Swing: how to get container bind to JRadioButton? 这个问题的答案让我想到了一个简单的应用程序设计中的 MVC。我描述了一个应用程序的总体思路以及我对这个案例的 MVC 模式的看法。

小应用说明

此应用程序允许用户添加由名称和描述组成的简单记录。按下“添加”按钮后,它们将作为两个标签和单选按钮添加到面板中,以便编辑记录。用户可以将他的列表保存在配置文件中(序列化为 xml、属性或其他位置)。

我对如何在这里应用 MVC 的想法

模型

  • 记录名称和描述字段

  • 带有序列化机制的配置文件

查看

  • 包含多个面板(记录列表)的面板 - 每条记录一个(单选按钮 + 2 个用于名称和描述数据的标签)

控制器

  • 2 个带有标签的文本框和一个添加记录的按钮

  • 用于编辑记录的按钮

目前没有代码示例(稍后我会提供)。我不想着急,我想了解我是否朝着正确的 MVC 方向前进,或者在实施之前应该改变什么。

更新

代码示例

*MainClass*:
public class RecordsControl extends JFrame {
    private RecordsModel model;
    private RecordsController controller;
    private RecordsControlView view;

    public RecordsControl() {
        super("Records Control");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        initMVC();
        getContentPane().add(view);

        pack();
        setMinimumSize(new Dimension(250, 500));
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    }

    private void initMVC() {
        model = new RecordsModel();
        view = new RecordsControlView(controller);
        controller = new RecordsController(model, view);
    }
}

*Model*:
public class RecordsModel {
    //Record class has only two fields String::name and String::description
    private List<Record> RecordsList;

    public RecordsModel() {
        RecordsList = new ArrayList<Record>();
    }

    public void addRecord(String name, String description) {
        RecordsList.add(new Record(name, description));
    }

    public List<Record> getRecordsList() {
        return RecordsList;
    }
}

*View*:
public class RecordsControlView extends JPanel {
    private final RecordsController controller;

    private JLabel nameLabel;
    private JLabel descrLabel;
    private JTextField nameField;
    private JTextField descrField;
    private JButton addButton;
    private JButton editButton;
    private JButton deleteButton;
    private JPanel recordsListPanel;

    public RecordsControlView(RecordsController controller) {
        super();
        this.controller = controller;
        achievNameLabel = new JLabel("Name: ");
        achievDescrLabel = new JLabel("Description: ");
        achievNameField = new JTextField(15);
        achievDescrField = new JTextField(15);
        addButton = new JButton("Add");

        initGUI();
        initListeners();
    }

    private void initListeners() {
        addButton.addActionListener(controller);
    }

    private void initGUI() {
        //Main Panel
        this.setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();

        //name panel
        //...BoxLayout label + panel

        //description panel
        //...BoxLayout label + panel

        //Records list Panel
        //...Vertical BoxLayout

        //Add widgets to GridBagLayout
        //Name panel
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.insets = new Insets(5, 5, 2, 2);
        add(namePanel, constraints);

        //Description Panel
        constraints.gridx = 0;
        constraints.gridy = 1;
        constraints.insets = new Insets(0, 5, 5, 2);
        add(descrPanel, constraints);

        //Add button
        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.gridheight = 2;
        constraints.gridwidth = 1;
        constraints.insets = new Insets(5, 0, 5, 5);
        constraints.fill = GridBagConstraints.VERTICAL;
        add(addButton, constraints);

        //Records List panel
        constraints.gridx = 0;
        constraints.gridy = 2;
        constraints.gridwidth = GridBagConstraints.REMAINDER;
        constraints.gridheight = GridBagConstraints.REMAINDER;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.insets = new Insets(0, 5, 5, 5);
        add(recordsListPanel, constraints);
    }

    public JButton getAddButton() {
        return addButton;
    }

    public void addRecord(JPanel record) {
        recordsListPanel.add(record);
    }
}

public class RecordsView extends JPanel {
    private static ButtonGroup radioButtons = new ButtonGroup();

    private JRadioButton radioButton;
    private JLabel name;
    private JLabel description;

    public RecordsView() {
        super();
        radioButton = new JRadioButton();
        name = new JLabel();
        description = new JLabel();

        initGUI();
    }

    private void initGUI() {
        radioButtons.add(radioButton);

        setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();

        constraints.gridx = 0;
        constraints.gridy = 0;
        add(radioButton, constraints);

        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.weightx = 1.0;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        add(name, constraints);

        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.weightx = 1.0;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        add(description, constraints);
}

*Controller*:
public class RecordsController implements ActionListener{
    private final RecordsModel model;
    private final RecordsControlView view;

    public RecordsController(RecordsModel model, RecordsControlView view) {
        this.model = model;
        this.view = view;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == view.getAddButton()) {
            RecordsView record = new RecordsView();
            view.add(record);
            view.updateUI();
        }
    }
}

【问题讨论】:

标签: java swing model-view-controller


【解决方案1】:

首先,我们先说一下actually MVC is

型号

它是一个抽象层,包含许多类来处理应用程序逻辑。从那时起,它是一个抽象的关注点,这意味着模型定义没有严格的规则,直到它的范围在business logic

查看

视图应直接从模型中读取数据并准备输出。每个模型都应该有一个单一的视图。

控制器

也称为Editor,它负责更改Model 的状态,这意味着它应该只负责定义/重新定义您正在处理的公共变量。

如果您的应用程序满足这样的条件,

- 控制器写入ModelView 并且不执行其他操作

- 视图只包含显示逻辑

- 由应用程序核心类组成的模型

那么你就在正确的轨道上——你正确地应用了 MVC。

一个基本实现的例子,

class ModelLayer
{
    public void ModelLayer()
    {
        this.age = 1;
    }

    public int getAgeFromDb()
    {
        return this.age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }
}

class View
{
     public void View(ModelLayer modelLayer)
     {
          this.modelLayer = modelLayer;
     }
     
     public string render()
     {
         return this.modelLayer.getAgeFromDb();
     }
}

class Controller
{
     public void Controller(ModelLayer modelLayer)
     {
          this.modelLayer = modelLayer;
     }
     
     public void onSaveBtnClick()
     {
          this.modelLayer.setAge(2);
     }
}

【讨论】:

  • +1 用于详细说明控制器;正如here 所述,我认为多个视图可能会监听同一个模型。
  • @Dave Just,我已经添加了我的示例,但控制器连接到视图(按钮侦听器)时遇到了一些困难。
  • @Dragon 你做的有点不对,看看:http://r.je/mvc-in-php.html(PHP无关)
猜你喜欢
  • 2012-08-26
  • 2014-03-07
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多