How to Create Displays(如何创建显示窗口)

Contents

Note:目前的Repast.net不支持录像

Building Displays

  显示是主体和它们环境的地理表示,在Repast里通过使用三种类来建立:空间类(uchicago.src.sim.space包中的类);在uchicago.src.sim.gui包里与那些空间对应的显示;一个显示界面DisplaySurface。此外,诸如主体、个体环境等对象必须通过使用特定的借口显示,实际使用的借口依赖于显示的类型。仿真实例的源码是如何使组合它们的好例子,应该与这个文件联系起来研究。

  在研究buildDisplay()方法之前,充分理解Repast如何设置和绘制显示是很有帮助的。为了绘制设置Repast包含以下几个步骤:第一步是创建你想要绘制的内容,通常就是主体和它们的环境。如How To Build a Repast Model里提到的,主体等是在buildModel()内创建,也是在buildModel()里,这些主体被添加到某种空间里,比如说Object2DTorus空间,有时是一个列表。然后,在buildDisplay()里创建合适于该空间的显示,该空间被添加到那个显示里。如果存在列表,它也被添加到显示里。显示本身再作为displayable或displayableProbeable 添加到DisplaySurface内,这取决于显示中的空间包含的对象是否会进行探测。(DisplaySurface应该由模型的setup()方法生成,简言之,在之后,你建立了一个包含一些显示的DisplaySurface,而这些显示包含了带有需要显示的对象的空间)。

  建立了这种结构以后,绘制顺序如下。对 DisplaySurface 对象调用updateDisplay 方法,通常,这个调用是由时间表安排好的,时间表记者产生该调用。接到该调用后,DisplaySurface 告诉它包含的所有的显示把他们自己表现出来;接到该调用,“显示”得到一个关于它们包含的空奖励所有对象的老板或者如果对象的列表被添加,它们只需要使用那个列表。然后“显示”(display)需要得到列表中的每个对象一些绘制信息(坐标等),使用该信息建立绘制界面,然后通知列表中的每个对象绘制他们自己。这些东西就会绘制他们自己了。为了使一个显示能表现出它的对象,可绘制对象要执行特定的方法。这些方法根据显示和封装它们的可绘制接口的不同而有细微差别。下面给出关于使用不同空间和显示的接口的图示。

  如How To Build a Repast Model里提到的那样显示通常用buildDisplay()方法创建,一个简单buildDisplay()的如下所示:

public void buildDisplay()
{
   Object2DDisplay agentDisplay = new Object2DDisplay(world);
   agentDisplay.ObjectList = agentList;

   dsurf.addDisplayableProbeable(agentDisplay, "Agents");
   addSimEventListener(dsurf);
}

  上例中,world 是一个空间,由 Object2DTorus 类型的主体组成,agentList 是一个简单的主体列表,dsurf 是一个 DisplaySurface。所有这些在先前的buildModel()或 dsurf 的 setup()中已经建立好了。这里创建的显示作为"world"空间结构的一部分添加进去。然后,agentList 也被添加进去以便显示,这个显示(即 agentDisplay)将作为可显示和可探测的显示添加到 dsurf 中。作为可显示的 dsurf 可以按上述方法显示 agentDisplay。作为可探测的 dsurf 可以允许对包含在空间内的主体进行探测,在这个例子中即由 agentDisplay 构成的world 空间。最后的方法将 dsurf 作为停止和暂停的接受者添加到模型里。这就允许 dsurf 知道模型的停止或暂停,并以此作出反应。看起来,将 agentList 和world 都添加到 agentDisplay 似乎多余,其实不然,以为空间不止通过要显示的对象给显示(),它们还参与了探测机制。

The Text Display

  TextDisplay和其他显示的不同在于它不显示空间,而是显DisplaySurface有关的文本, 你指定要显示的文本,TextDisplay将显示那个文本。

  如下设置一个 TextDisplay 作业 :

td = new TextDisplay(20, 20, Color.yellow);
dsurf.addDisplayableProbeable(td, "text");

  这里创建了一个在指定的 x,y 坐标(20,20)处用黄色显示文本的 TextDisplay。这样的代码会很典型地出现在你的 buildDisplay()方法中。这里的"td"是与你的模型有关的实例变量。主要,这里提到的坐标是预像素有关的,而不是网格元胞的位置。然后,这个文本显示"td"和其它显示一样添加到 DisplaySurface 中。缺省情况下文本将被显示在与文本颜色相同的长方形里。显示中可以使用鼠标该长方形移动。你可以使用 addLine 方法指定要显示的文本,这样添加文本不需要移除以前添加的文本,可以用 clearLines()方法移除以前添加的任何文本。新文本的添加一般作为一个预排动作的一部分,以便文本能反映某些得新状态。例如:

  

td.clearLines();
td.addLine("tick count: " + getTickCount());

 

  上面的例子讲安排在每个节拍发生,主要会显示一个新的节拍计数记录模型的每个节拍。

  addLine和clearLines以及开关长方形的方法都有变量,详见API文件。

Taking Snapshots and Making Movies

  Repast能用于截取快照,即当前显示的gif型图像,也可以使用随运行原因而改变的显示制作快速影像。这个功能可通过DisplaySurface类实现,你可以手动设置你的仿真截获快照制作影像,也可以使用Repast Action tab提供的按钮。下面描述手动设置的方法。设置显示界面截取快照,你需要在 buildDisplay()里调用dsurf.setSnapshotFileName(some_fileName)。DisplaySurface 将使用这个名字作为生成 gif 文件的名字的基础。然后在 buildSchedule()方法里预排DisplaySurface 在仿真的节拍里截取显示的快照。例如,假定一个DisplaySurface dsurf: 

schedule.scheduleActionAtInterval(100, dsurf, "takeSnapshot"); 

   dsurf 将会在仿真的每 100 个节拍时创建一个显示的 gif 图像,最后的 gif 图像文件存为 some_fileName_tick_count.gif

  你也可以用几乎相同的方法截取 Repast 图表对象的快照。只是用你的图表对象的变量名替代上面的 dsurf 即可。  

  制作影像也是类似的,将一个 DisplaySurface 为制作影像作准备你要调用dsurf.setMovieName(movie_name, DisplaySurface.QUICK_TIME);

  你需要在 DisplaySurface 上安排 addMovieFrame 来将指定的仿真节拍的显示转化成影像的一个画面:

schedule.scheduleActionAtInterval(10, dsurf, "addMovieFrame");

  

该语句表示每 10 个节拍截取一次显示作为影像的一个画面。只支持多媒体数字技术(quicktime)的电影。最后的电影文件名是 setMovieName 里的名字和影像类型和合理扩展名的结合。你必须发送 closeMovie 的消息给 DisplaySurface。例如

schedule.scheduleActionAtEnd(dsurf, "closeMovie");

  当影像不再将自己写入文件,你将会看到有关的消息框。不要退出仿真直到你看到并单击了该信息框。

  此时,不支持对 Repast 的图表对象制作电影。Repast 的行为标签可用来自动截取快照并制作你的 DisplaySurfaces 和图表对象的电影。点击 Repast 行为标签上的适当按钮将为提供给你一系列做好说明的选择。尽管如此,为了使它工作,你需要注意这些对象在 setup()方法中是如何建立的。总体说,你要在 setup()方法中建立这些对象并将他们申明为DisplaySurfaces 或 MediaProducters 类型。DisplaySurfaces 应该申明为DisplaySurfaces 型,图表对象应申明为 MediaProducers 型。例如:

  

private void setup() {
... 
dsurf = new DisplaySurface(this, "Sugar Scape");
registerDisplaySurface("Sugar Scape", dsurf);
bar = new OpenHistogram("Agent Wealth Distribution", 10, 0, this); 
graph = new OpenSequenceGraph("Agent Attributes", this, 
"./graph_data.txt", Statistics.CSV);
registerMediaProducer("Hist", bar);
registerMediaProducer("Plot", graph);
...
}

  

 

  申明一个对象或 DisplaySurface 允许它在快照和电影源里被显示。单击 Repast行为标签里的"take Snapshot"按钮允许从这些申明好的对象中进行选择作为快照源,在什么的例子中你可以在"Sugar Scape", "Hist", "Plot"中作一个或多个选择。

  注意:此时不支持制作图表对象的电影。

Drawable, Space and Display Mappings

  使用下表决定使用特定空间和显示时你的主体所使用的接口。例如,如果你的主体占用了Object2DTorus空间,你要使用Object2DDisplay显示,而且占用的Object2DTorus整体要使用Drawable接口。

 

Space

Display

Interface

Object2DGrid

Object2DDisplay

Drawable

Object2DTorus

Object2DDisplay

Drawable

Object2DGrid

Network2DGridDisplay

Nodes: Drawable2DNode
Edges: DrawableEdge

Object2DTorus

Network2DGridDisplay

Nodes: Drawable2DGridNode
Edges: DrawableEdge

Diffuse2D

Value2DDisplay

N/A. Map to values to a ColorMap instead.

Multi2DGrid

MultiObject2DDisplay

Drawable

Multi2DTorus

MultiObject2DDisplay

Drawable

OrderedMulti2DGrid

MultiObject2DDisplay

Drawable

OrderedMulti2DTorus

MultiObject2DDisplay

Drawable

Object2DHexagonalGrid

Object2DHexaDisplay

Drawable

Object2DHexagonalTorus

Object2DHexaDisplay

Drawable

DiffuseHexagonal2D

Value2DHexaDisplay

N/A. Map to values to a ColorMap instead.

RasterSpace

Object2DDisplay

Drawable

posted @ 2014-12-25 14:47  Buller Lee  阅读(311)  评论(0)    收藏  举报