`
bluestar
  • 浏览: 377284 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

了解swt的底层设计

阅读更多
   从前面的例子可以看出,swt是使用操作系统提供的本地部件库,通过Display对象来透明的与应用程序通信。Java控件对象的生命周期映射到本地控件的生命周期;当你创建了一个java空间,本地库也被创建,当java控件被销毁时,本地控件也被销毁。这个设计避免了调用一个代码对象的方法时,底层部件仍没有被创建的问题,这样的问题会导致代码控件生命周期和本地控件生命周期不匹配。
    例如,同Microsoft Foundation Classes (MFC)的两步创建过程相比。如果想创建一个按钮,要如下写代码:
CButton button; // Construct the C++ object on the stack
Button.Create( <parameters>); //Create the Windows widget
看一下在C++对象的构建代码和依赖的本地窗口工具代码之间插入代码:
CButton button; // Construct the C++ object on the stack
CString str = _T(“Hi”); // Create a CString to hold the button text
button.SetWindowText(str); // Set the button text—PROBLEM!
button.Create( <parameters>); // Create the Window widget
代码编译时没有任何问题,但是不能如期望运行。调试版本会引起一个断言,发布版本的行为是不确定的。
    </parameters> </parameters>
父控件
    很多GUIs在创建一个新控件前需要指明他的父控件,这个控件的生命周期是和他的父 控件相关的。父控件的生命时间就是子控件的生命时间。再有就是,很多本地控件都有他们的个性,或者说是“style”,必须在创建时指明。举例,一个按钮 可以是点击的,或者复选的。因为SWT控件在构造时创建相应的本地控件,所以必须将这些信息传递给他的构造函数。SWT控件一般都是带有两个参数的:父控 件和样式。父控件一般都是org.eclipse.swt.widgets.Widget或者他的一个子类。样式是在SWT类中定义的一些整形常量;可以 付给一个类型,或者使用或运算符添加几个类型。我们将在后面章节针对相应的控件指明它的类型。
   
释放控件
   
Swing的开发者可能会嘲笑这一点,作为证明SWT的缺点。Java开发者可能在这里也会感到讨厌和不适,而在这一点要说的是:自己处理的自己必须要清理。要知道,这是对java程序员的负责,对垃圾回收的侮辱。
    为 什么要释放对象?Java的垃圾回收可以很好的做到,但是GUI资源管理操作却承受巨大的约束。GUI资源是非常有限的,在很多平台上,系统资源是很有限的。由于SWT需要底层的图形资源来工作,每个SWT资源消耗着一个GUI资源,资源的延时释放不但对你的SWT程序有好处,同样对正在运行的GUI程序 有好处。Java的垃圾回收没有时间的保证,会使得对SWT的图形资源的管理变得很糟。所以,作为程序员的你必须承担起这个责任。
    这个工作有多繁重?实际上,并没有多大的工作量。在SWT的一系列文章上,Carolyn Macleod和Steve Northover给出了两个简单的法则来指导你(www.eclipse.org/articles/swt-design-2/swt-design-2.html):
•如果你创建了他,那么就要释放他
•释放了父控件,子控件也被释放
    法则一:如果你创建了他,那么就要释放他
    在本章节的前一部分,你知道了创建SWT控件,相应的本地控件也被创建了。也就是说,调用了SWT的构造函数,底层的本地资源也被创建了。所以如果你写下如下代码,那么你就创建了一个SWT颜色对象,那么也就在系统的底层资源里分配了一个颜色资源:
Color color = new Color(display, 255, 0, 0); // Create a red Color
法则一说明了如果你创建了他,那么你就要在使用完时释放他,像下面一样:
color.dispose(); // I create it, so I dispose it
但是,如果你没有使用构造函数来申请资源,你就不能显式的释放他。比如,考虑下面的代码:
Color color = display.getSystemColor(SWT.COLOR_RED); // Create a red Color
再一次获得了底层平台的颜色资源,但是没有分配他。法则一就说不能释放他。为什么不呢?因为这个不属于你-你只是借用了这个资源,其他的对象有可能正在使用它或者将要使用它。释放这个资源会变得非常严重的。
    法则二:释放了父控件,子控件也被释放
    对每一个使用new创建的控件都使用dispose ()会变得非常繁琐,会使得SWT很快被抛弃。但是,SWT的设计者意识到了这一点,创建了一种逻辑上层叠的自动释放机制。这意味着,当一个Shell被 释放了,所有与Shell有关的控件都被自动释放了。你会发现,永远也不会使用label.dispose()在“Hello World”程序里,甚至你使用了new来创建一个Label对象。当用户关闭了Shell,Label控件自动的释放了。
也许你在想,你永远不需要调用dispose(),这部分代码只是在浪费空间。实际上,有可能写一些程序,所有的资源都只有一个父类,并且这些资源都会自动释放。但是,考虑一下下面的改变Text中字体的代码。如下:
Text text = new Text(shell, SWT.BORDER); //Create the text field
Font font = new Font(display, ”Arial”, 4, SWT.BOLD); //Create the new font
text.setFont(font); //Set the font into the text field
这 个字体对象创建时没有父类,所以不会被自动释放,甚至当Shell被关闭了,Text对象调用了dispose()。也许你会对使用font这个负担而发 怒,但是考虑到text没有理由要对font负责-font不属于他。实际上,你也许会使用这个Font对象在各种各样的控件上,自动释放会引发一系列的 问题。
    忽略释放对象
    聪明的读者也许会发现在生命周期映射上有一个漏洞:如果Java包裹的本地控 件依然在活动,而他所属于的Shell被释放了,将发生什么情况呢?或者手动调用控件的dispose方法会怎么样呢?本地控件会被释放吗?我们是否可以 调用java对象而他的底层本地控件不存在?
答案当然是:可以!如果你调用一个对象而他的本地控件已经释放,会引出一些麻烦。一旦一个控件被释放 了,甚至他依然在活动,对他做什么都没有用。是的,Java对象依然可用,但是底层的对应点已经释放了。那么就会得到一个SWTException,显示 为“Widget has been disposed”。考虑下面的代码。 
java 代码
  1. import org.eclipse.swt.*;  
  2. import org.eclipse.swt.layout.*;  
  3. import org.eclipse.swt.widgets.*;  
  4. public class Broken  
  5. {  
  6.   public static void main(String[] args)  
  7.   {  
  8.     Display display = new Display();  
  9.     Shell shell = new Shell(display);  
  10.     shell.setLayout(new RowLayout());  
  11.     Text text = new Text(shell, SWT.BORDER);  
  12.     shell.open();  
  13.     while (!shell.isDisposed())  
  14.     {  
  15.        if (!display.readAndDispatch())  
  16.        {  
  17.           display.sleep();  
  18.        }  
  19.     }  
  20.     System.out.println(text.getText()); // PROBLEM!  
  21.     display.dispose();  
  22.   }  
  23. }  

  代码可以编译和运行,但是在关闭了主窗口后控制台会打印出以下的错误:
Org.eclipse.swt.SWTException: Widget is disposed
at org.eclipse.swt.SWT.error(SWT.java:2332)
at org.eclipse.swt.SWT.error(SWT.java:2262)
at org.eclipse.swt.widgets.Widget.error(Widget.java:385)
at org.eclipse.swt.widgets.Control.getDisplay(Control.java:735)
at org.eclipse.swt.widgets.Widget.isValidThread(Widget.java:593)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:315)
at org.eclipse.swt.widgets.Text.getText(Text.java:705)
at Broken.main(Verison.java:24)
    需要注意的,当你在Windows XP上运行这个程序,你会得到一个对话框显示javaw.exe出现了问题,需要关闭,你是否愿意发送错误报告到Microsoft?
    总之,一旦一个对象被释放了,是否是显式的调用dispose()方法还是由于它的父控件被释放了,我们不用管他。
分享到:
评论

相关推荐

    SWT界面设计PDF

    与Java的另一图形库AWT和Swing相比,SWT更接近底层操作系统,因此在性能和本地化集成方面具有优势。 在"第十八章.图形界面开发--AWT,Swing,SWT.pdf"中,你会了解到SWT与AWT和Swing的区别。AWT是Java最初的GUI库...

    SWT源代码 SWT Source code

    通过这些脚本,开发者可以了解SWT如何被编译成可执行库。 2. `os_structs.c`、`os.c`:这些文件包含了与操作系统交互的结构体定义和函数实现。`os_structs.c` 可能包含了各种操作系统特定的数据结构,而 `os.c` ...

    swt-api swt DOC

    这个文档可能是开发者们在使用SWT进行界面设计时的重要参考资料。 【描述】"java界面编程,swt的开发DOC,谁用谁知道,一般人我不告诉他" 提示我们SWT是Java编程中用于创建桌面应用用户界面的一种工具包。它提供了...

    《java程序设计之swt教程》

    8. ** SWT与Eclipse RCP**:如果你打算构建大型的桌面应用,了解Eclipse Rich Client Platform(RCP)是非常有益的,它是基于SWT和JFace的框架,可以帮助你快速开发专业级别的应用程序。 通过学习这个SWT教程,你将...

    JFace-SWT-中文版API(含swt.jar和swt-debug.jar)

    首先,我们来详细了解SWT(Standard Widget Toolkit)库。SWT是由Eclipse基金会开发的GUI库,它是基于操作系统原生控件的,因此能够提供与操作系统一致的外观和交互体验。SWT库包含了一系列的基础组件,如按钮、...

    SWT编程开发学习资料

    与Java Swing相比,SWT更加接近底层操作系统,因此在许多情况下,它的速度更快,界面更贴近操作系统原生风格。 在"SWT编程开发学习资料"中,你可以期待获取关于以下几个方面的深入理解和实践指导: 1. **SWT基础...

    swt/Jface中文教程

    - **构建基于SWT/JFace的应用程序**:了解SWT/JFace的基本原理后,开发者可以利用这两款工具包来构建高性能且美观的桌面应用程序。无论是简单的工具还是复杂的集成开发环境(IDE),SWT和JFace都能提供必要的支持。 ...

    swtdesigner

    - **可视化设计**:SwTDesigner的拖放界面使得开发者可以快速构建UI,而不需要深入了解每个组件的底层代码。 - **实时预览**:在设计过程中,开发者可以实时查看所设计的界面效果,方便调整和优化。 - **自动代码...

    swt源码以及jar

    源码还可以帮助我们了解SWT如何与操作系统底层交互,实现原生的外观和性能。 其次,预编译的jar文件是直接在项目中使用的,它们包含了SWT的所有类和方法。开发者可以通过引入这些jar文件,快速地在Eclipse环境中...

    SWT-Designer

    不过,熟练掌握其使用技巧并了解SWT的基本概念是必不可少的,以便更好地利用它来提高开发效率。通过阅读提供的"SWT-Designer.pdf"文档,你可以深入学习如何有效地使用这款插件。同时,与社区的交流(如通过邮件...

    图书馆管理系统SWT源码

    在学习这个图书馆管理系统SWT源码的过程中,我们不仅可以掌握SWT的基本用法,还能了解到如何设计和实现一个完整的管理系统的流程,包括数据库操作、事件监听、界面布局等多个方面。同时,通过实际项目的实践,可以...

    java eclipse swt教程

    SWT是Eclipse基金会推出的一种GUI库,它为Java开发者提供了一种与平台无关的方式来构建用户界面,同时又能充分利用底层操作系统提供的功能,以实现更快的性能和更贴近原生系统的用户体验。 SWT的设计理念是通过直接...

    org.eclipse.swt-3.1_SWT_doc_

    1. **原生控件**:SWT使用底层操作系统提供的控件,使得应用程序看起来和行为都与操作系统平台一致。 2. **事件驱动模型**:类似于其他GUI库,SWT基于事件驱动模型,允许用户响应用户的交互动作,如点击按钮或移动...

    swt-grouplayout-pgroup

    首先,让我们深入了解SWT。SWT是Java GUI开发的一个选择,它的设计目标是提高性能和与原生系统的集成度。SWT使用C/C++编写底层的窗口系统接口,然后通过Java绑定来提供跨平台的支持。这使得SWT应用通常比使用纯Java...

    SWT扩展

    了解SWT如何与操作系统进行交互,以及如何实现各种控件和功能,可以帮助开发者更好地优化应用性能,解决特定问题。 在实际项目中,SWT常用于开发桌面应用程序,尤其是在Eclipse插件开发中。结合Eclipse RCP(Rich ...

    SWT开发

    7. **源码阅读**:了解SWT源码有助于深入理解其工作机制,解决性能问题或自定义组件。 8. **开发工具**:Eclipse是主要的SWT开发环境,提供代码补全、调试、布局编辑等功能。除此之外,还有SWTBot用于自动化测试,...

    eclipse开发SWT应用

    在Eclipse中开发SWT应用,首先需要了解SWT提供的基本组件,如按钮(Button)、文本框(Text)、列表(List)、表格(Table)等,这些组件可以构建出丰富的用户交互界面。SWT的优势在于其与操作系统底层的紧密集成,...

    SWT JFace In Action 中文版

    - **界面设计原则**: 学习SWT和JFace不仅限于技术层面,还包括了解良好的用户界面设计原则,如易用性、一致性等。 - **布局管理**: 掌握SWT中的布局管理技巧,如GridLayout、FormLayout等,以创建整洁且可扩展的界面...

    SWT JFACE开发帮助文档(chm)

    1. **SWT控件和布局**:了解SWT中的各种控件,如Button、Label、Text、Composite等,以及如何使用Layout管理器(如GridLayout、FillLayout、RowLayout)来组织这些控件。 2. **JFace的数据绑定**:学习如何使用...

    swt.rar_java swt_jface_swt/jface

    在学习SWT和JFace时,你需要了解它们的事件模型,如何使用布局管理器来组织窗口元素,以及如何处理用户输入和响应。同时,数据模型和控件之间的绑定也是关键,这可以帮助实现动态更新视图和保持数据一致性。 通过...

Global site tag (gtag.js) - Google Analytics