分享
 
 
 

[Eclipse笔记]在SWT中有效的管理图形系统资源

王朝java/jsp·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

本文部分内容和灵感来自eclipse.org网站,特此声明。更多内容,请参考:

http://eclipse.org/articles/Article-SWT-Design-2/SWT-Design-2.html

由于SWT直接跟操作系统打交道,所以我们需要在处理系统的图形资源时格外小心,以免不必要的资源泄漏。所幸SWT提供了很好的资源管理机制,我们绝大多数情况下需要做的只是确保两条原则:

第一条原则 – 谁分配谁销毁

第二条原则 – 父控件销毁的同时销毁子控件

下面我们分别来看一看这两条在实际中是如何体现的。

先看第一条原则。乍一看这似乎是废话,但是在实际中往往并非那么简单。首先,构造方法不等于分配资源,实际上分配资源可以发生在一个类中的任何地方以及一个对象生命周期的任何时候,只要你的代码告诉操作系统这样做。你必须保证所有由你分配的资源当你不再使用时调用其dispose()方法;同时你也必须保证所有不是由你分配的资源不要随便调用其dispose()方法,否则很可能会影响到实际分配的那段相关代码的正常工作。好消息是,为了明确和简化这第一条原则所规定的分工,SWT在设计之初就确定下来,所有基于系统资源的SWT类都在其构造方法中完成所有所需的资源分配,在其他方法中则没有任何分配系统资源的动作,所以我们可以幸运的这样看待SWT的资源管理:如果你调用了某个SWT类的构造方法,那么就由你来调用其dispose()方法释放资源;如果你没有调用某个SWT类的构造方法,即便你使用了这个类的实例,也不应该由你来调用其dispose()方法。就是这么明确。

比方讲,你new了一个Font对象,那么当你不再需要它时,就应该调用dispose();如果你通过某个控件的getFont()方法取得一个Font对象并使用后,你不应该去销毁它,而应该交给那个具体的控件去处理。

对于第二条原则,SWT有一个很好的机制去支持它,那就是,所有的SWT控件,具体讲,Composite类及其子类的实例,都必须有一个父控件,这个父控件的引用在子控件的构造方法中被传入。需要注意的是,所有这些控件的不带参数的构造方法都只有默认访问级别,于是我们不能在自己的SWT程序中直接调用这样的默认构造方法而只能提供一个父控件的引用,而在Widget类(Composit的父类)的带参数构造方法中,它会调用如下方法:

void checkParent (Widget parent)
{

if (parent == null) error (SWT.ERROR_NULL_ARGUMENT);

parent.checkWidget ();

}

进而:

protected void checkWidget ()
{

Display display = this.display;

if (display == null) error (SWT.ERROR_WIDGET_DISPOSED);

if (display.thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);

if ((state & DISPOSED) != 0) error (SWT.ERROR_WIDGET_DISPOSED);

}

这样的检查保证了任何控件在创建时都有父控件。当我们调用某个Composite的dispose()方法时,它会调用:

void releaseChildren ()
{

Control [] children = _getChildren ();

for (int i=0; i<children.length; i++)
{

Control child = children [i];

if (!child.isDisposed ()) child.releaseResources ();

}

}

其中的_getChildren()方法通过OS对象的方法遍历控件的子控件,然后汇总到一起分别调用releaseResources()方法释放控件和句柄。

回到上次的SimplestSWT的例子:

package sean.test.swt;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Shell;

public class SimplestSWT
{

public static void main(String[] args)
{

Display display = new Display();

Shell shell = new Shell(display);

shell.pack();

shell.open();

while (!shell.isDisposed())
{

if (!display.readAndDispatch())
{

display.sleep();

}

}

display.dispose();

}

}

这当中,Display是一个顶层的设备,它继承自Device类,而Device类实现了Drawable接口。Shell的父类是Decoration,而Decoration继承自Canvas,Canvas继承自Composite,最终这条继承链一直连到Widget类。我们在创建Shell示例的时候,需要告诉构造方法它的父控件是什么,在这里就是display。于是当我们最后调用display.dispose()时,虽然我们没有明确写shell.dispose(),我们的Shell实例也随之销毁了。

这就是SWT的资源管理机制,稍有例外的是MenuItem的setMenu()方法和Control的setMenu()方法,它们通过显式调用setMenu的方式注册自己的父控件。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有