2D Graphics GUI Java

/*
Java Media APIs: Cross-Platform Imaging, Media and Visualization
Alejandro Terrazas
Sams, Published November 2002, 
ISBN 0672320940
*/
import java.awt.*;
import java.awt.event.*;
import javax.media.*;
import javax.media.protocol.*;
import javax.media.control.*;
import java.io.*;
/*******************************************************************************
 * A Graphical application allowing the user to choose the media they wish to
 * play. PlayerOfMedia presents a Dialog in which the user may enter the URL of
 * the media to play, or select a file from the local system.
 * 
 * @author Spike Barlow
 ******************************************************************************/
public class PlayerOfMedia extends Frame implements ActionListener,
    ControllerListener {
  /** Location of the media. */
  MediaLocator locator;
  /** Player for the media */
  Player player;
  /** Dialog for user to select media to play. */
  Dialog selectionDialog;
  /** Buttons on user dialog box. */
  Button cancel, open, choose;
  /** Field for user to enter media filename */
  TextField mediaName;
  /** The menus */
  MenuBar bar;
  Menu fileMenu;
  /** Dialog for informing user of errors. */
  Dialog errorDialog;
  Label errorLabel;
  Button ok;
  /** Graphical component for controlling player. */
  Component controlComponent;
  /** Graphical component showing what isbeing played. */
  Component visualComponent;
  /** Graphical component to show download progress. */
  Component progressBar;
  /** Sizes to ensure Frame is correctly sized. */
  Dimension controlSize;
  Dimension visualSize;
  int menuHeight = 50;
  /** Directory user last played a file from. */
  String lastDirectory = null;
  /** Flags indicating conditions for resizing the Frame. */
  protected static final int VISUAL = 1;
  protected static final int PROGRESS = 2;
  /***************************************************************************
   * Construct a PlayerOfMedia. The Frame will have the default title of
   * "Player of Media". All initial actions on the PlayerOfMedia object are
   * initiated through its menu (or shotcut key).
   **************************************************************************/
  PlayerOfMedia() {
    this("Player of Media");
  }
  /***************************************************************************
   * Construct a PlayerOfMedia. The Frame will have the title supplied by the
   * user. All initial actions on the PlayerOfMedia object are initiated
   * through its menu (or shotcut key).
   **************************************************************************/
  PlayerOfMedia(String name) {
    super(name);
    ///////////////////////////////////////////////////////////
    // Setup the menu system: a "File" menu with Open and Quit.
    ///////////////////////////////////////////////////////////
    bar = new MenuBar();
    fileMenu = new Menu("File");
    MenuItem openMI = new MenuItem("Open...", new MenuShortcut(
        KeyEvent.VK_O));
    openMI.setActionCommand("OPEN");
    openMI.addActionListener(this);
    fileMenu.add(openMI);
    MenuItem quitMI = new MenuItem("Quit", new MenuShortcut(KeyEvent.VK_Q));
    quitMI.addActionListener(this);
    quitMI.setActionCommand("QUIT");
    fileMenu.add(quitMI);
    bar.add(fileMenu);
    setMenuBar(bar);
    ///////////////////////////////////////////////////////
    // Layout the frame, its position on screen, and ensure
    // window closes are dealt with properly, including
    // relinquishing the resources of any Player.
    ///////////////////////////////////////////////////////
    setLayout(new BorderLayout());
    setLocation(100, 100);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        if (player != null) {
          player.stop();
          player.close();
        }
        System.exit(0);
      }
    });
    /////////////////////////////////////////////////////
    // Build the Dialog box by which the user can select
    // the media to play.
    /////////////////////////////////////////////////////
    selectionDialog = new Dialog(this, "Media Selection");
    Panel pan = new Panel();
    pan.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    mediaName = new TextField(40);
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.gridwidth = 2;
    pan.add(mediaName, gbc);
    choose = new Button("Choose File...");
    gbc.ipadx = 10;
    gbc.ipady = 10;
    gbc.gridx = 2;
    gbc.gridwidth = 1;
    pan.add(choose, gbc);
    choose.addActionListener(this);
    open = new Button("Open");
    gbc.gridy = 1;
    gbc.gridx = 1;
    pan.add(open, gbc);
    open.addActionListener(this);
    cancel = new Button("Cancel");
    gbc.gridx = 2;
    pan.add(cancel, gbc);
    cancel.addActionListener(this);
    selectionDialog.add(pan);
    selectionDialog.pack();
    selectionDialog.setLocation(200, 200);
    ////////////////////////////////////////////////////
    // Build the error Dialog box by which the user can
    // be informed of any errors or problems.
    ////////////////////////////////////////////////////
    errorDialog = new Dialog(this, "Error", true);
    errorLabel = new Label("");
    errorDialog.add(errorLabel, "North");
    ok = new Button("OK");
    ok.addActionListener(this);
    errorDialog.add(ok, "South");
    errorDialog.pack();
    errorDialog.setLocation(150, 300);
    Manager.setHint(Manager.PLUGIN_PLAYER, new Boolean(true));
  }
  /***************************************************************************
   * React to menu selections (quit or open) or one of the the buttons on the
   * dialog boxes.
   **************************************************************************/
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() instanceof MenuItem) {
      //////////////////////////////////////////////////
      // Quit and free up any player acquired resources.
      //////////////////////////////////////////////////
      if (e.getActionCommand().equalsIgnoreCase("QUIT")) {
        if (player != null) {
          player.stop();
          player.close();
        }
        System.exit(0);
      }
      /////////////////////////////////////////////////////////
      // User to open/play media. Show the selection dialog box.
      /////////////////////////////////////////////////////////
      else if (e.getActionCommand().equalsIgnoreCase("OPEN")) {
        selectionDialog.show();
      }
    }
    //////////////////////
    // One of the Buttons.
    //////////////////////
    else {
      /////////////////////////////////////////////////////////////
      // User to browse the local file system. Popup a file dialog.
      /////////////////////////////////////////////////////////////
      if (e.getSource() == choose) {
        FileDialog choice = new FileDialog(this, "Media File Choice",
            FileDialog.LOAD);
        if (lastDirectory != null)
          choice.setDirectory(lastDirectory);
        choice.show();
        String selection = choice.getFile();
        if (selection != null) {
          lastDirectory = choice.getDirectory();
          mediaName.setText("file://" + choice.getDirectory()
              + selection);
        }
      }
      ///////////////////////////////////////////////
      // User chooses to cancel opening of new media.
      ///////////////////////////////////////////////
      else if (e.getSource() == cancel) {
        selectionDialog.hide();
      }
      ///////////////////////////////////////////////////////
      // User has selected the name of the media. Attempt to
      // create a Player.
      ///////////////////////////////////////////////////////
      else if (e.getSource() == open) {
        selectionDialog.hide();
        createAPlayer(mediaName.getText());
      }
      ////////////////////////////////////////////
      // User has seen error message. Now hide it.
      ////////////////////////////////////////////
      else if (e.getSource() == ok)
        errorDialog.hide();
    }
  }
  /***************************************************************************
   * Attempt to create a Player for the media who's name is passed the the
   * method. If successful the object will listen to the new Player and start
   * it towards Realized.
   **************************************************************************/
  protected void createAPlayer(String nameOfMedia) {
    ////////////////////////////////////////////////////////////
    // If an existing player then stop listening to it and free
    // up its resources.
    ////////////////////////////////////////////////////////////
    if (player != null) {
      System.out.println("Stopping and closing previous player");
      player.removeControllerListener(this);
      player.stop();
      player.close();
    }
    ///////////////////////////////////////////////////////////
    // Use Manager class to create Player from a MediaLocator.
    // If exceptions are thrown then inform user and recover
    // (go no further).
    //////////////////////////////////////////////////////////
    locator = new MediaLocator(nameOfMedia);
    try {
      System.out.println("Creating player");
      player = Manager.createPlayer(locator);
    } catch (IOException ioe) {
      errorDialog("Can't open " + nameOfMedia);
      return;
    } catch (NoPlayerException npe) {
      errorDialog("No player available for " + nameOfMedia);
      return;
    }
    //////////////////////////////////////////////////////////
    // Player created successfully. Start listening to it and
    // realize it.
    //////////////////////////////////////////////////////////
    player.addControllerListener(this);
    System.out.println("Attempting to realize player");
    player.realize();
  }
  /***************************************************************************
   * Popup a dialog box informing the user of some error. The passed argument
   * isthe text of the message.
   **************************************************************************/
  protected void errorDialog(String errorMessage) {
    errorLabel.setText(errorMessage);
    errorDialog.pack();
    errorDialog.show();
  }
  /***************************************************************************
   * Resize the Frame (window) due to the addition or removal of Components.
   **************************************************************************/
  protected void resize(int mode) {
    //////////////////////////////////////////
    // Player's display and controls in frame.
    //////////////////////////////////////////
    if (mode == VISUAL) {
      int maxWidth = (int) Math.max(controlSize.width, visualSize.width);
      setSize(maxWidth, controlSize.height + visualSize.height
          + menuHeight);
    }
    ////////////////////////////////
    // Progress bar (only) in frame.
    ////////////////////////////////
    else if (mode == PROGRESS) {
      Dimension progressSize = progressBar.getPreferredSize();
      setSize(progressSize.width, progressSize.height + menuHeight);
    }
    validate();
  }
  /***************************************************************************
   * React to events from the player so as to drive the presentation or catch
   * any exceptions.
   **************************************************************************/
  public synchronized void controllerUpdate(ControllerEvent e) {
    ///////////////////////////////////////
    // Events from a "dead" player. Ignore.
    ///////////////////////////////////////
    if (player == null)
      return;
    ////////////////////////////////////////////////////////////
    // Player has reached realized state. Need to tidy up any
    // download or visual components from previous player. Then
    // obtain visual and control components for the player,add
    // them to the screen and resize window appropriately.
    ////////////////////////////////////////////////////////////
    if (e instanceof RealizeCompleteEvent) {
      ////////////////////////////////////////////////////
      // Remove any inappropriate Components from display.
      ////////////////////////////////////////////////////
      if (progressBar != null) {
        remove(progressBar);
        progressBar = null;
      }
      if (controlComponent != null) {
        remove(controlComponent);
        validate();
      }
      if (visualComponent != null) {
        remove(visualComponent);
        validate();
      }
      ///////////////////////////////////////////////////////
      // Add control and visual components for new player to
      // display.
      //////////////////////////////////////////////////////
      controlComponent = player.getControlPanelComponent();
      if (controlComponent != null) {
        controlSize = controlComponent.getPreferredSize();
        add(controlComponent, "Center");
      } else
        controlSize = new Dimension(0, 0);
      visualComponent = player.getVisualComponent();
      if (visualComponent != null) {
        visualSize = visualComponent.getPreferredSize();
        add(visualComponent, "North");
      } else
        visualSize = new Dimension(0, 0);
      //////////////////////////////////////////////////////////
      // Resize frame for new components and move to prefetched.
      //////////////////////////////////////////////////////////
      resize(VISUAL);
      System.out.println("Player is now pre-fetching");
      player.prefetch();
    }
    ////////////////////////////////////////////////////////////
    // Provide user with a progress bar for "lengthy" downloads.
    ////////////////////////////////////////////////////////////
    else if (e instanceof CachingControlEvent
        && player.getState() <= Player.Realizing && progressBar == null) {
      CachingControlEvent cce = (CachingControlEvent) e;
      progressBar = cce.getCachingControl().getControlComponent();
      if (progressBar != null) {
        add(progressBar, "Center");
        resize(PROGRESS);
      }
    }
    ////////////////////////////////////////////////
    // Player initialisation complete. Start it up.
    ////////////////////////////////////////////////
    else if (e instanceof PrefetchCompleteEvent) {
      System.out.println("Pre-fetching complete, now starting");
      player.start();
    }
    ///////////////////////////////////////////////////////
    // Reached end of media. Start over from the beginning.
    ///////////////////////////////////////////////////////
    else if (e instanceof EndOfMediaEvent) {
      player.setMediaTime(new Time(0));
      System.out.println("End of Media - restarting");
      player.start();
    }
    //////////////////////////////////////////////////////////////
    // Some form of error. Free up all resources associated with
    // the player, don't listen to it anymore, and inform the
    // user.
    //////////////////////////////////////////////////////////////
    else if (e instanceof ControllerErrorEvent) {
      player.removeControllerListener(this);
      player.stop();
      player.close();
      errorDialog("Controller Error, abandoning media");
    }
  }
  /***************************************************************************
   * Create a PlayerOfMedia object and pop it up on the screen for the user to
   * interact with.
   **************************************************************************/
  public static void main(String[] args) {
    PlayerOfMedia ourPlayer = new PlayerOfMedia();
    ourPlayer.pack();
    ourPlayer.setSize(200, 100);
    ourPlayer.show();
  }
}