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:
Create the ReservationForm.java
class file.
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;
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;
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));
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");
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); }
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); }
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(); }
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.