MovieBooking.java
/*
* Copyright © 2011 Nokia Corporation. All rights reserved.
* Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
* Oracle and Java are trademarks or registered trademarks of Oracle and/or its
* affiliates. Other product and company names mentioned herein may be trademarks
* or trade names of their respective owners.
* See LICENSE.TXT for license information.
*/
package com.nokia.example.moviebooking.ui;
import java.util.Vector;
import javax.microedition.midlet.MIDlet;
import com.nokia.example.moviebooking.moviedb.BookingTicket;
import com.nokia.example.moviebooking.moviedb.Movie;
import com.nokia.example.moviebooking.moviedb.MovieDB;
import com.nokia.example.moviebooking.moviedb.MovieDBEvent;
import com.nokia.example.moviebooking.moviedb.MovieDBListener;
import com.nokia.example.moviebooking.moviedb.Showing;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.MessageBox;
/**
* The class MovieBooking is the core of the application It takes care
* of managing the user interface, drive the eSWT event loop and talk
* to the Movie Database
*/
public class MovieBooking implements Runnable, MovieDBListener {
private MovieDB movieDB;
private Shell mainShell;
private SplashScreen splashScreen;
private Display display;
private ReservationForm reservationForm;
private boolean running = false;
private MIDlet midlet;
public MovieBooking(MIDlet midlet) {
this.midlet = midlet;
}
// In the run method we execute the eSWT event loop
public void run() {
running = true;
// Note that Display has to be created here since that
// determines the UI thread
display = new Display();
// Create the main shell
mainShell = new Shell(display, SWT.NONE);
mainShell.setText("MovieBooking");
// Create a layout for the shell
GridLayout layout = new GridLayout();
// Zero the margins that are non-zero by default
layout.horizontalSpacing = 0;
layout.verticalSpacing = 0;
layout.marginWidth = 0;
layout.marginHeight = 0;
mainShell.setLayout(layout);
// open first this shell to be in the background
mainShell.open();
mainShell.setRedraw(false);
// Creates the splash screen
splashScreen = new SplashScreen(this, mainShell);
// Activate the layout of the mainShell to make it resize
// the splashScreen
mainShell.layout();
mainShell.setRedraw(true);
// Create the MovieDB and request that it starts loading the data
movieDB = new MovieDB(getClass().getResourceAsStream(
"/res/movieDB.properties"));
movieDB.setDBListener(this);
// This starts loading the data on a separate thread
movieDB.loadData();
// eSWT event loop runs until the main shell is disposed
// or the running flag is set to false.
// The flag can get set due to a user initiated exit or due to
// a system request to terminate the application.
while (running && !mainShell.isDisposed()) {
// Check if there are pending events
if (!display.readAndDispatch()) {
// otherwise sleep
display.sleep();
}
}
// Dispose the display, this will also dispose mainShell
display.dispose();
// Destroy the MIDlet
midlet.notifyDestroyed();
}
// This is called when new data is loaded by MovieDB
public void handleEvent(MovieDBEvent event) {
// check anyway if the mainShell is still alive
if (!mainShell.isDisposed()) {
// this is a non-GUI thread. we need to do actions
// in the GUI thread and so asyncExec is used
SplashScreenRunnable runnable = new SplashScreenRunnable(event);
display.asyncExec(runnable);
}
}
// Exit method
public void exit() {
// close the DB and dispose the main shell
movieDB.close();
running = false;
display.wake();
}
// Show the reservation form when coming back from seatingShell
void setSelectedSeats(int[][] selected) {
reservationForm.setSelectedSeats(selected);
}
void cancelSeatSelection() {
reservationForm.cancelSeatSelection();
}
// Show the reservation form
void startReserve(Movie movie) {
reservationForm = new ReservationForm(MovieBooking.this,
mainShell,
movie);
}
// Shown when the reservation is being sent to movieDB
void confirmReservation(String firstNameText,
String familyNameText, Showing showing, int[][] selectedSeats) {
// Ask MovieDB to request some seats
dataLoaded();
int result = displayMessageBox(SWT.ICON_INFORMATION | SWT.YES | SWT.NO,
"Booking",
"Are you sure you want to reserve?");
if (result == SWT.YES) {
// return to the movie list
movieDB.sendBookingRequest(firstNameText, familyNameText,
showing, selectedSeats);
}
}
// Displays a message box
int displayMessageBox(int type, String text, String message) {
if (Thread.currentThread() == display.getThread()) {
MessageBox box = new MessageBox(mainShell, type);
box.setText(text);
box.setMessage(message);
return box.open();
} else {
return -1;
}
}
// Shows the seating dialog
void showSeatingDialog(Showing showing, int[][] selectedSeats,
int ticketsCount) {
new SeatingScreen(this, mainShell, showing,
selectedSeats, ticketsCount);
}
// Advance the progress bar in SplashShell
private void advanceSplashShellProgress(String message) {
splashScreen.setLabel(message);
splashScreen.advance();
}
// Called if an error occured in movieDB
private void movieDBDataError() {
displayMessageBox(SWT.ICON_ERROR,
"Information",
"Error loading the database");
// Exit the swt loop
mainShell.dispose();
}
// Set the total amount of movies to display
private void setMovieCount(int count) {
splashScreen.setMoviesCount(count);
}
// Show a dialog box when a reservation has been confirmed
private void displayReservationConfirmed(BookingTicket booking) {
displayMessageBox(SWT.ICON_INFORMATION | SWT.OK,
"Booking",
"Reservation confirmed number " + booking.getCode()
+ " total: " + booking.getPrice());
}
// Called when all the data in MovieDB is
// available. We close splashShell and
// start Movie Display
private void dataLoaded() {
if (splashScreen != null) {
splashScreen.destroy();
splashScreen = null;
}
Vector movies = movieDB.getMovies();
if (movies.isEmpty()) {
// No movie found
displayMessageBox(SWT.ICON_INFORMATION | SWT.OK,
"Information",
"No movies available");
// Exit the swt loop
mainShell.dispose();
} else {
// Start the new MovieDisplay screen
new MoviesListScreen(MovieBooking.this, mainShell, movies);
}
}
// Inner class used to call actions on the GUI
// being initiated in MovieDB
private class SplashScreenRunnable implements Runnable {
private MovieDBEvent event;
SplashScreenRunnable(MovieDBEvent event) {
this.event = event;
}
public void run() {
// Note that this is called from the GUI thread
switch (event.getEvent()) {
case MovieDBEvent.CONNECTING:
// When connecting update the progress label
// in the splash shell
advanceSplashShellProgress("Loading from " + (String) event.getData());
break;
case MovieDBEvent.DATA_ERROR:
movieDBDataError();
break;
case MovieDBEvent.MOVIES_COUNT:
setMovieCount(((Integer) event.getData()).intValue() + 1);
break;
case MovieDBEvent.MOVIE_LOADED:
// Called when data for a new movie is available
advanceSplashShellProgress("Movie "
+ (((Integer) event.getData()).intValue() + 1));
break;
case MovieDBEvent.DATA_LOADED:
dataLoaded();
break;
case MovieDBEvent.MOVIE_RESERVED:
displayReservationConfirmed((BookingTicket) event.getData());
break;
}
}
}
}