📄 abstractplayer.java
字号:
} }; thread.setName("SynchronousStart Thread for " + this); getThreadQueue().addThread(thread); // TODO: this seems to be able to cause an NPE if window is abruptly closed, using MDIApp sample } /** * Adds a Controller to be controlled by this Player. * * @param newController * The Controller to add * * @exception NotRealizedError * If this Player or the new Controller are not * Realized. * * @exception ClockStartedError * If this Player or the new Controller are in the * Started state. * * @exception IncompatibleTimeBaseException * Thrown by newController.setTimeBase() if the * new Controller cannot use this player's * TimeBase */ public synchronized void addController(Controller newController) throws IncompatibleTimeBaseException { // Return immediately if the new Controller // is already being managed by this Player if( controllers.contains(newController) || this == newController ) { return; } int currentState = getState(); // Enforce state reqs for this Player if( currentState == Unrealized || currentState == Realizing ) { throw new NotRealizedError( "Cannot add Controller to an Unrealized Player"); } // Enforce state reqs for this Player if(currentState == Started) { throw new ClockStartedError( "Cannot add Controller to a Started Player"); } int controllerState = newController.getState(); // Enforce state reqs for new controller if( controllerState == Unrealized || controllerState == Realizing ) { throw new NotRealizedError( "Cannot add Unrealized Controller to a Player"); } // Enforce state reqs for this Player if(controllerState == Started) { throw new ClockStartedError( "Cannot add Started Controller to a Player"); } // Set the time base for the new Controller. This may // throw an IncompatibleTimeBaseException. newController.setTimeBase(getTimeBase()); // Stop any forward-transitions of this Player and the // to-be-managed Controller. This will allow us to // stabilize and synchronize the two. Also update the // current states of each. stop(); newController.stop(); currentState = getState(); controllerState = newController.getState(); // According to the API, if the new Controller is not // Prefetched, and this Player is Prefetched or // Prefetching, then this Player must be transitioned // back to the Realized state. if( controllerState < Prefetched && currentState > Realized ) { deallocate(); } // Set the media time for the new Controller newController.setMediaTime( getMediaTime() ); // Reset the stop time for the new Controller. It will // be stopped automatically when this Player's stop time // is reached. newController.setStopTime(Clock.RESET); // Set the rate for the new Controller. If the new // Controller cannot accomodate the current rate, then // the rate for all Controllers and this Player will be // set to 1.0. float rate = getRate(); if( rate != newController.setRate(rate) ) { newController.setRate(1.0F); setRate(1.0F); } // Add the controller to the list controllers.addElement(newController); // Add ourselves as a listener to the new Controller so // we can tell when the Controller has completed an event // transition newController.addControllerListener(this); // Update the overall duration updateDuration(); } /** * Remove a Controller from the list of Controllers managed by * this Player. * * @param oldController * The Controller to remove */ public synchronized void removeController(Controller oldController) { int currentState = getState(); if(currentState == Unrealized || currentState == Realizing) { throw new NotRealizedError( "Cannot remove Controller from an Unrealized Player"); } if(currentState == Started) { throw new ClockStartedError( "Cannot remove Controller from a Started Player"); } if( controllers.indexOf(oldController) == -1 ) { return; } // Stop all transitions. This is so that the // doTransition methods don't need to synchronize on the // controllers Vector. stop(); // This is already synchronized controllers.removeElement(oldController); // Remove ourselves as a listener on this Controller oldController.removeControllerListener(this); // Reset the timebase on the Controller try { oldController.setTimeBase(null); } catch(IncompatibleTimeBaseException e) {} // Update the overall duration updateDuration(); } /** * Gets the list of Controllers under control of this Player. */ protected Vector getControllers() { return (Vector)controllers.clone(); } /** * Set the GainControl for this AbstractPlayer. If the * AbstractPlayer does not support audio media, this method * should return null. * * @param c * The GainControl allowing control of the volume * of this AbstractPlayer's media. */ protected void setGainControl(GainControl c) { if( gainControl != null ) { removeControl(gainControl); } addControl(c); gainControl = c; } /** * Get the Gain Control for this Player. * * @return The GainControl object, or null if it has * not been set. */ public GainControl getGainControl() { int currentState = getState(); if(currentState == Unrealized || currentState == Realizing) { throw new NotRealizedError( "Cannot get gain control on an Unrealized Player"); } return gainControl; } /** * Set the visual Component for this AbstractPlayer. If the * AbstractPlayer does not support video media, this method * should return null. * * @param c * A java.awt.Component on which the media is * rendered. */ protected void setVisualComponent(Component c) { visualComponent = c; } /** * Get the visual Component for this Player. * * @return The visual Component, or null if it has * not been set. */ public Component getVisualComponent() { int currentState = getState(); if(currentState == Unrealized || currentState == Realizing) { throw new NotRealizedError( "Cannot get visual Component on an Unrealized Player"); } return visualComponent; } /** * Set the control panal Component for this AbstractPlayer. * * @param c * A java.awt.Component providing control over * this AbstractPlayer's media. */ protected void setControlPanelComponent(Component c) { controlPanelComponent = c; } /** * Get the control panel Component for this Player. * * @return The control panel Component, or null if * it has not been set. */ public Component getControlPanelComponent() { int currentState = getState(); if(currentState == Unrealized || currentState == Realizing) { throw new NotRealizedError( "Cannot get control panel Component on an Unrealized Player"); } return controlPanelComponent; } //////////////////////////////////////////////////////////// // // javax.media.MediaHandler methods // //////////////////////////////////////////////////////////// /** * Called by javax.media.Manager. This is the litmus test * that tells whether this Player can support the given * DataSource. If it can't, this method should throw a * IncompatibleSourceException. Our only requirement here is * that the DataSource has not already been set. Subclasses * may wish to override this method to extend the acceptance * criteria. * * @param source * The DataSource to test * * @exception IncompatibleSourceException * Thrown if the DataSource has already been set * on this MediaHandler, or if the DataSource is * not a PullDataSource */ public void setSource(DataSource source) throws IncompatibleSourceException { // Make sure the DataSource has only been set once if( this.source != null ) { throw new IncompatibleSourceException( "Datasource already set in MediaHandler " + getClass().getName() ); } this.source = source; } /** * Convenience method to get the DataSource for the Player. */ public DataSource getSource() { return source; } //////////////////////////////////////////////////////////// // // javax.media.ControllerListener methods // //////////////////////////////////////////////////////////// /** * Used to monitor events posted by this Player's managed * Controllers. By keeping track of the actions of each * Controller, the Player can synchronize the state * transtitions of multiple Controllers. * <p> * This method is final because the controller-management * functionality of the AbstractPlayer will not work if it is * overridden. * * @param e * The ControllerEvent posted by one of the * managed Controllers. */ public final void controllerUpdate(ControllerEvent e) { synchronized(controllers) { if( e instanceof TransitionEvent ) { controllers.notifyAll(); } else if( e instanceof ControllerErrorEvent ) { setControllerError((ControllerErrorEvent)e); controllers.notifyAll(); } } } //////////////////////////////////////////////////////////// // // ejmf.toolkit.media.content.AbstractController methods // //////////////////////////////////////////////////////////// /** * Realize player and all of its managed Controllers. * Subclasses should override doPlayerRealize() to do the * actual work to transition the Controller. * <p> * This method should not be called directly. Instead, call * realize(). */ public final boolean doRealize() { try { // Initialte the data transfer source.start(); } catch(IOException e) { postEvent( new ResourceUnavailableEvent(this, "Could not start DataSource") ); return false; } // No multi-Controller management is needed here because // all Controllers are guaranteed to be Realized when // they are added to this Player. Furthermore, the // Player itself must be realized before any Controllers // are added. if(! doPlayerRealize() ) { return false; } // Now that the Player is realized, getDuration() may // be more accurate. updateDuration(); return true; } /** * Prefetch player and all of its managed Controllers. * Subclasses should override doPlayerPrefetch() to do the * actual work to transition the Controller. * <p> * This method should not be called directly. Instead, call * prefetch(). */ public final boolean doPrefetch() { // Synchronize on the controllers Vector so that // Controllers cannot be added or deleted while we are // transitioning them. resetControllerError(); // Prefetch each managed Controller for(int i = 0; i < controllers.size(); i++) { Controller c = (Controller)controllers.elementAt(i); c.prefetch(); } // Prefetch this Player. If it fails, then assume a // ControllerErrorEvent was posted and return false. if(! doPlayerPrefetch() ) { return false; } // Now wait for our all of our managed Controllers to // complete the state transition or post an error. // controllerUpdate() will catch such events and // notify us. synchronized(controllers) { while( controllerError == null && ! isStateReached(Prefetched) ) { try { controllers.wait(); } catch(InterruptedException e) {} } } if( controllerError != null ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -