### Custom widgets

Occasionally, you may find that none of the controls provided in SWT meet the need of your application. In these cases, you may want to extend SWT by implementing your own custom widget. SWT itself provides a package, org.eclipse.swt.custom, which contains custom controls that are not in the core set of SWT controls but are needed to implement the platform workbench.

Control | Purpose | Styles | Events
--- | --- | --- | ---
CCombo | Similar to Combo, but custom drawn to allow for using a combo without a border. This class was developed for using combos inside table cells. | BORDER, FLAT, READ_ONLY | Dispose, Control*, Selection
CLabel | Similar to Label, but supports clipping of text with ellipsis. Also supports a gradient effect for the background color as seen in the active workbench view. Does not support wrapping. | CENTER, LEFT, RIGHT, SHADOW_IN, SHADOW_OUT, SHADOW_NONE | Dispose, Control*
CTabFolder | Similar to TabFolder, but supports additional configuration of the visual appearance of tabs (top or bottom) and borders. | BORDER, FLAT, BOTTOM, TOP | Dispose, Control*, Selection
CTabItem | Selectable user interface object corresponding to a tab for a page in a CTabFolder. |  | Dispose, Control*
SashForm | Composite control that lays out its children in a row or column arrangement and uses a Sash to separate them so that the user can resize them. | BORDER, HORIZONTAL, VERTICAL | Dispose, Control*
ScrolledComposite | Composite control that scrolls its contents and optionally stretches its contents to fill the available space. | BORDER, H_SCROLL, V_SCROLL | Dispose, Control*
StyledText | Editable control that allows the user to type text. Ranges of text inside the control can have distinct colors (foreground and background) and font styles (bold and regular). | BORDER, FULL_SELECTION, MULTI, SINGLE, WRAP, READ_ONLY | Dispose, Control*, ExtendedModify, LineGetBackground, LineGetSegments, LineGetStyle, Modify, Selection, Verify, VerifyKey
TableTree | Selectable control that displays a hierarchical list of items that can be selected by the user. Items are presented in rows that display multiple columns representing different aspects of the items. | BORDER, SINGLE, MULTI, CHECK, FULL_SELECTION | Dispose, Control*, Selection, DefaultSelection, Collapse, Expand
TableTreeItem | Selectable user interface object that represents a hierarchy of tree items in a TableTree. |  |
ViewForm | Composite control that lays out three children horizontally and allows programmatic control of layout and border parameters. Used in the workbench to implement a view's label/toolbar/menu local bar. | BORDER, FLAT | Dispose, Control*

Control* = Events inherited from Control: FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick, MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove, Move, Paint, Resize

Before implementing a custom widget, you should consider several important issues:

- Can an existing SWT control be used as a simpler or plainer version of your widget? If so, consider using the existing control and finishing your application. You can always write a custom widget later that is API compatible with the simpler control.
- Does the widget have to be portable? If so, does a native widget exist on all platforms? If you are comfortable writing native platform code, you can provide a native implementation for each platform that your application supports. If it does not exist on any (or all) platforms, you will also have to provide a portable implementation.
- Can the function be achieved by extending the behavior of an existing control? If so, consider using an existing control and wrapping it with additional behavior.
- Will your widget contain other controls from the user's point of view? It's useful to think about this issue in advance because it influences your implementation and API.

Once you've determined that you need a custom widget and have decided which platforms must be supported, you can consider several implementation techniques for your widget. These techniques can be mixed and matched depending on what is available in the underlying OS platform.

#### Native implementation

If your application requires a native widget that is not provided by SWT, you will need to implement it natively. This may be a platform widget, a third party widget, or any other widget in a platform shared library.

Each SWT platform is shipped with both a shared library (for example, a DLL on Windows) and a JAR (for the Java class files). The shared library contains all of the native function required for SWT, but it was not meant to be a complete set of the functions available on the platform. To expose native function or native widgets that were not exposed by SWT, you need to write your own shared library. If you are using a combination of native code on one platform and portable code on another, make sure you call your shared library on the platform with the native widget, and your jar on the platform with the portable widget.

To implement a native widget, you must understand the Java Native Interface (JNI), the API of the widget in the shared library, and the underlying OS platform APIs in C.

The basic process for implementation is to decide which part of the API of the native widget will be exposed in the Java API and writing the Java code that calls the natives to implement the behavior. JNI C code must be written to call the shared library.

It is a good idea to follow the design principles used to implement SWT when building your own native widget implementation. For example, your JNI natives should map one to one with the API calls being made into the shared library.

A complete example of a native custom widget implementation can be found in Creating Your Own Widgets using SWT..

#### Extending an existing widget

If your new widget is similar in concept or implementation to an existing widget, you may want to wrap an existing SWT widget. This technique is used for the implementation of TableTree.

To wrap a widget, you create a subclass of the Composite or Canvas widget (depending on whether your control will have children). In the constructor for the custom widget, create the wrapped widget. The resulting widget will be 100% Java portable since you are calling the wrapped widget's API for your implementation.

Wrapping a widget is often a simpler way to implement custom widgets than starting from scratch. However, you must be careful in designing the API of your new widget. Here are some important tips:

Consider whether your widget is a "kind of" wrapped widget or whether it just uses one for its implementation. For example, a table tree is not a kind of table. It doesn't refer to items by row number index. The TableTree just uses a table to implement the presentation and adds tree behavior. If you are wrapping a widget purely for implementation reasons, then your API may not look similar to the underlying widget's API.

Forward as few methods and events as possible. Don't reimplement the entire API of the wrapped widget or you'll be constantly playing catch-up when the wrapped API changes in a future release. Methods that are common to most widgets, such as setFont, setForeground, setBackground, should be forwarded.

If you find yourself implementing most of the wrapped widget's API, consider exposing the wrapped widget at the API level and letting the application code use the wrapped widget directly. In this case, you may want to reconsider whether providing a new widget makes sense at all. It may be better to implement your feature as an "adapter" which adds behavior to a widget but does not pretend to be a widget. (JFace viewers follow this pattern.)

> Note: This discussion has focused solely on extending the behavior of a widget by wrapping it. Extending a widget by subclassing it is highly discouraged, since it will make your widget dependent on the implementation of the superclass.

#### Custom drawn implementation

In some cases, you don't have any native code or existing widgets that help you in the implementation of your new widget. This means you must draw the widget yourself using SWT graphics calls. Although this technique can become quite complicated, it has the advantage of producing a completely portable implementation.

Custom drawn controls are implemented by subclassing the Canvas or Composite class using these rules:

- Subclass Canvas if your widget will not have any children. This means you do not intend to allow applications to create children of your widget, and that you do not intend to create any children in order to implement your widget. Canvas is used for both simple controls, such as stylized labels, and for more complex controls, such as the styled text editor. In both cases, the widget is implemented completely internally using graphics calls and no children are added by applications.
- Subclass Composite if your widget will have children from the application's perspective, or if you will be creating children to implement your widget. Composite is used when you are combining widgets to create a new widget, such as using a text and list to implement a combo control. It is also used when you implement a widget without children that allows clients to add children. This is the case with the ViewForm control. The SashForm widget represents both cases: it uses widgets (sashes) internally for its implementation and allows clients to add their own children.

In a custom drawn control, your internal state is kept in Java instance variables. You define your API and styles according to the requirements of your widget.

The internal implementation of a custom drawn widget usually involves these major tasks:

- Create any graphics objects needed in your constructor and store them in an instance variable. Register a listener for the dispose event on your canvas or composite so that you can free these objects when the widget is destroyed.
- Add a paintListener to your canvas or composite and paint the widget according to your design. For complex widgets, a lot of work goes into optimizing this process by calculating and repainting only what's absolutely necessary.
- Ensure that any API calls that affect the appearance of your widget trigger a repaint of the widget. In general, you should use redraw to damage your widget when you know you must repaint, rather than call your internal painting code directly. This gives the platform a chance to collapse the paint you want to generate with any other pending paints and helps streamline your code by funneling all painting through one place.
- If your widget defines events in its API, determine what low level Canvas or Composite events will trigger your widget's events. For example, if you have a clicked event, you will want to register a mouse event on your canvas and perform calculations (such as hit testing) to determine whether the mouse event in your canvas should trigger your widget event.

Many of the widgets implemented in the org.eclipse.swt.custom use this approach. A simple example can be found in CLabel.

Further information on custom widgets can be found in Creating your own widgets using SWT.