Implementing the reservation screen

The ReservationForm class contains a form for entering data required for making a reservation. The basic fields include the first name, family name, date, time, and the number of tickets. The actual seating arrangement is defined in a separate form. The ReservationForm is created using a GridLayout with two columns that contain standard eSWT widgets: the first column contains five Labels, while the second column has five other widgets (two Text widgets, a DateEditor, a Combo, and at the bottom a ConstrainedText widget).

The ReservationForm class creates the following UI:

Figure: Reservation screen

To implement the reservation screen:

  1. Create the ReservationForm.java class file.

  2. Import the required classes.

    import java.util.Vector;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Hashtable;
    
    import com.nokia.example.moviebooking.moviedb.Movie;
    import com.nokia.example.moviebooking.moviedb.Showing;
    
    import org.eclipse.ercp.swt.mobile.Command;
    import org.eclipse.ercp.swt.mobile.ConstrainedText;
    import org.eclipse.ercp.swt.mobile.DateEditor;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.events.ModifyEvent;
    import org.eclipse.swt.events.ModifyListener;
    import org.eclipse.swt.events.SelectionEvent;
    import org.eclipse.swt.events.SelectionListener;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Label;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.swt.widgets.Text;
    import org.eclipse.swt.widgets.Combo;
  3. Set ReservationForm to implement SelectionListener and ModifyListener, and create the required variables.

    public class ReservationForm implements SelectionListener, ModifyListener {
    
        private MovieBooking main;
        private Command exitCommand, seatCommand, confirmCommand;
        private DateEditor movieDate;
        private Combo movieTime;
        private Composite mainComposite;
        private Hashtable validDates = new Hashtable();
        private Text firstNameText, familyNameText;
        private ConstrainedText ticketsText;
        private int[][] selectedSeats;
  4. Create a Composite into which the widgets can be placed.

        ReservationForm(MovieBooking main, Shell mainShell, Movie movie) {
            this.main = main;
            mainShell.setText("Reservation");
            mainShell.setRedraw(false);
            mainComposite = new Composite(mainShell, SWT.NONE);
    
            // Size and location of this Composite are controlled by
            // the GridLayout of the mainShell
            mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
  5. Create the widgets. For a full list of available widgets and their details, see the org.eclipse.swt.widgets package.

            // Create all the widgets in the Composite
            Label firstNameLabel = new Label(mainComposite, SWT.NONE);
            firstNameLabel.setText("First name");
            // Contains the first name
            firstNameText = new Text(mainComposite, SWT.SINGLE | SWT.BORDER);
            firstNameText.setTextLimit(20);
    
            Label familyNameLabel = new Label(mainComposite, SWT.NONE);
            familyNameLabel.setText("Family name");
            // Contains the family name
            familyNameText = new Text(mainComposite, SWT.SINGLE | SWT.BORDER);
            familyNameText.setTextLimit(20);
    
            Label dateLabel = new Label(mainComposite, SWT.NONE);
            dateLabel.setText("Date");
            // Date for the movie, by default today
            movieDate = new DateEditor(
                    mainComposite,
                    SWT.NONE,
                    DateEditor.DATE | SWT.BORDER);
            movieDate.setDate(new Date());
            movieDate.addModifyListener(this);
    
            // A drop-down list of times
            Label timeLabel = new Label(mainComposite, SWT.NONE);
            timeLabel.setText("Time");
            movieTime = new Combo(mainComposite, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER);
    
            Vector showings = movie.getShowings();
            Vector times = new Vector();
            // Store in the time combo the time valid
            // for all showings, validDates contains
            // a map between showingDate and showing
            for (int i = 0; i < showings.size(); ++i) {
                Showing show = (Showing) showings.elementAt(i);
                Calendar cal = Calendar.getInstance();
                cal.setTime(show.getDate());
                String showingTime = cal.get(Calendar.HOUR_OF_DAY) + ":00";
                if (!times.contains(showingTime)) {
                    times.addElement(showingTime);
                }
                validDates.put(show.getDate(), show);
            }
            for (int i = 0; i < times.size(); ++i) {
                movieTime.add((String) times.elementAt(i));
            }
            movieTime.select(0);
            movieTime.addSelectionListener(this);
    
            Label ticketsLabel = new Label(mainComposite, SWT.NONE);
            ticketsLabel.setText("Tickets");
    
            // Amount of tickets, note that ConstrainedText only takes numbers
            ticketsText = new ConstrainedText(mainComposite, SWT.SINGLE | SWT.BORDER, ConstrainedText.NUMERIC);
            ticketsText.addModifyListener(this);
            ticketsText.setText("2");
  6. Organize the widgets by using a layout. For a full list of available layouts and their details, see the org.eclipse.swt.layout package.

            // Use a grid layout with two columns
            GridLayout layout = new GridLayout();
            layout.makeColumnsEqualWidth = false;
            layout.numColumns = 2;
            mainComposite.setLayout(layout);
    
            // Distribute the forms using the layout
            firstNameText.setLayoutData(
                    new GridData(SWT.FILL, SWT.CENTER, true, false));
            familyNameText.setLayoutData(
                    new GridData(SWT.FILL, SWT.CENTER, true, false));
            ticketsText.setLayoutData(
                    new GridData(SWT.FILL, SWT.CENTER, true, false));
            movieDate.setLayoutData(
                    new GridData(SWT.FILL, SWT.CENTER, true, false));
            movieTime.setLayoutData(
                    new GridData(SWT.FILL, SWT.CENTER, true, false));
    
            setCommands();
            mainShell.layout();
            mainShell.setRedraw(true);
        }
  7. Add Commands to the screen:

    • exitCommand is used to exit the MIDlet.

    • seatCommand is used to select the seats for the specified showing. Selecting this command opens the seat selection screen.

    Use the setText method to define the text to be displayed for the commands. The commands are associated with a typed listener called SelectionListener, which invokes the appropriate method after an event has been generated by the Control. For more information on eSWT API typed listeners, see the org.eclipse.swt.events package.

        private void setCommands() {
            // add commands
            exitCommand = new Command(mainComposite.getShell(), Command.EXIT, 0);
            exitCommand.setText("Exit");
            exitCommand.addSelectionListener(this);
    
            seatCommand = new Command(mainComposite.getShell(), Command.GENERAL, 1);
            seatCommand.setText("Seating");
            seatCommand.addSelectionListener(this);
        }
  8. Define handlers for the generated events.

        // Called when some command is selected
        public void widgetSelected(SelectionEvent e) {
            if (e.widget == exitCommand) {
                // Exit the main application
                destroy();
                main.exit();
            } else if (e.widget == movieTime) {
                selectedSeats = null;
                if (confirmCommand != null) {
                    confirmCommand.dispose();
                    confirmCommand = null;
                }
            } else if (e.widget == seatCommand) {
                // Iterate over the valid dates
                Date showingDate = calculateTime();
    
                if (validDates.containsKey(showingDate) || (ticketsText.getText().length() == 0)) {
                    int ticketsCount = 0;
                    try {
                        ticketsCount = Integer.parseInt(ticketsText.getText());
                    } catch (NumberFormatException ex) {
                        // Ignore, just use 0
                    }
                    if (ticketsCount == 0) {
                        return;
                    }
                    Showing show = (Showing) validDates.get(showingDate);
                    exitCommand.dispose();
                    exitCommand = null;
                    seatCommand.dispose();
                    seatCommand = null;
                    if (confirmCommand != null) {
                        confirmCommand.dispose();
                        confirmCommand = null;
                    }
                    main.showSeatingDialog(show, selectedSeats, ticketsCount);
                } else {
                    main.displayMessageBox(SWT.ICON_ERROR | SWT.OK,
                            "Error",
                            "Wrong date selected");
                }
            } else if (e.widget == confirmCommand) {
                Date showingDate = calculateTime();
                // Validate the fields
                if (selectedSeats == null || firstNameText.getText().equals("")
                        || familyNameText.getText().equals("")) {
                    main.displayMessageBox(SWT.ICON_ERROR | SWT.OK,
                            "Error",
                            "Missing required fields");
                    return;
                } else {
                    // Request to main to make the reservation
                    String firstName = firstNameText.getText();
                    String familyName = familyNameText.getText();
                    destroy();
                    main.confirmReservation(firstName,
                            familyName, (Showing) validDates.get(showingDate), selectedSeats);
                }
            }
        }
    
        public void widgetDefaultSelected(SelectionEvent e) {
        }
    
        // Called when the user has selected the seats
        void setSelectedSeats(int[][] selected) {
            this.selectedSeats = selected;
            setCommands();
            if (confirmCommand == null && selectedSeats != null) {
                // Add a new command
                confirmCommand = new Command(
                        mainComposite.getShell(),
                        Command.GENERAL,
                        1);
                confirmCommand.setText("Confirm");
                confirmCommand.addSelectionListener(this);
                confirmCommand.setDefaultCommand();
            }
        }
    
        void cancelSeatSelection() {
            selectedSeats = null;
            if (confirmCommand != null) {
                confirmCommand.dispose();
                confirmCommand = null;
            }
            setCommands();
        }
    
        // Close the main composite and dispose it
        private void destroy() {
            if (confirmCommand != null) {
                confirmCommand.dispose();
                confirmCommand = null;
            }
            if (seatCommand != null) {
                seatCommand.dispose();
                seatCommand = null;
            }
            if (exitCommand != null) {
                exitCommand.dispose();
                exitCommand = null;
            }
            mainComposite.dispose();
        }
  9. Fetch the time and date of the movie showing.

        // Create a time based on movieDate and timeCombo
        private Date calculateTime() {
            if (movieTime.getSelectionIndex() == -1) {
                return null;
            } else {
                Calendar cal = Calendar.getInstance();
                // Take the date from movieDate
                Date showingDate = movieDate.getDate();
                cal.setTime(showingDate);
    
                // Get the time from movieTime, so we remove the last ":00"
                // Notice that we expect only exact minutes
                String time = movieTime.getItem(movieTime.getSelectionIndex());
                int hourOfDay = Integer.parseInt(time.substring(0, time.indexOf(':')));
                int minutes = Integer.parseInt(time.substring(time.indexOf(':') + 1, time.length() - 1));
    
                cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
                cal.set(Calendar.MINUTE, minutes);
                cal.set(Calendar.SECOND, 0);
                cal.set(Calendar.MILLISECOND, 0);
                return cal.getTime();
            }
        }
    
        public void modifyText(ModifyEvent e) {
            selectedSeats = null;
            if (confirmCommand != null) {
                confirmCommand.dispose();
                confirmCommand = null;
            }
        }
    }

Now that you have implemented the reservation screen, implement the seat selection screen.