【发布时间】:2019-09-10 02:20:34
【问题描述】:
在 MVC 模式中,这是模型通知视图的最佳选择(如果首先这是正确的方法),在模型存储的所有数据字段中,只有几个字段被更新。特别是当我们只想更新视图的特定字段时。
我目前正在使用带有观察者/订阅者 (JAVA Swing) 的 MVC 模式,如下所述:https://stackoverflow.com/a/6963529 但是当模型更新时,它会在调用 update() 函数时更改视图中的所有内容,因此无法确定为了只更新视图中的必填字段,模型中的哪个字段发生了变化。
我读过这个主题:https://softwareengineering.stackexchange.com/a/359008 和这个:https://stackoverflow.com/a/9815189,我认为它很有用,但是对于后面,我不太明白如何在变量上设置 propertyChangeListener(int,float , 等等)。也与此相关:https://stackoverflow.com/a/9815189
软件开始运行的Main类:
public class Main {
public static void main(String[] args) {
Model m = new Model();
View v = new View(m);
Controller c = new Controller(m, v);
c.initController();
}
}
所以我在模型上的代码是这样的:
public class Model extends Observable {
//...
private float speed;
private int batteryPercentage;
public float getSpeed() {
return speed;
}
public void setSpeed(float speed) {
this.speed = speed;
setChanged();
notifyObservers();
}
public int getBatteryPercentage() {
return batteryPercentage;
}
public void setBatteryPercentage(int batteryPercentage) {
this.batteryPercentage = batteryPercentage;
setChanged();
notifyObservers();
}
}
视图知道模型:
public class View implements Observer {
private Model model;
private JTextField txtFldSpeed;
private JTextField txtFldBattery;
private JFrame mainWindow;
public View(Model m) {
this.model = m;
initialize();
}
private void initialize() {
mainWindow = new JFrame();
mainWindow.setTitle("New Window");
mainWindow.setMinimumSize(new Dimension(1280, 720));
mainWindow.setBounds(100, 100, 1280, 720);
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel tPanel1 = new JPanel();
tPanel1.setBorder(new LineBorder(new Color(0, 0, 0)));
tPanel1.setLayout(null);
mainWindow.getContentPane().add(tPanel1);
mainWindow.getContentPane().add(tPanel1);
txtFldSpeed = new JTextField();
txtFldSpeed.setEditable(false);
txtFldSpeed.setBounds(182, 11, 116, 22);
tPanel1.add(txtFldSpeed);
txtFldBattery = new JTextField();
txtFldBattery.setEditable(false);
txtFldBattery.setBounds(182, 43, 116, 22);
tPanel1.add(txtFldBattery);
mainWindow.setVisible(true);
}
@Override
public void update(Observable o, Object arg) {
txtFldSpeed.setText(Float.toString(model.getSpeed()) + " kn");
txtFldBattery.setText(Integer.toString(model.getBatteryPercentage()) + " %");
}
}
Controller 将 View 添加为 Model 的 Observer:
public class Controller {
private Model model;
private View view;
public Controller(Model m, View v) {
this.model = m;
this.view = v;
}
public void initController() {
model.addObserver(view);
model.setSpeed(10);
}
}
我期待的是,当模型更新时,假设函数setSpeed() 被调用,视图被告知她需要在该特定字段上更新自身,而不是每个“可变”字段(如txtFldBattery。
我想这样做是因为在视图上,每秒会更新几次字段,并且因为我需要更新视图上的所有内容,JComboBox 不需要经常更新,尝试选择选项时一直关闭。
【问题讨论】:
-
请澄清您的问题。此外,问题越具体,您发布的minimal reproducible example 代码越好,通常问题的质量越高,答案就越好。旁注:通常视图会在模型中添加侦听器,这些侦听器会在模型更改时触发。您可以使用一个侦听器并简单地更新模型更改的整个视图,或者您可以使用多个侦听器并更有选择性地更新事物,这听起来像是您正在尝试做的事情。任何解决方案的详细信息将取决于您的代码和问题的详细信息。
-
感谢您的帮助@HovercraftFullOfEels。我将更新一些代码。我不认为它会有用。
-
我不认为我以前被称为“Ho”,但我被称为更糟(严重)。不过,如果可能,请再次改进您的问题。
-
不是你的反对者(还),等待你的更新
-
@HovercraftFullOfEels,对不起! :-D 我试图引用你。我更新了帖子。我省略了一些代码以使其更易于阅读,因为变量命名非常简单。谢谢。
标签: java model-view-controller listener observer-pattern