Tutorial 6: Menu Bar

This tutorial will be implemented only in C++.

The last tutorial introduced Layout Managers. In this tutorial we will build a menu for our application. Today most applications have a menu bar with several menues, like "File", "Edit" and "Help". In this example we will build a small menu. Our filemenu will contain an exit menuitem and a checkboxmenuitem. In our help menu there is only an about menuitem, which opens an other form. On the form we put a choice for changing the backgroound color of the frame.

So lets have a look how to build a menu.

We have to program the following for this example:

#include "grubc/awt/frame.h"
#include "grubc/awt/panel.h"
#include "grubc/awt/menubar.h"
#include "grubc/awt/menu.h"
#include "grubc/awt/menuitem.h"
#include "grubc/awt/checkboxmenuitem.h"
#include "grubc/awt/label.h"
#include "grubc/awt/choice.h"
#include "grubc/swing/messagebox.h"
#include "grubc/awt/simplelayout.h"


/* The colors for the frame. */
struct my_color {
   const char* name;
   const Color* color;
};

const int ccolors = 4;
struct my_color colors[ccolors] = {{"white", &WHITE},
      {"red", &RED}, {"green", &GREEN}, {"blue", &BLUE}};

/* Declare the needed variables. */
Jvm jvm;
Frame frame;
Frame about;
Panel panel;
MenuBar menubar;
Menu file;
Menu filesubmenu;
Menu help;
MenuItem miexit;
MenuItem miabout;
Label label;
Choice choice;
CheckBoxMenuItem cbmiask;
SimpleLayout borderlayout;
SimpleLayout flowlayout;

jboolean exitprg = JNI_FALSE;


/* Declare the needed listener callback function. */
void windowListener(jint event, Window window);
void actionListener(Component source);
void itemListener(Component source, jboolean selected, const char* item);


int main(int argc, char *argv[]) {
   WindowListener wlframe; /* WindowListener Object of the frame. */
   WindowListener wlaboutframe; /* WindowListener Object of the about frame. */
   ActionListener almiexit; /* ActionListener Object for exit menuitem. */
   ActionListener almiabout; /* ActionListener Object for about menuitem. */
   ItemListener ilchoice; /* ItemListener Object for the choice. */

   initJvm(&jvm, "./grubc.jar"); /* Initialize the JVM. */

   createFrame(&frame); /* Create the frame. */
   createFrame(&about); /* Create the about frame. */
   createPanel(&panel); /* Create the panel. */
   createMenuBar(&menubar); /* Create the menubar. */
   createMenu(&file); /* Create the file menu. */
   createMenu(&help); /* Create the help menu. */
   createMenu(&filesubmenu); /* Create the filesubmenu. */
   createMenuItem(&miexit); /* Create the exit menuitem. */
   createMenuItem(&miabout); /* Create the about menuitem. */
   createCheckBoxMenuItem(&cbmiask); /* Create the ask checkboxmenuitem. */
   createLabel(&label); /* Create the label. */
   createChoice(&choice); /* Create the choice. */
   createBorderLayout(&borderlayout, 0, 0); /* Create the borderlayout. */
   createFlowLayout(&flowlayout, 10, 10, FLOWLAYOUT_CENTER); /* Create the flowlayout. */

   /* Register the callback functions as listeners. */
   wlframe = frame.addWindowListener(&windowListener);
   wlaboutframe = about.addWindowListener(&windowListener);
   almiexit = miexit.addActionListener(&actionListener);
   almiabout = miabout.addActionListener(&actionListener);
   ilchoice = choice.addItemListener(&itemListener);

   /* Set the title, state and layout of the frame. */
   frame.setTitle("Tutorial 6");
   frame.setSize(600, 300);
   frame.setLayout(borderlayout.getObject());

   /* Set the panels layout and color. */
   panel.setLayout(flowlayout.getObject());
   panel.setBackgroundColor(WHITE);

   /* Set the title and state of the about frame and display some text. */
   about.setTitle("About...");
   about.setSize(300, 200);
   about.drawString("This is tutorial 6!", 80, 60, NULL);

   /* Setup the label and the choice. */
   label.setText("Color:");
   for (int i = 0; i < ccolors; i++) {
      choice.addItem(colors[i].name);
   }

   /* Set the menus captions. */
   file.setLabel("File");
   help.setLabel("Help");
   filesubmenu.setLabel("Options");
   cbmiask.setLabel("Ask before closing");
   miexit.setLabel("Exit");
   miabout.setLabel("About...");

   /* Set the checkboxmenuitem selected. */
   cbmiask.setState(JNI_TRUE);

   /* Build the menu. */
   menubar.addMenu(&file);
   menubar.addMenu(&help);
   file.addMenuItem(filesubmenu.getObject());
   file.addSeparator();
   file.addMenuItem(miexit.getObject());
   help.addMenuItem(miabout.getObject());
   filesubmenu.addMenuItem(cbmiask.getObject());

   /* Add the menu bar to the frame. */
   frame.setMenuBar(&menubar);

   /* Add control elements. */
   frame.addComponentWithConstraint(panel.getObject(), BORDERLAYOUT_NORTH);
   panel.addComponent(label.getObject());
   panel.addComponent(choice.getObject());
 
   frame.show(); /* Display the frame. */
   
   /* Wait until the user wants to close the frame (exitprg is true). */
   while (!exitprg) {
      jnisleep(100); /* Sleep 100 ms. */
      if (exitprg) { /* Should frame be closed??? */
         if (cbmiask.getState()) { /* Ask before closing??? */
            exitprg = (showModalConfirmDialog(&frame, "Do you really want to exit?") == MSGBOX_YES);
         }
      }
   }

   about.close(); /* Close the about frame. */
   frame.close(); /* Close the frame. */

   /* Deregister the callback functions. */
   frame.removeWindowListener(wlframe);
   about.removeWindowListener(wlaboutframe);
   miabout.removeActionListener(almiabout);
   miexit.removeActionListener(almiexit);
   choice.removeItemListener(ilchoice);

   /* Cleanup */
   deleteMenuItem(&miabout);
   deleteMenuItem(&miexit);
   deleteCheckBoxMenuItem(&cbmiask);
   deleteMenu(&filesubmenu);
   deleteMenu(&file);
   deleteMenu(&help);
   deleteMenuBar(&menubar);
   deleteSimpleLayout(&flowlayout);
   deleteLabel(&label);
   deleteChoice(&choice);
   deletePanel(&panel);
   deleteFrame(&about);
   deleteFrame(&frame);

   return 0;
}

void windowListener(jint event, Window window) {
   if (frame.isSameWindow(window)) {
      switch (event) {
         case CB_WINDOW_OPENED:
            break;
         case CB_WINDOW_CLOSING:
            exitprg = JNI_TRUE; /* Frame should be closed. */
            break;
         case CB_WINDOW_CLOSED:
            break;
         case CB_WINDOW_ICONIFIED:
            break;
         case CB_WINDOW_DEICONIFIED:
            break;
         case CB_WINDOW_ACTIVATED:
            break;
         case CB_WINDOW_DEACTIVATED:
            break;
      }
   } else if (about.isSameWindow(window)) {
      switch (event) {
         case CB_WINDOW_OPENED:
            break;
         case CB_WINDOW_CLOSING:
            about.hide(); /* About frame should be closed. */
            break;
         case CB_WINDOW_CLOSED:
            break;
         case CB_WINDOW_ICONIFIED:
            break;
         case CB_WINDOW_DEICONIFIED:
            break;
         case CB_WINDOW_ACTIVATED:
            break;
         case CB_WINDOW_DEACTIVATED:
            break;
      }
   }
}

void actionListener(Component source) {
   /* Check if the source was the exit button??? */
   if (isSameObject(source, miexit.getObject())) {
      exitprg = JNI_TRUE;
   } else if (isSameObject(source, miabout.getObject())) {
      about.show();
   }
}

void itemListener(Component source, jboolean selected, const char* item) {
   /* Check if the source was the choice??? */
   if (isSameObject(source, choice.getObject())) {
      for (int i = 0; i < ccolors; i++) {
         if (strcmp(colors[i].name, item) == 0) {
            frame.setBackgroundColor(*colors[i].color);
            break;
         }
      }
   }
}

When you execute it you will get a window which looks like this:

tutorial6.gif

Generated on Sat Nov 19 14:11:18 2005 for GrubC by  doxygen 1.4.4