July 27, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Building a Java ME CDC Application Using the SavaJe Phone

  • October 24, 2006
  • By Carl Quinn
  • Send Email »
  • More Articles »

Coding the Xlet and the Main

I started out with the SavaJe HelloWorld sample Xlet, and turned it into a reusable abstract superclass to simplify writing small Xlets. All Xlets must implement the javax.microedition.xlet.Xlet interface that defines the four methods explained below, and this abstract class takes care of almost all of the work.

public abstract class SimpleXlet implements Xlet {

The first thing that happens after your Xlet is constructed is that your initXlet method is called. It is called exactly once during application startup and provides the context object for the Xlet. You'll use the context to retrieve your visual AWT Container object, and squirrel it away for later. Not much else should be done during this early phase of initialization.

public void initXlet(final XletContext xletContext)
   context = xletContext;
   if (rootContainer == null) {
      try {
         rootContainer = context.getContainer();

The next thing that happens during startup is that your startXlet method is called. This is where you can really kick off your Xlet by creating its main screen and getting it situated in the root container and making both windows visible.

public void startXlet() throws XletStateChangeException {
   if (screen == null) {
      EventQueue.invokeAndWait(new Runnable() {
         public void run() {
            screen = newScreen();
            screen.setVisible(true);
            rootContainer.add(screen);
            // This is needed - or nothing will be displayed.
            rootContainer.setVisible(true);
         }
      });

Your SimpleXlet doesn't actually know how to make a screen that does anything, so I have left that method abstract. It will need to be overridden in a real subclass that then is responsible for returning a fully populated InternalFrame that you add to the root container above.

protected abstract JInternalFrame newScreen();

An interesting thing to note with the Xlet lifecycle is that the application can be paused and restarted any number of times, resulting in pauseXlet and then startXlet being called alternately. This corresponds to the user switching away to another application and returning. In your simple Xlet, you'll take the easy road and discard your whole screen on pause, and rebuild it later on start as needed. You could, instead, choose to keep some of it around, but in general when an Xlet is paused it should be a good citizen and release resources that it doesn't really need.

public void pauseXlet() {
   EventQueue.invokeAndWait(new Runnable() {
      public void run() {
         rootContainer.remove(screen);
         screen = null;
      }
   });

The last call made into your Xlet is to the destroyXlet method. Here you could do any remaining cleanup that you didn't do in pauseXlet. In your case, though, you've already cleaned up and don't need to do anything.

public void destroyXlet(final boolean unconditional)

When your Xlet wants to shut itself down, there are a couple of things that it has to do, and so you've bundled them into a single handy method. The root container needs to be hidden, and the context notified that you are destroying yourself. That will trigger the shutdown sequence and everything will get cleaned up.

protected void exit() {
   rootContainer.setVisible(false);
   context.notifyDestroyed();
}

Your concrete SudokuXlet subclass extends the SimpleXlet and only needs to override the one abstract method to create your frame.

public class SudokuXlet extends SimpleXlet {

Your real newScreen implementation creates a JInternalFrame, adds a menubar with menus, and pops an instance of the actual SudokuPanel in the center. The phone itself has two menus, one for each of the soft keys. The left menu added is a generic exit item that delegates to your exit method defined above. The right menu is a game menu that is retrieved from the SudokuPanel, allowing the panel to remain unaware of its container's type or where its game menu actually goes.

protected JInternalFrame newScreen() {
   JInternalFrame screen = new JInternalFrame();

   screen.setTitle("Micro Sudoku!");
   final SudokuPanel panel = new SudokuPanel();
   screen.getContentPane().add(panel, BorderLayout.CENTER);

   JMenuBar menubar = new JMenuBar();
   menubar.add(new JMenu(new AbstractAction("Exit") {
      public void actionPerformed(final ActionEvent e) {
         System.out.println("Exiting...");
         exit();
      }
   }));
   menubar.add(panel.newGameMenu());
   screen.setJMenuBar(menubar);

   return screen;
}

Coding the Test Main

For the Java SE test application, the same general steps are followed. There, though, the entry point is main, and the panel's container is a JFrame. The meat of this single class looks remarkably similar to the Xlet screen construction, using the same SudokuPanel in the same way.

private void createAndShowGUI() {
   JFrame frame = new JFrame("Micro Sudoku");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

   SudokuPanel panel = new SudokuPanel();
   frame.getContentPane().add(panel, BorderLayout.CENTER);

   JMenuBar menubar = new JMenuBar();
   menubar.add(newFileMenu(frame));
   menubar.add(panel.newGameMenu());
   frame.setJMenuBar(menubar);

   frame.pack();
   frame.setVisible(true);
}

public static void main(String[] args) {
   javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
         new GameApp().createAndShowGUI();
      }
   });
}

And, the best part is that the actual game SudokuPanel is blissfully unaware of the application launch details or the specific frame class. Sweet.





Page 2 of 4



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel