Made 2 frame gifs work (#1852)

* Improved animation player

* Cleanup

* Acquiesced to Sean's frivolous complaints

* More complaints

---------

Co-authored-by: plherrin <plherrin@dickinson.ndc.nasa.gov>
This commit is contained in:
Pherring04
2025-03-11 11:04:00 -05:00
committed by GitHub
parent fd6df3cf33
commit 9ae0b35110
3 changed files with 1040 additions and 897 deletions

File diff suppressed because it is too large Load Diff

View File

@ -30,160 +30,214 @@ import trick.common.ui.UIUtils;
* *
* @since Trick 10 * @since Trick 10
*/ */
public class AnimationPlayer extends JPanel { public class AnimationPlayer extends JPanel
{
//========================================
// Public data //========================================
//======================================== // Public data
//========================================
//========================================
// Protected data //========================================
//======================================== // Protected data
//========================================
//========================================
// Private Data //========================================
//======================================== // Private Data
private boolean paused; //========================================
private boolean finished; private boolean paused;
private String animationFile; private boolean finished;
private JLabel animationLabel; private String animationFile;
private PlayAnimationTask animationTask; private int animationTimeStep;
private JLabel animationLabel;
private PlayAnimationTask animationTask;
private static final long serialVersionUID = 3705588596523798631L;
//======================================== private static final long serialVersionUID = 3705588596523798631L;
// Constructors
//======================================== //========================================
/** // Constructors
* Default constructor. //========================================
/**
* Default constructor.
* @param fileName name of file * @param fileName name of file
*/ */
public AnimationPlayer(String fileName) { public AnimationPlayer(String fileName)
animationFile = fileName; {
buildGUI(); animationFile = fileName;
if (animationTask == null) { animationTimeStep = 150;
animationTask = new PlayAnimationTask(); buildGUI();
} if (animationTask == null)
} {
animationTask = new PlayAnimationTask();
//======================================== }
// Set/Get methods }
//========================================
/**
* Constructor with paramaterized time step.
//======================================== * @param fileName name of file
// Methods * @param timeStep animation time step
//======================================== */
/** public AnimationPlayer(String fileName, int timeStep)
* Starts the animation task. This method has to be called {
* in order for the animation to be played. animationFile = fileName;
*/ animationTimeStep = timeStep;
public void start() { buildGUI();
if (animationTask == null) { if (animationTask == null)
animationTask = new PlayAnimationTask(); {
} animationTask = new PlayAnimationTask();
animationTask.execute(); }
} }
/** //========================================
* Pauses the animation play. // Set/Get methods
*/ //========================================
public void pause() {
paused = true;
} //========================================
// Methods
/** //========================================
* Resumes the animation play. /**
*/ * Starts the animation task. This method has to be called
public void resume() { * in order for the animation to be played.
paused = false; */
} public void start()
{
/** if (animationTask == null)
* Stops the animation play. {
*/ animationTask = new PlayAnimationTask();
public void stop() { }
finished = true; animationTask.execute();
} }
/** /**
* Builds the player GUI. * Pauses the animation play.
*/ */
private void buildGUI() { public void pause()
{
paused = true;
}
/**
* Resumes the animation play.
*/
public void resume()
{
paused = false;
}
/**
* Stops the animation play.
*/
public void stop()
{
finished = true;
}
/**
* Builds the player GUI.
*/
private void buildGUI()
{
setLayout(new BorderLayout()); setLayout(new BorderLayout());
animationLabel = new JLabel(); animationLabel = new JLabel();
ImageIcon icon = UIUtils.createImageIcon(animationFile); ImageIcon icon = UIUtils.createImageIcon(animationFile);
// set proper initial size for the label // set proper initial size for the label
if (icon != null) { if (icon != null)
animationLabel.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight())); {
animationLabel.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
} }
add(animationLabel, BorderLayout.CENTER); add(animationLabel, BorderLayout.CENTER);
} }
//======================================== //========================================
// Inner Class // Inner Class
//======================================== //========================================
/** /**
* Inner class for playing an animation image. * Inner class for playing an animation image.
*/ */
private class PlayAnimationTask extends SwingWorker<Void, Void> { private class PlayAnimationTask extends SwingWorker<Void, Void>
ImageInputStream stream; {
ImageInputStream stream;
@Override
public Void doInBackground() { @Override
public Void doInBackground()
if (animationFile == null) { {
return null;
} if (animationFile == null)
{
try { return null;
InputStream input = UIUtils.getInputStreamForFile(animationFile);
stream = ImageIO.createImageInputStream(input);
Iterator readers = ImageIO.getImageReaders(stream);
if (!readers.hasNext()) {
throw new RuntimeException("no image reader found");
}
ImageReader reader = (ImageReader) readers.next();
reader.setInput(stream); // don't omit this line!
int n = reader.getNumImages(true); // don't use false!
for (int i = 0; i < n; i++) {
BufferedImage image = reader.read(i);
Image img = image;
animationLabel.setIcon(new ImageIcon(img));
do {
try {
Thread.sleep(150);
} catch (InterruptedException ie) {
}
} while (paused);
if (finished) {
break;
} else {
// rewind
if (i == n-1) {
i = 0;
}
}
}
} catch (IOException ioe) {
} }
return null; try
} {
InputStream input = UIUtils.getInputStreamForFile(animationFile);
stream = ImageIO.createImageInputStream(input);
Iterator readers = ImageIO.getImageReaders(stream);
if (!readers.hasNext())
{
throw new RuntimeException("no image reader found");
}
ImageReader reader = (ImageReader) readers.next();
reader.setInput(stream); // don't omit this line!
int n = reader.getNumImages(true); // don't use false!
int i = 0;
while(i < n)
{
Image img = reader.read(i);
animationLabel.setIcon(new ImageIcon(img));
do
{
try
{
Thread.sleep(animationTimeStep);
}
catch (InterruptedException ie)
{
}
} while (paused);
if (finished)
{
break;
}
else
{
// rewind
if (i >= n-1)
{
i = 0;
}
else
{
++i;
}
}
}
}
catch (IOException ioe)
{
}
@Override return null;
public void done() { }
if (stream != null) {
try { @Override
public void done()
{
if (stream != null)
{
try
{
stream.close(); stream.close();
} catch (IOException ioe) { } }
catch (IOException ioe)
{
}
} }
} }
} }
} }

View File

@ -927,7 +927,19 @@ public class SimControlApplication extends TrickApplication implements PropertyC
trickLogoName = UIUtils.getTrickLogo(); trickLogoName = UIUtils.getTrickLogo();
} }
logoImagePanel = new AnimationPlayer(trickLogoName); if (UIUtils.getTrickLogoStep() != null) {
try {
int timeStep = Integer.parseInt(UIUtils.getTrickLogoStep());
logoImagePanel = new AnimationPlayer(trickLogoName, timeStep);
}
catch (NumberFormatException e) {
logoImagePanel = new AnimationPlayer(trickLogoName);
}
}
else {
logoImagePanel = new AnimationPlayer(trickLogoName);
}
logoImagePanel.setToolTipText("Trick Version " + UIUtils.getTrickVersion()); logoImagePanel.setToolTipText("Trick Version " + UIUtils.getTrickVersion());
JSplitPane topPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, litePanel, logoImagePanel); JSplitPane topPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, litePanel, logoImagePanel);