📄 standardprogresscontrol.java
字号:
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. */ 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. */ protected EventListener createControlListener() { return new ChangeListener() { public void stateChanged(ChangeEvent e) { ProgressBar s = (ProgressBar) e.getSource(); int value = s.getValue(); long mediaNanos = (long)((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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -