В шаблоне MVC, который является лучшим вариантом для Модели, чтобы уведомить Представление (если это правильный подход в первую очередь), где из всех полей данных, которые хранит Модель, только пара из нихобновляются.В частности, когда мы хотим обновить только определенные поля представления.
В настоящее время я использую шаблон MVC с Observer / Subscriber (JAVA Swing), как описано здесь: 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
Основной класс, в котором запускается программное обеспечение:
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();
}
}
Итак, код, который у меня есть в Model, такой:
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()) + " %");
}
}
Контроллер добавляет представление в качестве наблюдателя модели:
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()
, View сообщается, что ей нужно обновить себя в этом конкретном поле, а не в каждом «изменяемом» поле (например, txtFldBattery
.
. Я хочусделать это потому, что в представлении есть поля, которые обновляются пару раз в секунду, и потому что мне нужно обновить все в представлении, JComboBox
, который не нужно обновлять так часто, продолжает закрываться при попытке выборавариант.