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

View File

@ -61,7 +61,8 @@ import trick.common.utils.TrickColors;
* @author Hong Chen * @author Hong Chen
* @since Trick 7 * @since Trick 7
*/ */
public class UIUtils { public class UIUtils
{
//======================================== //========================================
// Public data // Public data
@ -86,18 +87,6 @@ public class UIUtils {
//======================================== //========================================
//========================================
// Private Data
//========================================
// for env variables
private final static int HOME = 0;
private final static int TRICK_HOME = 1;
private final static int TRICK_USER_HOME = 2;
private final static int TRICK_VER = 3;
private final static int TRICK_HOST_CPU = 4;
private final static int TRICK_LOGO = 5;
//======================================== //========================================
// Constructors // Constructors
//======================================== //========================================
@ -111,8 +100,9 @@ public class UIUtils {
* *
* @return The value of HOME. * @return The value of HOME.
*/ */
public static String getUserHome() { public static String getUserHome()
return getTrickEnv(HOME); {
return System.getenv("HOME");
} }
/** /**
@ -121,10 +111,12 @@ public class UIUtils {
* @return The value of TRICK_USER_HOME. If it is not defined, return * @return The value of TRICK_USER_HOME. If it is not defined, return
* the value of HOME. * the value of HOME.
*/ */
public static String getTrickUserHome() { public static String getTrickUserHome()
String ret = getTrickEnv(TRICK_USER_HOME); {
if (ret == null) { String ret = System.getenv("TRICK_USER_HOME");
ret = getTrickEnv(HOME); if (ret == null)
{
ret = getUserHome();
} }
return ret; return ret;
} }
@ -135,10 +127,12 @@ public class UIUtils {
* @return The value of TRICK_HOME. If it is not defined, return * @return The value of TRICK_HOME. If it is not defined, return
* the value of HOME. * the value of HOME.
*/ */
public static String getTrickHome() { public static String getTrickHome()
String ret = getTrickEnv(TRICK_HOME); {
if (ret == null) { String ret = System.getenv("TRICK_HOME");
ret = getTrickEnv(HOME); if (ret == null)
{
ret = getUserHome();
} }
return ret; return ret;
} }
@ -149,10 +143,12 @@ public class UIUtils {
* @return The text of $TRICK_HOME/bin. If it is not defined, return * @return The text of $TRICK_HOME/bin. If it is not defined, return
* the text of $HOME/bin. * the text of $HOME/bin.
*/ */
public static String getTrickBin() { public static String getTrickBin()
String ret = getTrickEnv(TRICK_HOME) ; {
if (ret == null) { String ret = System.getenv("TRICK_BIN");
ret = getTrickEnv(HOME); if (ret == null)
{
ret = getUserHome();
} }
ret = ret + File.separator + "bin"; ret = ret + File.separator + "bin";
return ret; return ret;
@ -163,8 +159,9 @@ public class UIUtils {
* *
* @return The value of TRICK_VER. * @return The value of TRICK_VER.
*/ */
public static String getTrickVersion() { public static String getTrickVersion()
return getTrickEnv(TRICK_VER); {
return System.getenv("TRICK_VER");
} }
/** /**
@ -172,8 +169,9 @@ public class UIUtils {
* *
* @return The value of TRICK_HOST_CPU. * @return The value of TRICK_HOST_CPU.
*/ */
public static String getTrickHostCPU() { public static String getTrickHostCPU()
return getTrickEnv(TRICK_HOST_CPU); {
return System.getenv("TRICK_HOST_CPU");
} }
/** /**
@ -181,47 +179,24 @@ public class UIUtils {
* *
* @return The value of TRICK_LOGO. * @return The value of TRICK_LOGO.
*/ */
public static String getTrickLogo() { public static String getTrickLogo()
return getTrickEnv(TRICK_LOGO); {
return System.getenv("TRICK_LOGO");
}
/**
* Gets the value of TRICK_LOGO_STEP environment variable.
*
* @return The value of TRICK_LOGO_STEP.
*/
public static String getTrickLogoStep()
{
return System.getenv("TRICK_LOGO_STEP");
} }
//======================================== //========================================
// Methods // Methods
//======================================== //========================================
/**
* Helper method for getting Trick environment variable value.
*
* @param type The type of the variable.
*
* @return The environment variable value.
*/
private static String getTrickEnv(int type) {
String value = null;
switch (type) {
case TRICK_HOME:
value = System.getenv("TRICK_HOME");
break;
case TRICK_USER_HOME:
value = System.getenv("TRICK_USER_HOME");
break;
case TRICK_VER:
value = System.getenv("TRICK_VER");
break;
case HOME:
value = System.getenv("HOME");
break;
case TRICK_HOST_CPU:
value = System.getenv("TRICK_HOST_CPU");
break;
case TRICK_LOGO:
value = System.getenv("TRICK_LOGO");
break;
default:
break;
}
return value;
}
/** /**
* Gets html hex for a {@link Color}. * Gets html hex for a {@link Color}.
@ -231,9 +206,11 @@ public class UIUtils {
* @return "#" followed by exactly 6 hex digits. * @return "#" followed by exactly 6 hex digits.
* *
*/ */
public final static String colorToHTMLHex(Color c) { public final static String colorToHTMLHex(Color c)
{
String s = Integer.toHexString( c.getRGB() & 0xffffff ); String s = Integer.toHexString( c.getRGB() & 0xffffff );
if ( s.length() < 6 ) { // pad on left with zeros if ( s.length() < 6 )
{ // pad on left with zeros
s = "000000".substring( 0, 6 - s.length() ) + s; s = "000000".substring( 0, 6 - s.length() ) + s;
} }
return '#' + s; return '#' + s;
@ -246,14 +223,19 @@ public class UIUtils {
* *
* @return An instance of {@link Color}. * @return An instance of {@link Color}.
*/ */
public final static Color getColorFromHTMLHex(String colorStrOrCode) { public final static Color getColorFromHTMLHex(String colorStrOrCode)
if (colorStrOrCode == null || "".equals(colorStrOrCode)) { {
if (colorStrOrCode == null || "".equals(colorStrOrCode))
{
return null; return null;
} }
Color c = null; Color c = null;
try { try
{
c = Color.decode(colorStrOrCode); c = Color.decode(colorStrOrCode);
} catch (NumberFormatException nfe) { }
catch (NumberFormatException nfe)
{
c = TrickColors.getColor(colorStrOrCode); c = TrickColors.getColor(colorStrOrCode);
} }
return c; return c;
@ -265,9 +247,12 @@ public class UIUtils {
* @param obj object to test for * @param obj object to test for
* @return true or false * @return true or false
*/ */
public static boolean comboBoxContains(DefaultComboBoxModel model, Object obj) { public static boolean comboBoxContains(DefaultComboBoxModel model, Object obj)
for (int i = 0; i < model.getSize(); i++) { {
if (obj.equals(model.getElementAt(i))) { for (int i = 0; i < model.getSize(); i++)
{
if (obj.equals(model.getElementAt(i)))
{
return true; return true;
} }
} }
@ -281,9 +266,11 @@ public class UIUtils {
* *
* @return <code>true</code> if right button was pressed, <code>false</code> otherwise. * @return <code>true</code> if right button was pressed, <code>false</code> otherwise.
*/ */
public static boolean isRightMouseClick(MouseEvent e) { public static boolean isRightMouseClick(MouseEvent e)
{
boolean rval = false; boolean rval = false;
if(e.getButton() == 3) { if(e.getButton() == 3)
{
rval = true; rval = true;
} }
@ -297,10 +284,12 @@ public class UIUtils {
* *
* @return <code>true</code> if is double-clicking, <code>false</code> otherwise. * @return <code>true</code> if is double-clicking, <code>false</code> otherwise.
*/ */
public static boolean isDoubleClick(MouseEvent e) { public static boolean isDoubleClick(MouseEvent e)
{
boolean rval = false; boolean rval = false;
if (e.getClickCount() == 2) { if (e.getClickCount() == 2)
{
rval = true; rval = true;
} }
@ -314,7 +303,8 @@ public class UIUtils {
* *
* @return <code>true</code> if the specified directory has log files, <code>false</code> otherwise. * @return <code>true</code> if the specified directory has log files, <code>false</code> otherwise.
*/ */
public static boolean hasLogFile(File dir) { public static boolean hasLogFile(File dir)
{
return hasSpecifiedFile(dir, TrickFileFilter.LOG); return hasSpecifiedFile(dir, TrickFileFilter.LOG);
} }
@ -325,7 +315,8 @@ public class UIUtils {
* *
* @return <code>true</code> if the specified directory has .header files, <code>false</code> otherwise. * @return <code>true</code> if the specified directory has .header files, <code>false</code> otherwise.
*/ */
public static boolean hasHeaderFile(File dir) { public static boolean hasHeaderFile(File dir)
{
return hasSpecifiedFile(dir, TrickFileFilter.HEADER); return hasSpecifiedFile(dir, TrickFileFilter.HEADER);
} }
@ -336,7 +327,8 @@ public class UIUtils {
* *
* @return <code>true</code> if the specified directory has .trk files, <code>false</code> otherwise. * @return <code>true</code> if the specified directory has .trk files, <code>false</code> otherwise.
*/ */
public static boolean hasTRKFile(File dir) { public static boolean hasTRKFile(File dir)
{
return hasSpecifiedFile(dir, TrickFileFilter.TRK); return hasSpecifiedFile(dir, TrickFileFilter.TRK);
} }
@ -347,7 +339,8 @@ public class UIUtils {
* *
* @return <code>true</code> if the specified directory has .csv files, <code>false</code> otherwise. * @return <code>true</code> if the specified directory has .csv files, <code>false</code> otherwise.
*/ */
public static boolean hasCSVFile(File dir) { public static boolean hasCSVFile(File dir)
{
return hasSpecifiedFile(dir, TrickFileFilter.CSV); return hasSpecifiedFile(dir, TrickFileFilter.CSV);
} }
@ -359,9 +352,11 @@ public class UIUtils {
* *
* @return <code>true</code> if the specified directory has specified files, <code>false</code> otherwise. * @return <code>true</code> if the specified directory has specified files, <code>false</code> otherwise.
*/ */
private static boolean hasSpecifiedFile(File dir, int type) { private static boolean hasSpecifiedFile(File dir, int type)
{
File[] tmp = dir.listFiles(new TrickFileFilter(type)); File[] tmp = dir.listFiles(new TrickFileFilter(type));
if (tmp == null || tmp.length < 1) { if (tmp == null || tmp.length < 1)
{
return false; return false;
} }
return true; return true;
@ -373,10 +368,12 @@ public class UIUtils {
* @param file file object to use. * @param file file object to use.
* @return file name * @return file name
*/ */
public static String getFileNameWithoutExtension(File file) { public static String getFileNameWithoutExtension(File file)
{
String fileName = file.getName(); String fileName = file.getName();
int dotLoc = fileName.lastIndexOf('.'); int dotLoc = fileName.lastIndexOf('.');
if (dotLoc > 0 && dotLoc <= fileName.length() - 2) { if (dotLoc > 0 && dotLoc <= fileName.length() - 2)
{
return fileName.substring(0, dotLoc); return fileName.substring(0, dotLoc);
} }
return fileName; return fileName;
@ -391,8 +388,10 @@ public class UIUtils {
* @return An array of abstract pathnames denoting the files, <code>null</code> * @return An array of abstract pathnames denoting the files, <code>null</code>
* if the specified dir is null or is not a directory. * if the specified dir is null or is not a directory.
*/ */
public static File[] getListFiles(File dir, int type) { public static File[] getListFiles(File dir, int type)
if (dir != null && dir.isDirectory()) { {
if (dir != null && dir.isDirectory())
{
return dir.listFiles(new TrickFileFilter(type)); return dir.listFiles(new TrickFileFilter(type));
} }
return null; return null;
@ -405,13 +404,15 @@ public class UIUtils {
* @return An instance of {@link JXLabel} with its icon set to trick small icon and * @return An instance of {@link JXLabel} with its icon set to trick small icon and
* tool tip set to the trick version. * tool tip set to the trick version.
*/ */
public static JXLabel getSmallTrickIconLabel() { public static JXLabel getSmallTrickIconLabel()
{
JXLabel label = new JXLabel(); JXLabel label = new JXLabel();
String desc = "Trick Version " + getTrickVersion(); String desc = "Trick Version " + getTrickVersion();
label.setToolTipText(desc); label.setToolTipText(desc);
ImageIcon smallIcon = createImageIcon("trick_small.gif"); ImageIcon smallIcon = createImageIcon("trick_small.gif");
if (smallIcon != null) { if (smallIcon != null)
{
smallIcon.setDescription(desc); smallIcon.setDescription(desc);
label.setIcon(smallIcon); label.setIcon(smallIcon);
} }
@ -428,11 +429,14 @@ public class UIUtils {
* *
* @return - true if found, false otherwise. * @return - true if found, false otherwise.
*/ */
public static boolean searchWithWildcard(String inputStr, String searchStr) { public static boolean searchWithWildcard(String inputStr, String searchStr)
{
StringBuffer patternBuf = new StringBuffer(); StringBuffer patternBuf = new StringBuffer();
if (searchStr.contains("*")) { if (searchStr.contains("*"))
{
String[] parts = searchStr.split("\\*"); String[] parts = searchStr.split("\\*");
for (String part : parts) { for (String part : parts)
{
patternBuf.append(".*("); patternBuf.append(".*(");
patternBuf.append(part); patternBuf.append(part);
patternBuf.append(")"); patternBuf.append(")");
@ -442,7 +446,9 @@ public class UIUtils {
Pattern pattern = Pattern.compile(patternBuf.toString()); Pattern pattern = Pattern.compile(patternBuf.toString());
Matcher matcher = pattern.matcher(inputStr); Matcher matcher = pattern.matcher(inputStr);
return matcher.find(); return matcher.find();
} else { }
else
{
return (inputStr.contains(searchStr)); return (inputStr.contains(searchStr));
} }
} }
@ -457,13 +463,18 @@ public class UIUtils {
* *
* @return The selected directory. * @return The selected directory.
*/ */
public static File chooseDir(String chooserTitle, String dir, Component parent) { public static File chooseDir(String chooserTitle, String dir, Component parent)
{
JFileChooser chooser = new JFileChooser(); JFileChooser chooser = new JFileChooser();
if (dir == null) { if (dir == null)
{
chooser.setCurrentDirectory(new java.io.File(".")); chooser.setCurrentDirectory(new java.io.File("."));
} else { }
else
{
File file = new java.io.File(dir); File file = new java.io.File(dir);
if (!file.exists()) { if (!file.exists())
{
file = new java.io.File("."); file = new java.io.File(".");
} }
chooser.setCurrentDirectory(file); chooser.setCurrentDirectory(file);
@ -472,9 +483,12 @@ public class UIUtils {
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int chooserState = chooser.showDialog(parent, "Ok"); int chooserState = chooser.showDialog(parent, "Ok");
if (chooserState == JFileChooser.APPROVE_OPTION) { if (chooserState == JFileChooser.APPROVE_OPTION)
{
return chooser.getSelectedFile(); return chooser.getSelectedFile();
} else { }
else
{
return null; return null;
} }
} }
@ -489,48 +503,62 @@ public class UIUtils {
* *
* @return An instance of {@link File} if the selection is successful, <code>null</code> otherwise. * @return An instance of {@link File} if the selection is successful, <code>null</code> otherwise.
*/ */
public static File chooseOpenFile(String dir, String fileName, String fileNameExtension, Component parent) { public static File chooseOpenFile(String dir, String fileName, String fileNameExtension, Component parent)
{
JFileChooser chooser = new JFileChooser(); JFileChooser chooser = new JFileChooser();
File selectedFile = null; File selectedFile = null;
File fileDir = null; File fileDir = null;
// if dir is not specified or the dir doesn't exist, use the current directory // if dir is not specified or the dir doesn't exist, use the current directory
if (dir == null) { if (dir == null)
{
fileDir = new File("."); fileDir = new File(".");
} else { }
else
{
fileDir = new File(dir); fileDir = new File(dir);
} }
if (!fileDir.exists()) { if (!fileDir.exists())
{
fileDir = new File("."); fileDir = new File(".");
} }
chooser.setCurrentDirectory(fileDir); chooser.setCurrentDirectory(fileDir);
if (fileName != null) { if (fileName != null)
{
chooser.setSelectedFile(new java.io.File(fileName)); chooser.setSelectedFile(new java.io.File(fileName));
} }
if (fileNameExtension != null) { if (fileNameExtension != null)
{
chooser.setFileFilter(new FileNameExtensionFilter(fileNameExtension+" file", fileNameExtension)); chooser.setFileFilter(new FileNameExtensionFilter(fileNameExtension+" file", fileNameExtension));
} }
chooser.setDialogTitle("Open File"); chooser.setDialogTitle("Open File");
boolean isValid = true; boolean isValid = true;
do { do
{
int chooserState = chooser.showDialog(parent, "Ok"); int chooserState = chooser.showDialog(parent, "Ok");
if (chooserState == JFileChooser.APPROVE_OPTION) { if (chooserState == JFileChooser.APPROVE_OPTION)
{
selectedFile = chooser.getSelectedFile(); selectedFile = chooser.getSelectedFile();
if (!selectedFile.exists()) { if (!selectedFile.exists())
{
JOptionPane.showMessageDialog(parent, JOptionPane.showMessageDialog(parent,
selectedFile.getName()+" does not exist. Please choose another file!", selectedFile.getName()+" does not exist. Please choose another file!",
"File Not Found", "File Not Found",
JOptionPane.WARNING_MESSAGE); JOptionPane.WARNING_MESSAGE);
} else { }
else
{
isValid = false; isValid = false;
} }
} else { }
else
{
return null; return null;
} }
} while (isValid); } while (isValid);
@ -544,12 +572,16 @@ public class UIUtils {
* @param contents The text contents that need to be saved. * @param contents The text contents that need to be saved.
* @param file The file which the text will be saved to. * @param file The file which the text will be saved to.
*/ */
public static void saveTextFile(String contents, File file) { public static void saveTextFile(String contents, File file)
try { {
try
{
PrintWriter out = new PrintWriter(new FileWriter(file)); PrintWriter out = new PrintWriter(new FileWriter(file));
out.print(contents); out.print(contents);
out.close(); out.close();
} catch (IOException ioe) { }
catch (IOException ioe)
{
} }
} }
@ -564,7 +596,8 @@ public class UIUtils {
* *
* @return The specified the file, <code>null</code> if canceled. * @return The specified the file, <code>null</code> if canceled.
*/ */
public static File chooseSaveFile(String dir, String initialFile, String fileNameExtension, Component parent) { public static File chooseSaveFile(String dir, String initialFile, String fileNameExtension, Component parent)
{
JFileChooser chooser = new JFileChooser(); JFileChooser chooser = new JFileChooser();
File selectedFile = null; File selectedFile = null;
String selectedFileName = null; String selectedFileName = null;
@ -572,53 +605,69 @@ public class UIUtils {
File fileDir = null; File fileDir = null;
// if dir is not specified or the dir doesn't exist, use the current directory // if dir is not specified or the dir doesn't exist, use the current directory
if (dir == null) { if (dir == null)
{
fileDir = new File("."); fileDir = new File(".");
} else { }
else
{
fileDir = new File(dir); fileDir = new File(dir);
} }
if (!fileDir.exists()) { if (!fileDir.exists())
{
fileDir = new File("."); fileDir = new File(".");
} }
chooser.setCurrentDirectory(fileDir); chooser.setCurrentDirectory(fileDir);
if (initialFile != null) { if (initialFile != null)
{
chooser.setSelectedFile(new java.io.File(initialFile)); chooser.setSelectedFile(new java.io.File(initialFile));
} }
if (fileNameExtension != null) { if (fileNameExtension != null)
{
chooser.setFileFilter(new FileNameExtensionFilter(fileNameExtension + " file", fileNameExtension)); chooser.setFileFilter(new FileNameExtensionFilter(fileNameExtension + " file", fileNameExtension));
} }
chooser.setDialogTitle("Save File"); chooser.setDialogTitle("Save File");
boolean isValid = true; boolean isValid = true;
do { do
{
int chooserState = chooser.showDialog(parent, "Ok"); int chooserState = chooser.showDialog(parent, "Ok");
if (chooserState == JFileChooser.APPROVE_OPTION) { if (chooserState == JFileChooser.APPROVE_OPTION)
{
selectedFile = chooser.getSelectedFile(); selectedFile = chooser.getSelectedFile();
selectedFileName = selectedFile.getName(); selectedFileName = selectedFile.getName();
if (fileNameExtension != null) { if (fileNameExtension != null)
{
// 1.append the specified file extension if there is no extension. // 1.append the specified file extension if there is no extension.
// 2.append the desired extension if there is an extension which is not the same as specified // 2.append the desired extension if there is an extension which is not the same as specified
if (selectedFileName.indexOf('.') == -1 || if (selectedFileName.indexOf('.') == -1 ||
(selectedFileName.indexOf('.') != -1 && !selectedFileName.endsWith(fileNameExtension))) { (selectedFileName.indexOf('.') != -1 && !selectedFileName.endsWith(fileNameExtension)))
{
selectedFileName += "." + fileNameExtension; selectedFileName += "." + fileNameExtension;
} }
selectedFile = new File(selectedFile.getParentFile(), selectedFileName); selectedFile = new File(selectedFile.getParentFile(), selectedFileName);
} }
if (selectedFile.exists()) { if (selectedFile.exists())
{
int choice = JOptionPane.showConfirmDialog(parent, int choice = JOptionPane.showConfirmDialog(parent,
selectedFileName + " already exists. Overwrite it?", selectedFileName + " already exists. Overwrite it?",
"Overwrite File", "Overwrite File",
JOptionPane.YES_NO_OPTION); JOptionPane.YES_NO_OPTION);
// If "Yes" is selected // If "Yes" is selected
if (choice == JOptionPane.YES_OPTION) { if (choice == JOptionPane.YES_OPTION)
{
isValid = false; isValid = false;
} }
} else { }
else
{
isValid = false; isValid = false;
} }
} else { }
else
{
return null; return null;
} }
} while (isValid); } while (isValid);
@ -636,7 +685,8 @@ public class UIUtils {
* *
* @return The selected choice. * @return The selected choice.
*/ */
public static int showOkCancelDialog(String title, String msg, Component parent) { public static int showOkCancelDialog(String title, String msg, Component parent)
{
Object[] options = new Object[2]; Object[] options = new Object[2];
options[OK_OPTION] = "Ok"; options[OK_OPTION] = "Ok";
options[CANCEL_OPTION] = "Cancel"; options[CANCEL_OPTION] = "Cancel";
@ -672,7 +722,8 @@ public class UIUtils {
*/ */
public static Object showListInputDialog(Component parentComponent, Object message, String title, int messageType, public static Object showListInputDialog(Component parentComponent, Object message, String title, int messageType,
Icon icon, Object[] selectionValues, Object initialSelectionValue) Icon icon, Object[] selectionValues, Object initialSelectionValue)
throws HeadlessException { throws HeadlessException
{
JOptionPane pane = new JOptionPane(); JOptionPane pane = new JOptionPane();
JList list = getSingleSelectionList(pane, selectionValues, initialSelectionValue); JList list = getSingleSelectionList(pane, selectionValues, initialSelectionValue);
JScrollPane sp = new JScrollPane(list); JScrollPane sp = new JScrollPane(list);
@ -693,11 +744,13 @@ public class UIUtils {
// if null, meaning the user closed the window without choosing anything // if null, meaning the user closed the window without choosing anything
Object choice = pane.getValue(); Object choice = pane.getValue();
if (choice == null || ((Integer)choice).intValue() == JOptionPane.CANCEL_OPTION) { if (choice == null || ((Integer)choice).intValue() == JOptionPane.CANCEL_OPTION)
{
return initialSelectionValue; return initialSelectionValue;
} }
if (value == JOptionPane.UNINITIALIZED_VALUE) { if (value == JOptionPane.UNINITIALIZED_VALUE)
{
return null; return null;
} }
@ -708,21 +761,26 @@ public class UIUtils {
* Helper method and only used by <code>showListInputDialog</code> method. * Helper method and only used by <code>showListInputDialog</code> method.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static JList getSingleSelectionList(final JOptionPane optionPane, Object[] values, Object initialValue) { private static JList getSingleSelectionList(final JOptionPane optionPane, Object[] values, Object initialValue)
{
JList list = new JList(values); JList list = new JList(values);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
if(initialValue != null) { if(initialValue != null)
{
list.setSelectedValue(initialValue, true); list.setSelectedValue(initialValue, true);
} }
MouseListener mouseListener = new MouseAdapter() { MouseListener mouseListener = new MouseAdapter()
{
@Override @Override
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e)
{
JList list = (JList)e.getSource(); JList list = (JList)e.getSource();
int index = list.locationToIndex(e.getPoint()); int index = list.locationToIndex(e.getPoint());
optionPane.setInputValue(list.getModel().getElementAt(index)); optionPane.setInputValue(list.getModel().getElementAt(index));
if (isDoubleClick(e)) { if (isDoubleClick(e))
{
// close the pane once the user selects a value by double-clicking // close the pane once the user selects a value by double-clicking
optionPane.setValue(JOptionPane.CLOSED_OPTION); optionPane.setValue(JOptionPane.CLOSED_OPTION);
} }
@ -743,21 +801,27 @@ public class UIUtils {
* @return an instance of {@link ImageIcon} for the specified image, * @return an instance of {@link ImageIcon} for the specified image,
* null if the image file can't be found. * null if the image file can't be found.
*/ */
public static ImageIcon createImageIcon(String fileName) { public static ImageIcon createImageIcon(String fileName)
{
ImageIcon imgIcon = null; ImageIcon imgIcon = null;
// if the fileName is a full path // if the fileName is a full path
if (fileName.indexOf(java.io.File.separator) != -1) { if (fileName.indexOf(java.io.File.separator) != -1)
{
imgIcon = new ImageIcon(fileName); imgIcon = new ImageIcon(fileName);
} else { }
else
{
// if only a file name specified, try to find it at common resources folder // if only a file name specified, try to find it at common resources folder
URL imgURL = TrickApplication.class.getResource("resources" + java.io.File.separator + fileName); URL imgURL = TrickApplication.class.getResource("resources" + java.io.File.separator + fileName);
if (imgURL != null) { if (imgURL != null)
{
imgIcon = new ImageIcon(imgURL); imgIcon = new ImageIcon(imgURL);
} }
} }
if (imgIcon == null) { if (imgIcon == null)
{
System.err.println("Couldn't find file: " + fileName); System.err.println("Couldn't find file: " + fileName);
} }
@ -773,20 +837,29 @@ public class UIUtils {
* @return an instance of {@link InputStream} for the specified file, * @return an instance of {@link InputStream} for the specified file,
* null if the specified file can't be found. * null if the specified file can't be found.
*/ */
public static InputStream getInputStreamForFile(String fileName) { public static InputStream getInputStreamForFile(String fileName)
try { {
try
{
InputStream ins = null; InputStream ins = null;
// if the fileName is a full path // if the fileName is a full path
if (fileName.indexOf(java.io.File.separator) != -1) { if (fileName.indexOf(java.io.File.separator) != -1)
{
ins = new FileInputStream(fileName); ins = new FileInputStream(fileName);
} else { }
else
{
// if only a file name, then find it at common resources area // if only a file name, then find it at common resources area
ins = TrickApplication.class.getResourceAsStream("resources" + java.io.File.separator + fileName); ins = TrickApplication.class.getResourceAsStream("resources" + java.io.File.separator + fileName);
} }
return ins; return ins;
} catch (NullPointerException npe) { }
catch (NullPointerException npe)
{
return null; return null;
} catch (FileNotFoundException fnfe) { }
catch (FileNotFoundException fnfe)
{
return null; return null;
} }
} }
@ -803,13 +876,15 @@ public class UIUtils {
*/ */
public static JPanel createSearchableTitledPanel(String title, public static JPanel createSearchableTitledPanel(String title,
JComponent contentComponent, JComponent contentComponent,
JPanel findPanel) { JPanel findPanel)
{
JXTitledPanel titledPanel = new JXTitledPanel(); JXTitledPanel titledPanel = new JXTitledPanel();
titledPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("")); titledPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(""));
titledPanel.setTitle(title); titledPanel.setTitle(title);
titledPanel.add(new JScrollPane(contentComponent), BorderLayout.CENTER); titledPanel.add(new JScrollPane(contentComponent), BorderLayout.CENTER);
titledPanel.setMinimumSize(new Dimension(300, 250)); titledPanel.setMinimumSize(new Dimension(300, 250));
if (findPanel != null) { if (findPanel != null)
{
titledPanel.add(findPanel, BorderLayout.SOUTH); titledPanel.add(findPanel, BorderLayout.SOUTH);
} }
return titledPanel; return titledPanel;
@ -821,7 +896,8 @@ public class UIUtils {
* *
* @return a JTextPane that has different document styles. * @return a JTextPane that has different document styles.
*/ */
public static JTextPane createReadingTextPane() { public static JTextPane createReadingTextPane()
{
JTextPane textPane = new JTextPane(); JTextPane textPane = new JTextPane();
textPane.setEditable(false); textPane.setEditable(false);
textPane.setPreferredSize(new Dimension(400, 200)); textPane.setPreferredSize(new Dimension(400, 200));
@ -835,7 +911,8 @@ public class UIUtils {
* *
* @param doc a StyledDocument to add styles to. * @param doc a StyledDocument to add styles to.
*/ */
private static void addStylesToDocument(StyledDocument doc) { private static void addStylesToDocument(StyledDocument doc)
{
//Initialize some styles. //Initialize some styles.
Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE); Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);

View File

@ -30,7 +30,8 @@ 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
@ -47,6 +48,7 @@ public class AnimationPlayer extends JPanel {
private boolean paused; private boolean paused;
private boolean finished; private boolean finished;
private String animationFile; private String animationFile;
private int animationTimeStep;
private JLabel animationLabel; private JLabel animationLabel;
private PlayAnimationTask animationTask; private PlayAnimationTask animationTask;
@ -60,10 +62,29 @@ public class AnimationPlayer extends JPanel {
* Default constructor. * Default constructor.
* @param fileName name of file * @param fileName name of file
*/ */
public AnimationPlayer(String fileName) { public AnimationPlayer(String fileName)
{
animationFile = fileName; animationFile = fileName;
animationTimeStep = 150;
buildGUI(); buildGUI();
if (animationTask == null) { if (animationTask == null)
{
animationTask = new PlayAnimationTask();
}
}
/**
* Constructor with paramaterized time step.
* @param fileName name of file
* @param timeStep animation time step
*/
public AnimationPlayer(String fileName, int timeStep)
{
animationFile = fileName;
animationTimeStep = timeStep;
buildGUI();
if (animationTask == null)
{
animationTask = new PlayAnimationTask(); animationTask = new PlayAnimationTask();
} }
} }
@ -80,8 +101,10 @@ public class AnimationPlayer extends JPanel {
* Starts the animation task. This method has to be called * Starts the animation task. This method has to be called
* in order for the animation to be played. * in order for the animation to be played.
*/ */
public void start() { public void start()
if (animationTask == null) { {
if (animationTask == null)
{
animationTask = new PlayAnimationTask(); animationTask = new PlayAnimationTask();
} }
animationTask.execute(); animationTask.execute();
@ -90,33 +113,38 @@ public class AnimationPlayer extends JPanel {
/** /**
* Pauses the animation play. * Pauses the animation play.
*/ */
public void pause() { public void pause()
{
paused = true; paused = true;
} }
/** /**
* Resumes the animation play. * Resumes the animation play.
*/ */
public void resume() { public void resume()
{
paused = false; paused = false;
} }
/** /**
* Stops the animation play. * Stops the animation play.
*/ */
public void stop() { public void stop()
{
finished = true; finished = true;
} }
/** /**
* Builds the player GUI. * Builds the player GUI.
*/ */
private void buildGUI() { 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);
@ -128,49 +156,69 @@ public class AnimationPlayer extends JPanel {
/** /**
* 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 @Override
public Void doInBackground() { public Void doInBackground()
{
if (animationFile == null) { if (animationFile == null)
{
return null; return null;
} }
try { try
{
InputStream input = UIUtils.getInputStreamForFile(animationFile); InputStream input = UIUtils.getInputStreamForFile(animationFile);
stream = ImageIO.createImageInputStream(input); stream = ImageIO.createImageInputStream(input);
Iterator readers = ImageIO.getImageReaders(stream); Iterator readers = ImageIO.getImageReaders(stream);
if (!readers.hasNext()) { if (!readers.hasNext())
{
throw new RuntimeException("no image reader found"); throw new RuntimeException("no image reader found");
} }
ImageReader reader = (ImageReader) readers.next(); ImageReader reader = (ImageReader) readers.next();
reader.setInput(stream); // don't omit this line! reader.setInput(stream); // don't omit this line!
int n = reader.getNumImages(true); // don't use false! int n = reader.getNumImages(true); // don't use false!
for (int i = 0; i < n; i++) { int i = 0;
BufferedImage image = reader.read(i); while(i < n)
Image img = image; {
Image img = reader.read(i);
animationLabel.setIcon(new ImageIcon(img)); animationLabel.setIcon(new ImageIcon(img));
do { do
try { {
Thread.sleep(150); try
} catch (InterruptedException ie) { {
Thread.sleep(animationTimeStep);
}
catch (InterruptedException ie)
{
} }
} while (paused); } while (paused);
if (finished) { if (finished)
{
break; break;
} else { }
else
{
// rewind // rewind
if (i == n-1) { if (i >= n-1)
{
i = 0; i = 0;
} }
else
{
++i;
}
} }
} }
} catch (IOException ioe) { }
catch (IOException ioe)
{
} }
@ -178,11 +226,17 @@ public class AnimationPlayer extends JPanel {
} }
@Override @Override
public void done() { public void done()
if (stream != null) { {
try { 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();
} }
if (UIUtils.getTrickLogoStep() != null) {
try {
int timeStep = Integer.parseInt(UIUtils.getTrickLogoStep());
logoImagePanel = new AnimationPlayer(trickLogoName, timeStep);
}
catch (NumberFormatException e) {
logoImagePanel = new AnimationPlayer(trickLogoName); 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);