如何知道要在MVC视图中更新哪个字段?

时间:2015-11-10 19:14:40

标签: java swing model-view-controller

我正在使用一个使用MVC设计模式的Java Swing应用程序。主视图有一个与之关联的模型,程序逻辑完成。通过Setters中的setChanged()和NotifyObservers(),将通知View。在View中,有一个方法

的实现
public void update(Observable o, Object arg) 

处理视图的更新。但是我怎么知道更新 - 方法视图中的哪个字段要更新? o是Model本身,arg可以是NotifyObservers(Object)的参数。

但是说我在模型中有三个int值,需要在视图中显示。如果我比较

if (o.field1 == arg) {
   ...
} else if (o.field2 == arg) {
   ...
}

如果它是字段,则不进行比较,但它会比较整数的值,因此开发人员不知道要更新哪个字段。

所以我可以做两件事:

  1. 使用Integer(非int)并且如果我想比较该值,我使用.equals(Integer)并将Integer的对象赋予NotifyChanged。但我必须记住,在模型中我必须与类的方法进行比较,而在我的程序的其他部分我必须比较via ==,所以我可能不知道使用哪种方法。

  2. 将带有变量名称的字符串 - 可能是全局常量 - 传递给NotifyChanged()。

  3. 正确和推荐的方式是什么?提前致谢。

1 个答案:

答案 0 :(得分:1)

当我创建Swing MVC应用程序时,我遵循3个简单的规则。

  • 视图从模型中读取值。
  • 视图不会更新模型。
  • 控制器更新模型并刷新/重新绘制视图。

模型不了解视图或控制器。

这是一个使用MVC模式的非常简单的Swing应用程序。

enter image description here

Swing应用程序生成4个随机数。每个数字都有一个与数字相关的颜色。

DataModel类定义数字/颜色值。 DisplayModel类创建一个DataModel列表。该列表包含4个DataModel实例。

此列表已排序并传递给视图。当您左键单击New Numbers按钮时,会生成一组新的4数字/颜色并传递给视图。

以下是代码:

package com.ggl.testing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SortFrames implements Runnable {

    private DisplayModel displayModel;

    private JPanel[] panels;

    private JLabel[] labels;

    public SortFrames() {
        this.displayModel = new DisplayModel();
    }

    @Override
    public void run() {
        List<DataModel> dataModels = displayModel.getDisplayModel();

        JFrame frame = new JFrame("Sort Frames");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel mainPanel = new JPanel();

        panels = new JPanel[dataModels.size()];
        labels = new JLabel[dataModels.size()];

        for (int i = 0; i < dataModels.size(); i++) {
            DataModel dataModel = dataModels.get(i);
            panels[i] = new JPanel();
            panels[i].setBackground(dataModel.getBackgroundColor());
            panels[i].setPreferredSize(new Dimension(30, 30));

            labels[i] = new JLabel(getDisplayText(dataModel));
            labels[i].setBackground(dataModel.getBackgroundColor());
            labels[i].setForeground(dataModel.getForegroundColor());

            panels[i].add(labels[i]);
            mainPanel.add(panels[i]);
        }

        JPanel buttonPanel = new JPanel();

        JButton submitButton = new JButton("New Numbers");
        submitButton.addActionListener(new SubmitActionListener(displayModel,
                this));

        buttonPanel.add(submitButton);

        frame.add(mainPanel, BorderLayout.CENTER);
        frame.add(buttonPanel, BorderLayout.SOUTH);

        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
    }

    public void update() {
        List<DataModel> dataModels = displayModel.getDisplayModel();

        for (int i = 0; i < dataModels.size(); i++) {
            DataModel dataModel = dataModels.get(i);

            panels[i].setBackground(dataModel.getBackgroundColor());

            labels[i].setBackground(dataModel.getBackgroundColor());
            labels[i].setForeground(dataModel.getForegroundColor());
            labels[i].setText(getDisplayText(dataModel));
        }
    }

    private String getDisplayText(DataModel dataModel) {
        if (dataModel.getNumber() == 12) {
            return "-";
        } else {
            return Integer.toString(dataModel.getNumber());
        }
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new SortFrames());
    }

    public class DisplayModel {

        private Random random;

        private List<DataModel> displayModel;

        public DisplayModel() {
            this.displayModel = new ArrayList<>();
            this.random = new Random();
            createDisplayModel();
        }

        public void createDisplayModel() {
            displayModel.clear();

            for (int i = 0; i < 4; i++) {
                int number = random.nextInt(13);
                int colorNumber = random.nextInt(2);
                Color backgroundColor = Color.BLACK;
                Color foregroundColor = Color.WHITE;
                if (colorNumber == 1) {
                    backgroundColor = Color.WHITE;
                    foregroundColor = Color.BLACK;
                }
                displayModel.add(new DataModel(number, colorNumber,
                        backgroundColor, foregroundColor));
            }

            Collections.sort(displayModel, new DataModelComparator());
        }

        public List<DataModel> getDisplayModel() {
            return displayModel;
        }

    }

    public class DataModel {
        private final int number;
        private final int colorNumber;

        private final Color backgroundColor;
        private final Color foregroundColor;

        public DataModel(int number, int colorNumber, Color backgroundColor,
                Color foregroundColor) {
            this.number = number;
            this.colorNumber = colorNumber;
            this.backgroundColor = backgroundColor;
            this.foregroundColor = foregroundColor;
        }

        public int getNumber() {
            return number;
        }

        public int getColorNumber() {
            return colorNumber;
        }

        public Color getBackgroundColor() {
            return backgroundColor;
        }

        public Color getForegroundColor() {
            return foregroundColor;
        }

    }

    public class DataModelComparator implements Comparator<DataModel> {

        @Override
        public int compare(DataModel o1, DataModel o2) {
            if (o1.getNumber() < o2.getNumber()) {
                return -1;
            } else if (o1.getNumber() > o2.getNumber()) {
                return 1;
            } else {
                if (o1.getColorNumber() < o2.getColorNumber()) {
                    return -1;
                } else if (o1.getColorNumber() > o2.getColorNumber()) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }

    }

    public class SubmitActionListener implements ActionListener {

        private DisplayModel displayModel;

        private SortFrames sortFrames;

        public SubmitActionListener(DisplayModel displayModel,
                SortFrames sortFrames) {
            this.displayModel = displayModel;
            this.sortFrames = sortFrames;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            displayModel.createDisplayModel();
            sortFrames.update();
        }

    }
}