/*
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();
}
}
|