分享

Differences between Swing and SWT

 LibraryPKU 2013-05-13

Graphical resources and garbage collection

-->

Switching from AWT/Swing to SWT doesn't just mean learning a new API; it also requires former Swing programmers to change some of their habits and to care about new coding rules they didn't have to deal with in the Swing world.

SWT uses a completely different philosophy than AWT and Swing do when it comes to handling graphical resources. In AWT and Swing, you can, in most cases, rely on the JVM's garbage collector to free up graphical resources (image handles, colors, cursors, fonts, widgets, etc.) when these are not needed anymore. I emphasize the words "in most cases," because even in AWT this isn't always the case. For example, a java.awt.Image must be freed up explicitly by invoking the method flush() if you want the pixels to be freed. Programmers of applications making heavy use of images often fall into the trap of thinking that if the garbage collector finalizes the reference to an image, it will free up the platform resources assigned to it as well. Then they wonder where the memory leaks in their applications come from. There are some other examples of resources that have to be explicitly freed up in AWT -- java.awt.Dialog and java.awt.Graphics both have a dispose() method, for instance -- while other resources, such as fonts or colors, are automatically released by the garbage collector. This is quite confusing for programmers.

SWT uses a different approach: All SWT objects allocating platform resources ( Color, Cursor, Display, Font, GC, Image, Printer, Region, Widget, and their subclasses) have to be explicitly discarded. The JVM's garbage collector will finalize unreferenced SWT objects, but it will not dispose of the platform resources used by them. Thus, if you delete all the references to one of these objects without having previously discarded it, you will have a memory leak. This sounds like a very constricting rule, but it is a clear rule and it is the price you pay for better UI performance.

To avoid resource leaks in an SWT application, you must follow this simple rule: If you instantiate an object that consumes graphical resources, you have to dispose of it yourself. Objects obtained from getters, diverse methods, or parameters should not be discarded by the code obtaining them, because the objects were not created there, and may be used by other parts of the application. The only exceptions are widgets: Disposing of a parent container will automatically dispose of all its children.

If you follow this rule, you won't have any problem with memory leaks of graphical resources.

Note that JFace provides helper classes and frameworks to help you to manage and discard resources (fonts and images) that may be shared by several components. These classes are contained in the package org.eclipse.jface.resource.

If you want to get a better understanding of the rules listed above, and the reasons why SWT doesn't behave like AWT when managing graphical resources, read "SWT: The Standard Widget Toolkit, Part 2" by Steve Northover and Carolyn MacLeod. A link to this article is available in Resources.


The Swing component hierarchy

The most obvious difference between Swing and SWT is the component hierarchy. To facilitate the comparison between the Swing's and SWT component hierarchies, I've illustrated Swing's component tree in the following figure:

Swing component hierarchy

The boxes with a yellow background represent ready-to-use widgets that can be deployed in a user interface. The boxes with a blue background represent abstract classes that are not intended to be used directly.

As you can see, nearly all Swing components directly inherit from JComponent, which is itself a subclass of an AWT Container.


The SWT component hierarchy

Now let's take a look at SWT's component hierarchy:

SWT component hierarchy

As you can see, the number of available widgets here is pretty similar to what Swing offers, but the names and the hierarchy of the components is quite different.

  • The superclass for all SWT components is Widget, which directly inherits from Object.

  • The two most important subclasses of Widget are Control and Item. Control is the superclass for all widgets that can be added in a parent container and whose position and size can be set. Item is the superclass for components or sub-components that can only exist within another specific component, such as menu items, toolbar items, table rows or column, etc.

  • Seven widgets directly inherit from Control. Six of these subclasses are simple components that don't allow children, such as buttons or labels. Scrollable is an abstract class, and is the superclass of all components that may be scrollable (tables, lists, text fields, and so on).

  • Composite is an important class in the component hierarchy. It is the equivalent of AWT's Container and is the superclass of all components that allow children to be placed in them.

The correspondence between each Swing component and its equivalent in SWT will be introduced in Widgets .


Containers and layouts

The equivalent of an AWT Container is an SWT Composite. As with a Container, you can add controls to a Composite, and set a layout manager that will relocate and resize the children as the parent composite is being resized.

However, there are some differences in this domain between AWT and SWT. If you look at the API documentation of Composite, keeping in mind that it is the equivalent of an AWT Container, you may be surprised to see that there is no direct equivalent for the methods add(...) or remove(...), which in AWT allow you to add a child to or remove a child from its parent.

SWT controls are automatically added to their parent at construction time. When you construct an SWT control, the first parameter required by the constructor is always the reference to the parent composite. For this reason, Composite doesn't provide any add(...) method, as AWT's Container does. Although Control has a setParent(Composite) method that allows you to reparent a control -- that is, to remove it from its original parent and add it to a new parent -- this feature is not available for all widgets and all platforms, so you can't rely on it if your application has to be cross-platform. For example, Motif doesn't allow a control to be reparented. To test if this feature is supported by a particular platform or widget, you can use the method Control.isReparentable(). Invoking setParent(Composite) on a widget that is not reparentable will throw an exception.

Because the addition to the parent composite is done during the instantiation of a control, the order in which controls are instantiated defines the index the controls have in their parent. The index of a control in its parent may have an influence on the way the layout manager places it in the container. This can be an issue when porting existing Swing code, because in AWT/Swing, the order of instantiation of the children is not important -- in fact, a child can be instantiated before its parent. Only the order of addition of the children plays a role. When porting Swing code, you may have to change the order of creation of some widgets to get the same result as in Swing.

Composite doesn't provide a remove(...) method to remove a child as AWT's Container does. To remove a control from its parent, you have to dispose of it. However, you should be aware that a control that has been discarded can't be used anymore. There is no way to add a control to its parent again after it has been eliminated. You have to instantiate a new control again. Here, you don't have the flexibility of AWT, which allows you to remove a component, keep it instantiated offscreen, and later add it again to the same or a different parent.

Like AWT, SWT makes use of layout managers to place children of a container. The layout algorithms that are available are different, however. To get an overview of the SWT layout algorithms, read "Understanding Layouts in SWT" by Carolyn MacLeod and Shantha Ramachandran. A link to this article is available in Resources.

As in AWT, some SWT layouts require you to set some layout constraints on widgets so that you can influence how the children of a container are going to be laid out. In AWT, you set this constraint by passing it as the second parameter to the method Container.add(Component, Object). Because Composite doesn't provide any method to add a child, you have to set it by invoking a method named setLayoutData(Object) on the child component itself.


Data models and cell renderers vs. content providers and label providers

One of the most beautiful aspects of Swing's architecture is its strict adherence to the Model-View-Controller pattern. The clean separation between model, view, and controller can be above all observed in components like JTable or JTree, which use a data model:

  • A data model provides, in an unformatted form, the raw content to be displayed by the component.

  • The component uses a cell renderer to display the content of each cell in the component. Swing allows the cell renderer to be any kind of Swing component.

  • The controller role -- modification of the model and of the presentation after a user interaction -- is assumed by the component itself.

SWT components don't have such a clean separation between model, view, and controller. If you create a table or tree using the SWT API only (that is, without using JFace), you'll probably miss the data models and cell renderers used in Swing. Creating a table using only the pure SWT API obliges you to create each row and each column like a standard control in a container, and to initialize them with rendered text and images. There is no support in SWT for data models.

Fortunately, on top of the standard SWT controls, JFace provides a framework that is comparable to the concepts used in Swing. To use this framework, you have to instantiate a JFace viewer on top of the basic SWT table or tree. There are different viewers specialized for each kind of control: TableViewer for a table, TreeViewer for a tree, etc. A viewer is a class that will extract data from a data model and automatically create and initialize the rows or items to display.

The equivalent of Swing's data model is in JFace called a content provider (see org.eclipse.jface.viewers.IContentProvider ). Like a Swing TreeModel or TableModel, a content provider provides unformatted raw data that has to be displayed in the component. Unlike Swing's data models, JFace's content providers don't contain the data itself; instead, they extract that data from an input object that can be any kind of object. In this way, a JFace content provider acts as a data extractor: it knows how to extract data from a specific sort of input object, and provides a public interface used by the viewer to fill the underlying SWT component.

The equivalent of Swing's cell renderers in JFace is called a label provider (see org.eclipse.jface.viewers.ILabelProvider ). Like Swing's renderers, the label provider defines how raw data provided by the content provider has to be displayed in the SWT component. JFace is here not as flexible as Swing is. In SWT/JFace, a cell of a tree or a table can only be represented by an icon and/or text. If you need custom rendering for some other kind of data, you have to display the renderer into an image and make the label provider return that image.

For more information and examples of how to use JFace viewers, read the related articles in Resources.


Events

Like AWT and Swing, SWT lets your application react to user interactions by registering event listeners on components. There is not much difference in this area; the events thrown are all subclasses of java.util.EventObject, and the kind of events that are thrown, along with the listeners or adapters that are notified, are comparable to those in AWT and Swing.

Of course, the hierarchy of the events and their associated listeners is different. In Widgets , we'll see what kind of events are thrown for SWT controls, and compare each to its Swing equivalent.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多