Using eSWT

MIDlets using eSWT have similar requirements as MIDlets using LCDUI. Both must implement the common MIDlet lifecycle methods as described in section Implementing MIDlet lifecycle requirements.

In addition, eSWT MIDlets must also meet the requirements that are described below

In other words, an eSWT MIDlet should first create the UI thread in the MIDlet.startApp() method and then a Display instance in the UI thread. This Display instance must stay active until the MIDlet is destroyed.

eSWT classes

Figure 36: eSWT class diagram

The eSWT API offers the Display class for constructing the user interface thread, and implementing the event loop. After the user interface thread is constructed, a top-level Shell is created which in turn can contain widgets and UI elements. For an example of this, see HelloWorld in eSWT below.

Only the user interface thread can invoke user interface operations. If you try to access an SWT object outside the user interface thread, you will get an SWTException("Invalid thread access"). User input generated events and system events are handled by an event loop that listens for events in a message queue and dispatches them to the appropriate handlers until the user interface thread is disposed of. Note that the user interface thread can also access system resources.

HelloWorld in eSWT

Figure 37: eSWT Hello World MIDlet

import javax.microedition.midlet.*;

import org.eclipse.ercp.swt.mobile.Command;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

public class HelloWorld extends MIDlet implements Runnable, SelectionListener, PaintListener {

  // A handle to the eSWT UI thread created by this MIDlet. 
  private Thread UIThread;
  // The eSWT Display created by this MIDlet in the eSWT UI thread.
  // When this is created the MIDlet gets connected to the native UI
  // functionality and eSWT UI toolkit is initialised for it. 
  private Display display;
  // A Shell widget created by this MIDlet. 
  private Shell shell;
  // A custom color resource owned by this MIDlet. 
  private Color myColor;
  // A boolean to set when the event loop should exit. 
  private boolean exiting = false;

  public void startApp() {
    // Create the eSWT UI thread. 
    if(UIThread == null) {
      UIThread = new Thread(this);
      UIThread.start();
    }
  }

  public void pauseApp() {
    // Here we could reduce the resources but we should keep the Display 
    // instance and the eSWT UI Thread. 
  }

  // destroyApp is called when the MIDlet is terminated from the task list 
  // with the clear key, or the end key is pressed when the MIDlet is focused. 
  // It might also be called when the system needs to close applications 
  // e.g. in low memory conditions. 
  public void destroyApp(boolean unconditional) {
    // Make the event loop exit in the eSWT UI thread.
    exitEventLoop();
    // Wait for the eSWT UI thread to die. 
    try {
      UIThread.join();
    } catch(InterruptedException e) {
    }
  }

  // This method can be called from any thread to make the event loop to exit. 
  void exitEventLoop() {
    exiting = true;
    Display.getDefault().wake();
  }
  
  // The eSWT UI Thread. 
  public void run() {
    // Create the Display. 
    display = new Display();

    shell = new Shell(display);
    shell.open();

    Command exitCommand = new Command(shell, Command.EXIT, 0);
    exitCommand.setText("Exit");
    exitCommand.addSelectionListener(this);

    // Allocate some resources that we will own. 
    myColor = new Color(display, 100, 100, 0);

    // Print the hello world greeting on the Shell.
    shell.addPaintListener(this);
    shell.redraw();

    // Execute the eSWT event loop. 
    while(!exiting) {
      if(!display.readAndDispatch()) {
        display.sleep();
      }
    }
    
    // Clean up and destroy the MIDlet.
    myColor.dispose();
    display.dispose();
    notifyDestroyed();
  }

  public void widgetDefaultSelected(SelectionEvent e) {
  }

  public void widgetSelected(SelectionEvent e) {
    // Exit command selected, exit the event loop. 
    exitEventLoop();
  }

  public void paintControl(PaintEvent e) {
    // Print a hello world greeting using the custom color resource. 
    e.gc.setForeground(myColor);
    e.gc.drawText("Hello world!", 0, 0, SWT.DRAW_TRANSPARENT);
  }
}