Category: CS349

CS349 Assignment 2,3总结

偷懒把两个作业的总结写到一起了,呵呵。 不过也不仅仅是偷懒的问题,这两次作业都是在Java环境下通过swing库来编写图形界面程序。并且要使用MVC结构。对于熟悉JAVA的同学来说,这次作业的难度其实并不在与写JAVA,而是满足MVC结构。如何才算是满足呢? 简单地说,满足MVC的程序,将.java文件放在两个package里面,一个是model,另一个是view和controller,那么model里面的任何文件都不应该导入另外一个package。为什么不是3个packages? 因为虽然叫MVC但其实并没有必要刻意把View和Controller分开,毕竟两个合起来称作User Interface,甚至没有必要把view和controller放在不同的文件中。而且,各个不同的view也应该是相互独立的,换句话说,如果每一个view都是一个包含了自己所需要的controller的package的话,那么这些package之间也不应该相互导入,当然除了主窗口要导入所有的view和model之外。。。 正确的方法是,在model里面应该有一个public interface,每一个view都应该继承这个interface并通过model提供的函数向model注册自己。而model在内部数据发生任何变化的时候,都应该调用interface里面的函数来通知所有已经注册的view。这也是model唯一可能向view发出数据的地方。model必须提供完整的函数来满足各种view所需的数据并接收view发来的用户操作,而view也要在收到model通知的时候主动从model获取需要的数据并更新自己。而在用户进行任何操作的时候,view要尽量通知model并将变化的内容更新到model上。需要注意的是,自始至终应该只有一个model的实例在运行,这样是为了保证整个程序的数据是统一稳定的。 对于不熟悉JAVA的同学来说,Java Reference是非常好的学习资料。对于很多component和layout,reference里面都提供了一些tutorial来帮助理解。Component大都位于javax.swing下,而layout大多位于java.awt,还有一小部分位于javax.swing。事件和监听的类位于java.awt.event和javax.swing.event下。Eclipse是推荐的开发环境,它会帮助导入没有导入的包。对于一些需要大量数据的component,比如JTable, JList和JTree,他们都提供了model的interface,并有设置model的函数。可以通过implements这些model来实现对component数据的变化,也可以通过直接继承default model来只重载我们需要的部分。比如JTable有interface TableModel和class DefaultTableModel。 对于熟悉JAVA的同学来说,这两次作业一个星期就绰绰有余了。毕竟JAVA的debug简单,而且也不会有内存访问错误。对于不熟悉JAVA的同学来说,建议早点开始,这样有时间去看看reference,慢慢适应JAVA的图形开发。 Read More

CS349 Assignment 1总结

Assignment 1主要是联系在C/C++环境下通过X11库来编写图形界面程序。相信对于C/C++的规范,各位都很熟悉了。要使用X11库,通常需要include的库有X11/Xlib.h和X11/Xutil.h。所有库的reference可以在X的官方网站查询到:http://www.x.org/releases/X11R7.6/doc/libX11/specs/libX11/libX11.html本文只是简单的介绍了X11的基础功能,抛砖引玉。具体的函数用法可以参考reference,这里就不再赘述了。 要注意的是,上面的官方reference是针对X11R7版编写的,而在这个作业中,我们使用的是X11R6。具体两个版本有什么区别,这点笔者也不是很清楚。。。= =||| 这里先总结一下X11相关的概念和定义。Sever指的是要显示这个图形界面的终端,也就是你面前的电脑,而不是运行程序的终端。display指的是程序到x11 server的连接。screen是显示器,为什么要把显示器单独列出来呢?因为根据显示器的基本属性,比如分辨率和配色的不同,显示的结果也可能会不同。window就指的是创建的窗口了,一个程序可以有多个窗口。 XOpenDisplay(“”)用来打开一个display,函数返回指向这个display的指针,函数参数是server的名称,一般留空即可,程序会自动使用默认值。相应的,XCloseDisplay(display)可以关闭这个display,其中的display就是前面返回的display指针。 XCreateSimpleWindow可以创建一个窗口,函数参数制定了窗口的display, screen, 在屏幕上的位置,大小,背景色,创建出来的窗口默认是不会映射到服务器显示的。XDestroyWindow则可以销毁窗口。窗口创建好了之后需要使用XMapRaised函数来把创建的窗口映射到服务器显示。 程序生成的X11指令并不是实时发送到服务器执行的,XFlush函数可以强制把队列中的x11指令发送到服务器执行。而XSync函数出了具有XFlush的功能,但是XFlush只是将指令发送就会返回,并不保证所有的指令都已经发送完毕了。XSync函数可以保证这一点。(注意,是指令都发送完毕,而不是服务器接受并处理完毕) XSelectInput指令可以制定窗口希望接收到的事件类型,比如窗口重绘,鼠标移动,鼠标点击,键盘按键按下和释放等等。XNextEvent可以用来接收事件,如果当前没有需要处理的事件的话,函数会一直等待,直到下一个事件接受之后才会返回。但有时候我们不希望程序因此而暂停执行,这时可以用XPending函数来检查当前事件队列的长度,如果返回0的话,我们就知道如果调用XNextEvent可能会导致线程被暂停了。 绘图指令函数有很多种,XDrawLine, XDrawPoint, XDrawRectangle, XDrawArc, XDrawLines, XDrawArcs, XFillPolygon, XFillRectangle, XFillArc等等。。。用法各位从函数名称基本就能猜出来了,参数也大同小异。 Graphic Context,简写GC,就像网页的css文件一样可以管理绘图函数的绘制风格,比如线条宽度,颜色,虚实线等等,几乎所有的绘图函数都需要传入一个gc。GC常用的建立方法有两种,一个是通过XGCValues;另一个则是直接创建GC,然后通过XSet类型的函数来设置。由于一个GC包含很多种属性,前者适合设置大量属性;后者则适合设置少量,或者在创建之后修改GC。 由于所有的绘图信号都是通过网络发送到本地X11服务器的,网速的快慢一定程度上会影响显示效果。usleep函数暂停线程执行的功能在这里就会显得尤为重要,一定程度上可以缓解由于网速而导致的画面闪烁。 整个assignment建议使用一个星期左右的时间完成。GL HF Read More