MASON严格遵循MVC设计模式:
Model和View之间是严格分离开的。
1. 创建一个空的窗口
package com.mason.learn;
import sim.engine.*;
import sim.display.*;
public class StudentsWithUI extends GUIState {
public static void main(String[] args) {
StudentsWithUI vid = new StudentsWithUI();
Console c = new Console(vid);
c.setVisible(true);
}
public StudentsWithUI() {
super(new Students(System.currentTimeMillis()));
}
public StudentsWithUI(SimState state) {
super(state);
}
public static String getName() {
return "Student Schoolyard Cliques";
}
}
2. 添加可视化组件
sim.display.Display2D:用于显示field,也就是我们的yard操场
javax.swing.JFrame:承载Display
sim.portrayal.continuous.ContinuousPortrayal2D:对field进行绘制或者监控。
sim.portrayal.simple.OvalPortrayal2D:在field portrayal中注册的simple portrayal,用于绘制图形。
在上述空窗口的基础上,我们增加了三个域和一些重要的方法:
public Display2D display;
public JFrame displayFrame;
ContinuousPortrayal2D yardPortrayal = new ContinuousPortrayal2D();
init():创建一个600px*600px的Display,并且设置其不按照100*100的尺寸剪裁,然后创建承载它的frame,并命名,然后再Console(是Controller的子类)中注册这个frame,然后把field portrayal和这个Display(名字为Yard)联系起来。
public void init(Controller c) {
super.init(c);
display = new Display2D(600, 600, this);
display.setClipping(false);
displayFrame = display.createFrame();
displayFrame.setTitle("Schoolyard Display");
c.registerFrame(displayFrame); // so the frame appears in the "Display"
// list
displayFrame.setVisible(true);
display.attach(yardPortrayal, "Yard");
}
start()和load():基本上相同,当正要开始进行仿真或者重新恢复仿真状态的时候调用。
GUIState这个类中有两个重要的实例:
state:保存仿真的模型Model,本例中应该是Students实例。
controller:GUI系统的控制器,通常在init之后进行设置。
setupPortrayals功能:
1. 设置field的simple portrayals和field portrayal
2. 重置和清理Display
public void start() {
super.start();
setupPortrayals();
}
public void load(SimState state) {
super.load(state);
setupPortrayals();
}
public void setupPortrayals() {
Students students = (Students) state;
// tell the portrayals what to portray and how to portray them
yardPortrayal.setField(students.yard);
yardPortrayal.setPortrayalForAll(new OvalPortrayal2D());
// reschedule the displayer
display.reset();
display.setBackdrop(Color.white);
// redraw the display
display.repaint();
}
quit(): 当退出界面时调用,用于清理GUI。
public void quit() {
super.quit();
if (displayFrame != null)
displayFrame.dispose();
displayFrame = null;
display = null;
}
添加完上述几个方法后,窗口显示为:因为节点之间的引力过大,才会呈现为一团。。