diff --git a/src/main/java/bdv/viewer/ViewerPanel.java b/src/main/java/bdv/viewer/ViewerPanel.java
index 444d4adfb16b6da95aab374d7e56fcda5a334e8a..80cca1688e812848bcc25ef2bcde7d6339d57dce 100644
--- a/src/main/java/bdv/viewer/ViewerPanel.java
+++ b/src/main/java/bdv/viewer/ViewerPanel.java
@@ -45,6 +45,7 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
+import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
@@ -72,6 +73,7 @@ import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
+import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -170,7 +172,7 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
*/
protected final InteractiveDisplayCanvasComponent< AffineTransform3D > display;
- protected final JSlider sliderTime;
+ protected final TimeSlider sliderTime;
/**
* A {@link ThreadGroup} for (only) the threads used by this
@@ -427,10 +429,10 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
sliderPanel.add( timeKeyframePanel );
timeKeyframePanel.setLayout( new BoxLayout( timeKeyframePanel, BoxLayout.Y_AXIS ) );
- sliderTime = new JSlider( 0, numTimepoints - 1, 0 );
-// sliderTime.setMinimumSize( new Dimension( 36, 26 ) );
-// sliderTime.setMaximumSize( new Dimension( 32767, 26 ) );
- sliderTime.setSnapToTicks( true );
+
+ sliderTime = new DefaultTimeSlider();
+ sliderTime.updateNumTimepoints( 0, numTimepoints );
+ sliderTime.addTimePointListener( this::setTimepoint );
timeKeyframePanel.add( sliderTime );
@@ -439,16 +441,6 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
keyframePanel.setPreferredSize( new Dimension( 36, 26 ) );
timeKeyframePanel.add( keyframePanel );
- sliderTime.addChangeListener( new ChangeListener()
- {
- @Override
- public void stateChanged( final ChangeEvent e )
- {
- if ( e.getSource().equals( sliderTime ) )
- setTimepoint( sliderTime.getValue() );
- }
- } );
-
add( display, BorderLayout.CENTER );
if ( numTimepoints > 1 )
add( sliderPanel, BorderLayout.SOUTH );
@@ -886,12 +878,10 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
*/
public synchronized void setTimepoint( final int timepoint )
{
- if ( state.getCurrentTimepoint() != timepoint )
+ if ( state.getCurrentTimepoint() != timepoint && timepoint >= 0 && timepoint < state.getNumTimepoints() )
{
state.setCurrentTimepoint( timepoint );
- sliderTime.setValue( timepoint );
- for ( final TimePointListener l : timePointListeners )
- l.timePointChanged( timepoint );
+ sliderTime.setTimepoint( timepoint );
requestRepaint();
}
}
@@ -902,7 +892,7 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
public synchronized void nextTimePoint()
{
if ( state.getNumTimepoints() > 1 )
- sliderTime.setValue( sliderTime.getValue() + 1 );
+ setTimepoint( state.getCurrentTimepoint() + 1 );
}
/**
@@ -911,7 +901,7 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
public synchronized void previousTimePoint()
{
if ( state.getNumTimepoints() > 1 )
- sliderTime.setValue( sliderTime.getValue() - 1 );
+ setTimepoint( state.getCurrentTimepoint() - 1 );
}
/**
@@ -952,7 +942,7 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
for ( final TimePointListener l : timePointListeners )
l.timePointChanged( timepoint );
}
- sliderTime.setModel( new DefaultBoundedRangeModel( state.getCurrentTimepoint(), 0, 0, numTimepoints - 1 ) );
+ sliderTime.updateNumTimepoints( state.getCurrentTimepoint(), numTimepoints );
revalidate();
requestRepaint();
}
@@ -1348,4 +1338,78 @@ public class ViewerPanel extends JPanel implements OverlayRenderer, TransformLis
return t;
}
}
+
+ // TODO: move to separate file, add to ViewerOptions
+ public static abstract class TimeSlider extends JPanel
+ {
+ public TimeSlider( final LayoutManager layout, final boolean isDoubleBuffered )
+ {
+ super( layout, isDoubleBuffered );
+ }
+
+ public TimeSlider( final LayoutManager layout )
+ {
+ super( layout );
+ }
+
+ public TimeSlider( final boolean isDoubleBuffered )
+ {
+ super( isDoubleBuffered );
+ }
+
+ public TimeSlider()
+ {
+ super();
+ }
+
+ public abstract void updateNumTimepoints( int currentTimepoint, int numTimepoints );
+
+ public abstract void setTimepoint( int timepoint );
+
+ public abstract void addTimePointListener( TimePointListener listener );
+ }
+
+ // TODO: move to separate file
+ public static class DefaultTimeSlider extends TimeSlider
+ {
+ private final CopyOnWriteArrayList< TimePointListener > listeners;
+
+ private final JSlider slider;
+
+ public DefaultTimeSlider()
+ {
+ super( new BorderLayout() );
+ listeners = new CopyOnWriteArrayList<>();
+ slider = new JSlider( SwingConstants.HORIZONTAL );
+ slider.addChangeListener( new ChangeListener()
+ {
+ @Override
+ public void stateChanged( final ChangeEvent e )
+ {
+ for ( final TimePointListener l : listeners )
+ l.timePointChanged( slider.getValue() );
+ }
+ } );
+ slider.setSnapToTicks( true );
+ add( slider, BorderLayout.CENTER );
+ }
+
+ @Override
+ public void updateNumTimepoints( final int currentTimepoint, final int numTimepoints )
+ {
+ slider.setModel( new DefaultBoundedRangeModel( currentTimepoint, 0, 0, numTimepoints - 1 ) );
+ }
+
+ @Override
+ public void setTimepoint( final int timepoint )
+ {
+ slider.setValue( timepoint );
+ }
+
+ @Override
+ public synchronized void addTimePointListener( final TimePointListener listener )
+ {
+ listeners.add( listener );
+ }
+ }
}