Model-View-Controller , или более простой уровень, Передача информации в метод или конструктор и шаблон наблюдателя - это те концепции, которые вам нужныучиться и понимать.
По сути, ваше «представление» является визуальным представлением вашей «модели».«Представление» «наблюдает» за «моделью» изменений и обновляет себя соответственно.
Чтобы добиться этого в вашем контексте, вам нужно поделиться моделью между двумя представлениями, передав ссылку на каждое.Представление «рендер» также будет «наблюдать» модель за любыми возможными изменениями
Начните с определения модели ...
public class MazeModel {
private List<ChangeListener> listeners = new ArrayList<>(25);
private int rows;
private int cols;
public void setSize(int cols, int rows) {
this.cols = cols;
this.rows = rows;
fireStateChanged();
}
public int getRows() {
return rows;
}
public int getCols() {
return cols;
}
public void addChangeListener(ChangeListener listener) {
listeners.add(listener);
}
public void removeChangeListener(ChangeListener listener) {
listeners.remove(listener);
}
protected void fireStateChanged() {
ChangeEvent evt = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(evt);
}
}
}
Лично я бы предпочел начать с interface
для определения договора, но для краткости.Модель должна содержать данные и логику, необходимые для управления лабиринтом.
Затем обновите ваши классы, чтобы экземпляр MazeModel
можно было передать в ...
public class Frame extends JFrame {
private VariableDetails vDetails;
private MazeArea mArea;
private int width;
private int height;
private MazeModel model;
public Frame(String title, MazeModel model) {
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.model = model;
this.model.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
// Update the state as required...
}
});
width = 500;
height = 500;
// Prefer pack :/
setSize(width, height);
setLayout(new BorderLayout());
// I'm guessing that model should be passed to this
// and it should modify it's state accoridingly....
mArea = new MazeArea();
vDetails = new VariableDetails(model);
Container c = getContentPane();
c.add(mArea, BorderLayout.CENTER);
c.add(vDetails, BorderLayout.EAST);
setVisible(true);
}
public class VariableDetails extends JPanel {
private MazeModel model;
public VariableDetails(MazeModel model) {
this.model = model;
JButton genBtn = new JButton("Generate");
genBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
model.setSize(cols, rows);
}
});
}
}
}
Теперь это дает классам независимый канал связи через ChangeListener
, который гарантирует, что они остаются разъединенными.
Примечание об изменении размера окна
Я бы не стал.Вместо этого я передаю модель экземпляру MazeArea
, чтобы он мог наблюдать за изменениями в модели и соответствующим образом обновлять себя.Затем я бы обернул MazeArea
в JScrollPane
, что позволило бы ему изменить размер на что угодно, и рамка могла бы остаться с относительным статическим размером.
См. Как использовать панели прокрутки для получения более подробной информации
Как пользователь, я бы без конца разозлился, если бы я сам установил размер окна, а вы пришли и изменили его