1

这个问题的答案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();
        }
    }
}
4

1 回答 1

2

首先,让我们从真正的 MVC开始说起:

模型

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

看法

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

控制器

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

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

- 控制器写入 aModel或 aView并且不执行任何其他操作

- 视图只包含显示逻辑

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

那么你就走在了正确的轨道上——你正确地应用了 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);
     }
}
于 2013-08-21T12:15:40.040 回答