Package net.sf.fmj.ejmf.toolkit.gui.controls

Source Code of net.sf.fmj.ejmf.toolkit.gui.controls.StandardProgressControl$EnableComponentThread

package net.sf.fmj.ejmf.toolkit.gui.controls;

import java.awt.Component;
import java.util.EventListener;

import javax.media.Controller;
import javax.media.ControllerErrorEvent;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.Duration;
import javax.media.MediaTimeSetEvent;
import javax.media.PrefetchCompleteEvent;
import javax.media.RestartingEvent;
import javax.media.StartEvent;
import javax.media.StopEvent;
import javax.media.Time;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.sf.fmj.ejmf.toolkit.util.SourcedTimer;
import net.sf.fmj.ejmf.toolkit.util.SourcedTimerEvent;
import net.sf.fmj.ejmf.toolkit.util.SourcedTimerListener;
import net.sf.fmj.ejmf.toolkit.util.TimeSource;

/**
* Progress slider for StandardControlPanel.
* This control maintains an internal time which
* 'ticks'. At each tick, StandardProgressControl maps
* media time into a slider value and updates the progress slider.
* <p>
* The timer is provided by ejmf.toolkit.util.SourcedTimer.
* StandardProgressControl receieves 'ticks' by virtue of
* being a SourcedTimerListener.
*/

public class StandardProgressControl extends ChangeListenerControl
      implements ControllerListener,
           TimeSource,
           SourcedTimerListener {

    // Once prefetched, set to false.
    private boolean    firstPrefetch = true;

    private SourcedTimer        controlTimer;
  
    // Duration of Controller.
    private long    duration;
    // Timer will fire every TIMER_TICK milliseconds
    final private static int TIMER_TICK = 250;

    public StandardProgressControl(Skin skin, Controller controller) {
  this(skin);
  setController(controller);
    }

    public StandardProgressControl(Skin skin) {
      super(skin);
    }

  /** 
  * Create ProgressSlider
  * @see net.sf.fmj.ejmf.toolkit.gui.controls.skins.ejmf.ProgressSlider
  */
    @Override
    protected Component createControlComponent(Skin skin) {
  return skin.createProgressSlider();
    }

  /**
  * Augments setController by adding itself as
  * as ControllerListener on the Controller and forcing
  * operational state to false. Availability of progress 
  * bar is determined only after Controller is prefetch
  * and duration is determinate.
  */
    @Override
  protected void setControllerHook(Controller controller) {
  setOperational(false);
  getController().addControllerListener(this);
 
  if (controller.getState() >= Controller.Prefetched)
  {  init()// KAL: added to handle case where controller starts before our controllerUpdate handler gets registered.
  }
    }

    private void init() {
  Time d = getController().getDuration();
  // If duration is unknown or unbounded, slider
        // will not be operational.
  boolean flg =
          d != Duration.DURATION_UNBOUNDED &&
           d != Duration.DURATION_UNKNOWN;

  // We have some know duration, is it zero?
  if (flg) {
      duration = d.getNanoseconds();
      flg = (duration != 0L);
  }
  setOperational(flg);
  // Duration is known and non-zero, all is well...
  if (flg) {
      // Setup timer
      controlTimer = new SourcedTimer(this, TIMER_TICK);
        controlTimer.addSourcedTimerListener(this);

      Time mTime = getController().getMediaTime();
      long mediaTime = mTime.getNanoseconds();

      setValue(mediaTime);
     
      if (getController().getState() == Controller.Started)
        controlTimer.start()// this handles the case where it is already started before we get here, in which case controllerUpdate will never get called with the initial state
     
        }
    }

  /**
  * Create ChangeListener. Tracks user movement 
  * of progress slider and update media time   
  * accordingly.
  */
    @Override
  protected EventListener createControlListener() {
  return new ChangeListener() {
       public void stateChanged(ChangeEvent e) {
             ProgressBar s = (ProgressBar) e.getSource();
             int value = s.getValue();
             long mediaNanos = ((value * duration) /
                      (s.getMaximum() - s.getMinimum()));

             // Intel JMF: Setting media time will update video frame
             // Sun JMF: Video does not re-render until controller is restarted
     Controller controller = getController();
    int priorState = controller.getState();
    if (priorState == Controller.Started) {
        controller.stop();
          }

             controller.setMediaTime(new Time(mediaNanos));

    if (priorState == Controller.Started) {
        Time now = controller.getTimeBase().getTime();
        controller.syncStart(now);
    }
           }
        };
    }

    /**
      * Position slider based on mediaTime
      */
    public void setValue(long mediaTime) {
        ProgressBar bar;
  if (!isOperational()) {
      return;
        }
  bar = (ProgressBar) getControlComponent();
   long diff = bar.getMaximum() - bar.getMinimum();
   // Translate time to slider value
   int value = (int) ((diff * mediaTime) / duration);

   SwingUtilities.invokeLater(
    new SetProgressSliderValueThread(bar, value));
    }


  /** 
  * If the progress slider is operational, the
  * controllerUpdate method starts and stops its
  * time based on Start- and StopEvents from the Controller.
  * If response to MediaTimeSetEvent, the value of the
  * progress slider is explicitly set.
  * <p>
  * The controllerUpdate method is also responsible for
  * setting the operational state of the Control based 
  * on duration value. This is done in response to first
  * PrefetchCompleteEvent.
  */
    public void controllerUpdate(ControllerEvent event) {
    if (isOperational()) {
            if (event instanceof StartEvent ||
                event instanceof RestartingEvent) {
       controlTimer.start();
             } else if (event instanceof StopEvent ||
            event instanceof ControllerErrorEvent) {
                   controlTimer.stop();
             } else if (event instanceof MediaTimeSetEvent) {
    // This catches any direct setting of media time 
    // by application. Additionally, it catches
    // setMediaTime(0) by StandardStopControl.
       setValue(getTime());
       }
    } else {
      if ( firstPrefetch && event instanceof PrefetchCompleteEvent) {
    firstPrefetch = false;
          init();
    //SwingUtilities.invokeLater(new EnableComponentThread());
      }
        }
    }
  
    class EnableComponentThread implements Runnable {
  public void run() {
      getControlComponent().setEnabled(isOperational());
  }
    }
   
       /**
    * This method implements the SourcedTimerListener interface.
    * Each timer tick causes slider thumbnail to move if a ProgressBar
    * was built for this control panel.
    *
    * @see            net.sf.fmj.ejmf.toolkit.util.SourcedTimer
    */
    public void timerUpdate(SourcedTimerEvent e) {
       // Since we are also the TimeSource, we can get
       // directly from StandardControls instance.
       // Normally, one would call e.getTime().

  setValue(getTime());
    }

    class SetProgressSliderValueThread implements Runnable {
        int     value;
  ProgressBar  bar;

        public SetProgressSliderValueThread(ProgressBar bar, int value) {
      this.value = value;
      this.bar = bar;
        }

        public void run() {
      bar.setValue(value);
  }
    }

  // For TimeSource interface
  /**
  * As part of TimeSource interface, getTime returns
  * the current media time in nanoseconds. 
  */
    public long getTime() {
  return getController().getMediaNanoseconds();
    }

  /**
  * This method is used as a divisor to  convert
  * getTime to seconds.
  */
    public long getConversionDivisor() {
         return TimeSource.NANOS_PER_SEC;
    }
}
TOP

Related Classes of net.sf.fmj.ejmf.toolkit.gui.controls.StandardProgressControl$EnableComponentThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
', 'auto'); ga('send', 'pageview');