Eclipse SWT (Standard part Toolkit) provides a rich set of APIs to implement custom widgets (widgets). In this article, the author briefly introduces the MVC (model-View-Controller) architecture, explains the current implementation of MVC in the form of a structured viewer, and introduces an implementation that uses custom SWT widgets.
What is MVC?
The MVC architecture (or design pattern) is a graphical user interface (GUI) design style, consisting of three parts: models, views, and controllers. MVC decoupled the presentation layer from the data, and also decoupled the representation from the operation of the data.
Implementing the MVC architecture differs from other types of applications. The main differences come from how to place and implement business logic or view rendering logic. Unlike a typical WEB application, in which a programmer must design and implement all the MVC components, the API provided by Eclipse can do most of the control or rendering work for you. Therefore, it is not strictly possible to compare the MVC implementation of Eclipse with the Web or MVC of other application types.
Eclipse JFace
The Eclipse JFace implements the MVC architecture with content providers and label providers. The JFace API wraps standard (not unimportant) parts, such as tables and trees, and implements structured content providers and label providers. Different content providers can be implemented based on the part type. A list-oriented viewer implements a structured viewer, while the content is mapped to part entries in a structured (list) manner.
The base class, called the viewer, is an extension of the structured viewer. The viewer acts as a part container. The content provider obtains the data in a structured manner; Similarly, the label provider obtains the corresponding label. The JFace Viewer implementation retrieves the data, sets the corresponding association, and updates the user interface (UI) component with the dataset. It also performs selection, filtering, and sorting.
How to implement JFace
Eclipse View and Viewer are responsible for performing most of the JFace control functions. The Viewer, or the view portion of MVC, also acts as a component container;
Eclipse View instantiates the viewer, content provider, and label provider and acts as a model, holds value objects, and sets them to inputelement in the viewer.
To create a View, instantiate the Viewer with the Createpartcontrol () method. Listing 1 instantiates a default tree viewer, or you can customize the tree and use the tree object as a parameter to instantiate the tree viewer with the constructor.
Listing 1. The Createpartcontrol method of Exampleview
public class Exampleview extends Viewpart {... public void Createpartcontrol (composite parent) {//define a grid L Ayout GridLayout layout = new GridLayout (); Layout.numcolumns = 1; layout.marginheight = 0; layout.marginwidth = 0; L ayout.horizontalspacing = 0; layout.verticalspacing = 1; Parent.setlayout (layout); Create Widgets Createactionbar (parent); Createtree (parent); Add context menu and listeners Viewer.adddoubleclicklistener (this); Viewer.addselectionchangedlistener (openaction); Register Viewer so actions respond to selection getsite (). Setselectionprovider (Viewer); Hookcontextmenu (); } private void Createtree (composite parent) {viewer = new Treeviewer (parent, SWT. Single | Swt. H_scroll | Swt. V_scroll | Swt. BORDER); Viewer.setcontentprovider (New Exampleviewcontentprovider ()); Viewer.setlabelprovider (New Exampleviewlabelprovider ()); Viewer.setsorter (New Viewersorter ()); Viewer.setinput (Modelmanager.getexamplemodel ()); Viewer. GetControl (). Setlayoutdata (New Griddata (Griddata.fill_both)); } ... }
Implement ContentProvider in another standalone class, an object that provides data to the view with an interface that is appropriate for the viewer type. For example, you can implement a istructuredcontentprovider or Itreecontentprovider viewer.
Implement one of the following methods in the ContentProvider code to correlate the ContentProvider with the Viewer:
- GetElements (Object parent)
- GetChildren (Object Element)
Note: These methods are called by the JFace framework.
Listing 2. Create a custom ContentProvider
public class Exampleviewcontentprovide implements Itreecontentprovide {
The MVC schema typically contains multiple views and a data source. Currently on the Eclipse platform, only one view can be associated with a model. However, you can also create multiple views that access the same data with the adapter view. Just include the inputchanged () method in the ContentProvider class. As long as the Viewer has a new input set, the Inputchanged () method is used to notify the ContentProvider. The Inputchanged () method accepts the Viewer as an input parameter, so multiple views can use a contentprovider.
Listing 3. Using the Inputchanged method for different viewers
/** * Register content provider with model. */Public void inputchanged (Viewer Viewer, Object Oldinput, Object Newinput) { if (newinput!= null) { C6/>this.viewer = viewer; This.model = (exampledelegate) newinput; This.model.addModelListener (this); }
using MVC in conjunction with Eclipse SWT
In most common GUI applications, you create a layout to display the requested data, or to complete a form, such as a user interface, to add or modify data. The sample application in Figure 1 demonstrates how to display data from an XML store in a custom form, in read-only and programmable mode. It also explains the role of each component relative to the MVC schema.
Figure 1. Sample Application
Figure 2 shows the application's class diagram, which helps to better understand the overall architecture.
Figure 2. Class diagram of the sample application
Creating Controls
Exampleview acts as a container for the entire application. It initializes the application in the Createpartcontrol method.
Listing 4. Createpartcontrol method initializes the layout
public void Createpartcontrol (composite parent) { Exampleeditlayout _layout = new exampleeditlayout (parent, Swt. None,fieldmode.read,new Exampleviewcontentprovider ());
creating forms and layouts
The basic layout class defines the global methods and declarations used by different form applications. Some container events that act as callback mechanisms are also registered here.
Listing 5. CreateControl Method of Layout
public void Createcontrols (int style) {Griddata griddata; Text textfld, SUBJECTFLD; Control Tolabel, CcLabel, BccLabel; Control fromdatetime; Control control; Button Durationtext; Button submit; GridLayout layout = new GridLayout (2, false); layout.marginwidth = 0; Layout.marginheight = 4; SetLayout (layout); Label griddata = new Griddata (Griddata.horizontal_align_fill | Griddata.vertical_align_center); Griddata.horizontalindent = 10; Labelfactory.create (This, messages.getstring ("Exampleeditlayout.title"), Griddata); $NON-nls-1$ griddata = new Griddata (Griddata.horizontal_align_fill | Griddata.vertical_align_center); Griddata.horizontalindent = 40; Labelfactory.create (This, "", griddata); Text griddata = new Griddata (Griddata.horizontal_align_fill | Griddata.vertical_align_center); Griddata.horizontalindent = 10; Control = Labelfactory.create (This, messages.getstring ("Exampleeditlayout.email"), GRiddata); $NON-nls-1$ griddata = new Griddata (griddata.horizontal_align_beginning | Griddata.vertical_align_center); Griddata.horizontalindent = 10; Control = Textfactory.create (this, SWT. BORDER | Swt. V_scroll | Swt. WRAP, Griddata, Fieldmode.edit); $NON-nls-1$ AddField (New TextField (Control, Exampleviewcontentprovider.first_index)); Combo griddata = new Griddata (Griddata.horizontal_align_fill | Griddata.vertical_align_center); Griddata.horizontalindent = 10; Labelfactory.create (This, messages.getstring ("Exampleeditlayout.group"), Griddata); $NON-nls-1$ griddata = new Griddata (griddata.horizontal_align_beginning | Griddata.vertical_align_center); Griddata.horizontalindent = 40; Control = Combofactory.create (this, Fieldmode.edit, false, Griddata); $NON-nls-1$ AddField (New Combofield (Control, Exampleviewcontentprovider.second_index)); ...}
Create a field (view)
Field is an abstract class that defines methods that contain various user interface controls, as well as the associated IDs of these controls globally. Each user interface control is a subclass of Field and provides read and write capabilities to content providers. Listing 6 creates a Field in the Layout class with the factory pattern.
Listing 6. Create a text object with the Field class
public class TextField extends Field { /** * @param control * @param ID /public TextField (Control C Ontrol, int id) { super (control, ID); } /* Based on the widget, values retrieved from * The content provider are set. * /public void readfromcontent (Iexamplecontentprovider content) { string newtext = (string) Content.getelement (GetId ()); if (NewText!= null) ((Text) _control). SetText (NewText); /* Based on the widget, values retrieved from widget are * sent the content provider. */Public void Writetocontent (Iexamplecontentprovider content) { String NewText = ((Text) _control). GetText ( ); Content.setelement (GetId (), NewText); }
simplifying content providers (models)
Exampleviewcontentprovider acts as a model listener, which extends from Istructuredcontentprovider. It is a simple implementation of the Eclipse API and provides a callback for retrieving data. Each request data entry is based on the unique ID defined in the layout for the entry in the view creation.
The method call returns the data associated with each defined global ID. In the content provider shown in Listing 7, you can use an adapter to retrieve data from an XML file or a database.
Listing 7. Implementing a method in a custom ContentProvider
Public Object getelement (int iindex) { switch (iindex) {case first_index:return ' developer@ibm.com '; Case Second_index:return New Integer (1); Case Fourth_index:return New Boolean (true); Case Third_index:return New Boolean (false); Case Fifth_index:return New Boolean (false); return null; }
After you create the control and initialize the layout, the form uses the control ID to require the content provider to populate the form controls with data.
Listing 8. Initialize the layout and populate the control's form
Public Form (composite parent, int style, Fieldmode mode, exampleviewcontentprovider content) { super (parent, style); _content = content; _style = style; SetMode (mode); init (style); } private void init (int style) { createcontrols (style); Controlscreated (); } protected void controlscreated () { readfromcontent (); }
Concluding remarks
Web applications are early adopters of the MVC architecture style. However, with the advent of simple and powerful development platforms like Eclipse, programmers can easily develop richer user interfaces with shorter time and minimal complexity.