/**
*
*/
package photoSpreadUtilities;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidParameterException;
import java.text.ParseException;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import photoSpread.PhotoSpread;
import photoSpreadLoaders.CSVFileFilter;
import photoSpreadUtilities.HelpPane.HelpString;
/**
* @author paepcke
*
* Useful utilities of various sorts.
*
*/
public final class Misc {
static String reportToAdminMsg = "\nPlease copy/paste and send to the poor schlemiel who fixes this stuff:";
// The JFileChooser() is very slow. Known problem on the Web
// TODO: Switch file choosing to SWT:
static final JFileChooser fc = new JFileChooser();
/**
* @author paepcke
* Inner class to construct a Pair of two
* items that may be of differing type.
* Access the two parts as foo.first()
* and foo.second();
*
* @param <T1> Any item of type T
* @param <T2> Any item of type T
*/
/****************************************************
* Pair Inner Class
*****************************************************/
public class Pair<T1, T2> {
T1 _firstItem;
T2 _secondItem;
public Pair (T1 obj1, T2 obj2) {
_firstItem= obj1;
_secondItem = obj2;
}
public T1 first () {
return _firstItem;
}
public T2 second() {
return _secondItem;
}
}
/****************************************************
* WindowCloseAction Inner Class
*****************************************************/
public class WindowCloseAction extends AbstractAction implements Action, ActionListener{
private static final long serialVersionUID = 1L;
private JFrame _win = null;
public WindowCloseAction () {
}
public WindowCloseAction (JFrame frameToClose) {
_win = frameToClose;
}
public void actionPerformed(ActionEvent e) {
try {
if (_win == null)
_win = (JFrame) SwingUtilities.getWindowAncestor((Component) e.getSource());
} catch (Exception exc) {
return;
}
if (_win != null) {
_win.dispose();
}
}
}
/****************************************************
* ShowHelpAction Inner Class
*****************************************************/
/**
* @author paepcke
*
* Given the name of a help file, this class can display
* a help panel. Help files are in a directory called HelpFiles,
* whose parent directory must be on the classpath.
*/
public static class ShowHelpAction extends AbstractAction implements Action, ActionListener{
private static final long serialVersionUID = 1L;
private String _winTitle = null;
private JFrame _parentFrame = null;
private InputStream _helpFileStream = null;
private HelpString _helpText= null;
/**
* Given a relative path, like "HelpFiles/foo.html",
* return an input stream that points to the respective resource.
* 'Relative' is with respect to the location of the
* main method's class location.
*
* This method will work within Eclipse, and also
* when the resources are included in an executable
* jar file (as files, not within their own nested jar).
*
* To read from a text file resource:
* BufferedReader fileReader = new BufferedReader(new InputStreamReader(helpTextStream));
* String line = fileReader.readLine();
* while (line != null) {
* fullText += line;
* line = fileReader.readLine();
* }
*
*
* @param pathName
* @return InputStream from the resource, or null.
* @throws java.io.FileNotFoundException
*/
public static InputStream getResource(String pathName) throws java.io.FileNotFoundException {
File resFileObj = new File(pathName);
if (resFileObj.isAbsolute())
return new FileInputStream(resFileObj);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
return loader.getResourceAsStream(pathName);
}
public ShowHelpAction (String winTitle, String helpFilePath) {
_winTitle = winTitle;
try {
_helpFileStream = getResource(helpFilePath);
} catch (java.io.FileNotFoundException e) {
showErrorMsg("Failed to find help file '" + helpFilePath + "'.");
}
}
public ShowHelpAction (String winTitle, HelpString helpText) {
_winTitle = winTitle;
_helpText = helpText;
}
public ShowHelpAction (String winTitle, String helpFilePath, JFrame parentFrame) {
_winTitle = winTitle;
try {
_helpFileStream = getResource(helpFilePath);
} catch (java.io.FileNotFoundException e) {
showErrorMsg("Failed to find help file '" + helpFilePath + "'.");
}
_parentFrame = parentFrame;
}
public ShowHelpAction (String winTitle, HelpString helpText, JFrame parentFrame) {
_winTitle = winTitle;
_helpText = helpText;
_parentFrame = parentFrame;
}
public void makeHelpPaneVisible() {
if (_helpFileStream == null)
new HelpPane(_winTitle, _helpText, _parentFrame);
else
new HelpPane(_winTitle, _helpFileStream, _parentFrame);
}
public void actionPerformed(ActionEvent e) {
makeHelpPaneVisible();
}
}
/****************************************************
* AppExitWithConfirmAction Inner Class
*****************************************************/
/**
* @author paepcke
* Action that asks user's OK to exit the entire program.
* Instances of this action can be bound to keys, such
* as cnt-shift-w
*/
public static class AppExitWithConfirmAction extends AbstractAction {
private static final long serialVersionUID = 1L;
String _exitConfirmation = "";
JFrame _frameToShowIn = null;
public AppExitWithConfirmAction (String confirmMsg) {
_exitConfirmation = confirmMsg;
}
public AppExitWithConfirmAction (String confirmMsg, JFrame frameToShowIn) {
this(confirmMsg);
_frameToShowIn = frameToShowIn;
}
public void actionPerformed (ActionEvent e) {
exitIfUserWants(_exitConfirmation, _frameToShowIn);
}
}
/****************************************************
* SpaceFiller Inner Class
*****************************************************/
public static class SpaceFiller extends Box.Filler {
private static final long serialVersionUID = 1L;
boolean _isTransparent;
Dimension _dim;
public SpaceFiller (Dimension dim, boolean isTransparent) {
super(dim, dim, dim);
_isTransparent = isTransparent;
_dim = dim;
if (_isTransparent)
setOpaque(false);
else
setOpaque(true);
}
public void paintComponent(Graphics g) {
if (_isTransparent)
return;
super.paintComponent(g);
}
}
/****************************************************
* Methods
*****************************************************/
/**
* Given filename string, make sure it has
* the specified extension. If another extension
* exists, it is replaced. Throws error if
* filename is a directory.
*
* @param fileName
* @param desiredExtension
* @return
* @throws ParseException
*/
public static String ensureFileExtension(String fileName, String desiredExtension) throws ParseException {
// If user passed in a directory, throw error:
if (denotesDirectory(fileName))
throw new ParseException("Cannot add extension '" +
desiredExtension +
"' to '" + fileName +
"', which is a directory.", 0);
// Make sure the passed-in extension
// doesn't have dots:
desiredExtension = Misc.trim(desiredExtension, '.');
int dotPos = fileName.lastIndexOf(".");
// If file is without extension, just append the desired one:
if (dotPos == -1) return fileName + '.' + desiredExtension;
// If file name already has the right extension, great:
String currExtension = fileName.substring(dotPos + 1);
if (currExtension.equals((String) desiredExtension)) return fileName;
return fileName.substring(0, dotPos + 1) + desiredExtension;
}
public static boolean denotesDirectory(String path) {
if (path.endsWith("/") || path.endsWith("\\"))
return true;
else
return false;
}
/**
* Given a File object, returns its path's extension, if present.
*
* @param f
* @return Extension of given File object's path, or null.
*/
public static String getExtension(File f) {
String ext = null;
String s = f.getName();
int i = s.lastIndexOf('.');
if (i > 0 && i < s.length() - 1) {
ext = s.substring(i+1).toLowerCase();
}
return ext;
}
/**
* Reads a file storing intermediate data into a list if file is just too,
* too big.
*
* @param fileName the file to be read
* @return Byte array with file contents
* @throws IOException
*/
public static byte[] readBigFile(String fileName) throws IOException {
final int BUF_LEN = 10000 * 1024; // 10MB
InputStream in = null;
final int noOffset = 0;
final byte[] buf = new byte[BUF_LEN];
// List of bufLen pieces of the read data:
List<byte[]> chunkList = new ArrayList<byte[]>();
try {
in = new BufferedInputStream(new FileInputStream(fileName));
int lenRead = 0;
while ((lenRead = in.read(buf, noOffset, BUF_LEN)) != -1) {
// If all the file's data fit into the first
// chunk, then we're done:
if ((lenRead < BUF_LEN) && chunkList.isEmpty()) {
return buf;
}
// Not done reading, or we already read at least
// one chunk. Create a new chunk and copy the just-read
// data into it:
byte[] tmp = new byte[lenRead];
System.arraycopy(buf, noOffset, tmp, noOffset, lenRead); // still
// need
// to
// do
// copy
// Append to our growing list of chunks:
chunkList.add(tmp);
}
/*
* This part is optional. This method could instead return the
* arrayList of data chunks. But here we consolidate everything into
* one big buffer:
*/
// If only one chunk was read, return it.
// This would only happen if the file is exactly
// bufLen bytes long:
if (chunkList.size() == 1)
return (byte[]) chunkList.get(0);
int totalLength = 0;
for (int i = 0; i < chunkList.size(); i++)
totalLength += ((byte[]) chunkList.get(i)).length;
byte[] resBuf = new byte[totalLength]; // Final output buffer
int totalBytesCopied = 0;
for (int i = 0; i < chunkList.size(); i++) {
byte[] oneChunk = (byte[]) chunkList.get(i);
System.arraycopy(oneChunk, noOffset, resBuf, totalBytesCopied,
oneChunk.length);
totalBytesCopied += oneChunk.length;
}
} finally {
if (in != null)
try {
in.close();
} catch (Exception e) {
}
}
return buf;
}
public static ArrayList<File> flattenFiles(ArrayList<File> files) {
ArrayList<File> flatFiles = new ArrayList<File>();
for (File f : files) {
if(f.isDirectory()){
flatFiles.addAll(flattenFiles(f.listFiles()));
}
else{
flatFiles.add(f);
}
}
return flatFiles;
}
public static ArrayList<File> flattenFiles(File[] files){
ArrayList<File> flatFiles = new ArrayList<File>();
for(int i = 0; i < files.length; i++){
File f = files[i];
if(f.isDirectory()){
flatFiles.addAll(flattenFiles(f.listFiles()));
}
else{
flatFiles.add(f);
}
}
return flatFiles;
}
/**
* Given a string, like C3 or AY390, return
* a corresponding CellCoordinates object, or null if
* error.
* @param cellSpec String of a cell name
* @return CellCoordinates corresponding to given name, or null if parsing error.
*/
public static CellCoordinates getCellAddress(String cellSpec) {
String colName;
int rowInt = 0;
int pos = -1;
for (char c : cellSpec.toCharArray()) {
if (Character.getType(c) == Character.UPPERCASE_LETTER) {
pos++;
continue;
}
}
if (pos < 0)
return null;
colName = new String(cellSpec.substring(0, pos + 1));
for (char c : cellSpec.substring(pos + 1).toCharArray())
if (Character.getType(c) != Character.DECIMAL_DIGIT_NUMBER)
return null;
try {
rowInt = new Integer(cellSpec.substring(pos + 1));
} catch (Exception e) {
return null;
}
if (rowInt < 1)
return null;
// Make row 0-based:
return(new CellCoordinates(--rowInt, excelColToInt(colName)));
}
public static String getCellAddress(CellCoordinates coords) {
return getCellAddress(coords.row(), coords.column());
}
public static String getCellAddress(int row, int col) {
if (col == 0) return "";
return intToExcelCol(col) + (++row);
}
/**
* Given an int between 1 and 701, return string "A" through "ZZ"
* as per Excel spreadsheet column names.
*
* @param col
* @return
* @throws InvalidParameterException
*/
public static String intToExcelCol(int col) throws InvalidParameterException {
if (col < 1)
throw new InvalidParameterException("Only numbers above zero can be converted to Excel column names.");
return intToExcelColHelper(--col);
}
public static String intToExcelColHelper(int col) {
final int radix = 26;
char excelDigit;
if (col < radix) {
excelDigit = (char)(((int)'A') + col);
return String.valueOf(excelDigit);
}
else
return intToExcelColHelper((int)Math.floor(col/radix) - 1) + intToExcelColHelper(col % radix);
}
/**
* Given an Excel column name, return the corresponding
* column number. Column A is 1.
*
* @param colName
* @return Integer corresponding to the Excel name (A<==>1)
*/
public static int excelColToInt(String colName) {
int res = 0;
int radix = 26;
StringCharacterIterator it = new StringCharacterIterator(colName);
for(char excelDigit = it.first(); excelDigit != StringCharacterIterator.DONE; excelDigit = it.next()) {
res = (res*radix) + excelDigit - (int)'A' + 1;
}
return res;
}
/**
* Given a string and a char, trim all occurrences of
* the char from both the front and back of the string.
*
* @param str
* @param trash
* @return Cleaned string.
*/
public static String trim(String str, char trash) {
while (str.startsWith(String.valueOf(trash)))
str = str.substring(1);
while (str.endsWith(String.valueOf(trash)))
str = str.substring(0, str.length() - 1);
return str;
}
public static String trim(String str, String trash) {
while (str.startsWith(trash)) {
str = str.substring(trash.length());
}
while (str.endsWith(trash)) {
str = str.substring(0, str.length() - trash.length() - 1);
}
return str;
}
/**
* Determines whether a value is PhotoSpread's special null.
* @param arg
* @return True if argument is a PhotoSpread null, else false
*/
public boolean isNull(Object arg) {
try {
return ((String) arg).equals(Const.NULL_VALUE_STRING);
} catch (Exception e) {
return false;
}
}
/**
* Given a string, return a string with all XML special
* characters escaped.
* @param strToConvert
* @return XML-safe string.
*/
public static String escapeXMLSpecials(String strToConvert) {
StringBuffer buffer = new StringBuffer();
for(int i = 0;i < strToConvert.length();i++)
{
char c = strToConvert.charAt(i);
if(c == '<')
buffer.append("<");
else if(c == '>')
buffer.append(">");
else if(c == '&')
buffer.append("&");
else if(c == '"')
buffer.append(""");
else if(c == '\'')
buffer.append("'");
else
buffer.append(c);
}
return buffer.toString();
}
/**
* Bind a key to an action on a particular component.
* The binding will be active while the surrounding
* window is selected. Binding keys to a container,
* like JFrame needs to use the root pane. The
* polymorphic bindKey(JFrame) takes care of that.
*
* @param comp The component to which the action will be attached.
* @param keyDescription A string describing the key as
* per KeyStroke.getKeyStroke(String). Ex: "alt A" or "ctrl UP" (for up-arrow).
* Key names are the <keyName> part in VK_<keyName>
* @param action Action object to invoke when key is pressed.
*/
public static void bindKey (JComponent comp, String keyDescription, Action action) {
InputMap keyMap = comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = comp.getActionMap();
keyMap.put(KeyStroke.getKeyStroke(keyDescription), keyDescription);
actionMap.put(keyDescription, action);
}
public static void bindKey (JFrame frame, String keyDescription, Action action) {
bindKey(frame.getRootPane(), keyDescription, action);
}
/**
* Given a string with two integers, produce a Pair object
* with the two integers. Error checking is performed on
* the string.
*
* @param strOfTwoSpaceSeparatedInts
* @return Pair object containing two ints.
*/
public static Pair<Integer, Integer> twoIntsFromString (String twoIntsStr) {
String strOfTwoSpaceSeparatedInts = ((String) twoIntsStr);
// Partition the string by whitespace. The 3 tells the
// split to return at most 3 elements: the first two
// (hopefully) numbers, and any rest of the string. The
// latter we ignore:
String[] intStrArray = strOfTwoSpaceSeparatedInts.split("[ \t\n\f\r]", 3);
if (intStrArray.length < 2) {
throw new NumberFormatException("Expected a string with two integers. Was given '" +
strOfTwoSpaceSeparatedInts + "'.");
}
int first, second = 0;
try {
first = Integer.parseInt(intStrArray[0]);
second = Integer.parseInt(intStrArray[1]);
} catch (NumberFormatException e) {
throw new RuntimeException(new NumberFormatException("Expected a string with two integers. Was given '" +
strOfTwoSpaceSeparatedInts + "'."));
}
return new Misc().new Pair<Integer, Integer>(first, second);
}
/**
* Create an ImageIcon from a file name.
* @param path File containing a Java-understandable file (.gif, .jpg, .png)
* @param description Description of image for assistive technologies.
* @return ImageIcon or null if file not found.
*/
public static ImageIcon createImageIcon(String path, String description) {
java.net.URL imgURL = ClassLoader.getSystemResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
return null;
// throw new PhotoSpreadException.FileIOException("Image file " + path + " not found.");
}
}
/**
* Create an ImageIcon from a file name.
* @param path File containing a Java-understandable file (.gif, .jpg, .png)
* @param description Description of image for assistive technologies.
* @return ImageIcon or null if file not found.
*/
public static ImageIcon createImageIcon(String path) {
return createImageIcon(path, "");
}
public static ImageIcon createImageIcon(String path, Dimension dim) {
ImageIcon imgIcon = createImageIcon(path, "");
if (imgIcon == null)
return null;
BufferedImage buffImg = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = buffImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(imgIcon.getImage(), 0, 0, dim.width, dim.height, null);
g2.dispose();
return new ImageIcon(buffImg);
}
public static Image getScaledImage(ImageIcon srcImgIcon, int h, int w){
Image srcImg = srcImgIcon.getImage();
Double scale = new Double(srcImgIcon.getIconHeight()) / new Double(srcImgIcon.getIconWidth());
int scaledHeight = new Double(w * scale).intValue();
BufferedImage resizedImg = new BufferedImage(w, scaledHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(srcImg, 0, 0, w, scaledHeight, null);
g2.dispose();
return resizedImg;
}
public static final Component getVisibleChildAt(Container container, Point p) {
for (int i = 0; i < container.getComponentCount(); i++) {
Component c = container.getComponent(i);
if (c.isVisible() && c.contains(p.x - c.getX(), p.y - c.getY()))
return c;
}
return null;
}
/**
* Use for error message dialog boxes that just call for clicking OK.
* @param msg Message to display in the dialog box
*/
public static void showErrorMsg(String msg) {
showErrorMsg(msg, null);
}
public static void showErrorMsgOnSheetWindow(String msg) {
showErrorMsg(msg, PhotoSpread.getCurrentSheetWindow());
}
/**
* For multi-line error messages. Use for error message
* dialog boxes that just call for clicking OK.
* @param msgs ArrayList of message strings to display in the dialog box,
* one line per ArrayList item.
*/
public static void showErrorMsgs(ArrayList<String> msgs) {
showErrorMsgArray(msgs, null);
}
/**
* For multi-line error messages. Use for error message
* dialog boxes that just call for clicking OK.
* Displays the box on top of the current sheet window.
* @param msgs ArrayList of message strings to display in the dialog box,
* one line per ArrayList item.
*/
public static void showErrorMsgsOnSheetWindow(ArrayList<String> msgs) {
showErrorMsgArray(msgs, PhotoSpread.getCurrentSheetWindow());
}
public static void showErrorMsg(Exception e, String msg) {
String fullMsg = msg + " (" + e.getClass().getName() + "): " + e.getMessage();
showErrorMsg(fullMsg);
}
public static void showErrorMsgAndStackTrace(Exception e) {
ArrayList<String> msgs = new ArrayList<String>();
msgs.add(e.getMessage());
msgs.add(reportToAdminMsg);
msgs.addAll(prepareStackTraceOutput(e));
showErrorMsgs(msgs);
/*showErrorMsg(
e.getMessage() +
reportToAdminMsg +
prepareStackTraceOutput(e));
*/
}
public static void showErrorMsgAndStackTrace(Exception e, String msg) {
ArrayList<String> fullMsg = new ArrayList<String>();
fullMsg.add(msg);
fullMsg.add(e.getMessage());
fullMsg.add(reportToAdminMsg);
fullMsg.addAll(prepareStackTraceOutput(e));
showErrorMsgs(fullMsg);
}
private static ArrayList<String> prepareStackTraceOutput(Exception e) {
String oneStackTraceLine = "";
ArrayList<String> fullMsg = new ArrayList<String>();
for (StackTraceElement traceEntry : e.getStackTrace()) {
oneStackTraceLine =
"" + "at " +
traceEntry.getFileName() +
"(" +
traceEntry.getMethodName() +
":" +
traceEntry.getLineNumber() +
")";
fullMsg.add(oneStackTraceLine);
}
return fullMsg;
}
/**
* Use for error message dialog boxes that just call for clicking OK.
* @param msg Message to display in the dialog box
* @param frameToShowIn Frame in which the dialog box is to be placed. If null,
* then a new frame is created.
*/
public static void showErrorMsg(String msg, Component frameToShowIn) {
JOptionPane.showMessageDialog(
frameToShowIn,
msg,
"PhotoSpread Error",
JOptionPane.ERROR_MESSAGE);
}
public static File getCSVFileNameFromUser() {
return getFileNameFromUser(
new CSVFileFilter(),
JFileChooser.FILES_AND_DIRECTORIES);
}
public static File getFileNameFromUser() {
return getFileNameFromUser(
null, // no file filter
JFileChooser.FILES_AND_DIRECTORIES);
}
public static File getFileNameFromUser(int whatToShow) {
return getFileNameFromUser(
null, // no file filter
whatToShow);
}
/**
* @return
*/
public static File getFileNameFromUser(
FileFilter browseFileTypeFilter,
int whatToShow) {
File importFile = null;
String priorReadDir = PhotoSpread.photoSpreadPrefs.getProperty(PhotoSpread.lastDirReadKey);
fc.setCurrentDirectory(new File(priorReadDir));
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
if ((whatToShow == JFileChooser.DIRECTORIES_ONLY) ||
(whatToShow == JFileChooser.FILES_ONLY) ||
(whatToShow == JFileChooser.FILES_AND_DIRECTORIES))
fc.setFileSelectionMode(whatToShow);
// Should browser offer only files? Only directories? Both, etc.
// Value of null shows all files:
fc.setFileFilter(browseFileTypeFilter);
fc.setMultiSelectionEnabled(false);
int returnVal = fc.showOpenDialog(PhotoSpread.getCurrentSheetWindow());
if (returnVal != JFileChooser.APPROVE_OPTION)
return null;
importFile = fc.getSelectedFile();
PhotoSpread.photoSpreadPrefs.setProperty(PhotoSpread.lastDirReadKey, importFile.getParent());
return importFile;
}
/**
* Use for error message dialog boxes that just call for clicking OK.
* @param msgs Array of messages to display in the dialog box as a 'vertical stack'
* @param frameToShowIn Frame in which the dialog box is to be placed. If null,
* then a new frame is created.
*/
public static void showErrorMsgArray(ArrayList<String> msgs, Component frameToShowIn) {
JOptionPane op = new JOptionPane(msgs, JOptionPane.ERROR_MESSAGE) {
private static final long serialVersionUID = 1L;
public int getMaxCharactersPerLineCount() {
return 80;
}
};
op.setVisible(true);
/*
op.showMessageDialog(
frameToShowIn,
msgs,
"PhotoSpread Error",
JOptionPane.ERROR_MESSAGE);
*/
}
/**
* Use for yes/no dialog boxes.
* @param msg Message to display in the dialog box
* @return True if user clicked Yes. Else returns false;
*/
public static boolean showConfirmMsg(String msg) {
return showConfirmMsg(msg, null);
}
/**
* Use for yes/no dialog boxes.
* @param msg Message to display in the dialog box
* @param frameToShowIn Frame in which the dialog box is to be placed. If null,
* then a new frame is created.
* @return True if user clicked Yes. Else returns false;
*/
public static boolean showConfirmMsg(String msg, Component frameToShowIn) {
int res = JOptionPane.showConfirmDialog(
frameToShowIn,
msg,
"PhotoSpread Confirmation",
JOptionPane.YES_NO_OPTION);
if (res == JOptionPane.YES_OPTION)
return true;
else
return false;
}
/**
* Shows a purely informational message with an OK button.
* @param msg The message to show the user.
* @param frameToShowIn The frame within which to show the
* message dialog. Null causes display in center of screen.
*/
public static void showInfoMsg (String msg, Component frameToShowIn) {
JOptionPane.showMessageDialog(
frameToShowIn,
msg,
"PhotoSpread Information",
JOptionPane.INFORMATION_MESSAGE);
}
/**
* Shows a purely informational message with an OK button.
* The message will display in the center of the screen.
*
* @param msg The message to show the user.
*/
public static void showInfoMsg (String msg) {
showInfoMsg(msg, null);
}
/**
* Puts up a Yes/No question. If user answers yes,
* exits the program (and therefore never returns).
* Else returns false. Dialog box will be in center
* of the screen.
* @param confirmMsg
* @return If the user responded No to confirmMsg, returns false. Else won't return.
*/
public static boolean exitIfUserWants (String confirmMsg) {
if (showConfirmMsg(confirmMsg))
System.exit(0);
return false;
}
/**
* Puts up a Yes/No question. If user answers yes,
* exits the program (and therefore never returns).
* Else returns false. Dialog box will be inside
* the given frame.
* @param confirmMsg
* @return If the user responded No to confirmMsg, returns false. Else won't return.
*/
public static boolean exitIfUserWants (String confirmMsg, JFrame frameToShowIn) {
if (showConfirmMsg(confirmMsg, frameToShowIn))
System.exit(0);
return false;
}
/****************************************************
* Inner Class ByteArrayConverter: Convert byte array to string
*****************************************************/
public static class ByteArrayConverter {
static final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1',
(byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6',
(byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
(byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };
public static String getHexString(byte[] raw) {
byte[] hex = new byte[2 * raw.length];
int index = 0;
String res = null;
for (byte b : raw) {
int v = b & 0xFF;
hex[index++] = HEX_CHAR_TABLE[v >>> 4];
hex[index++] = HEX_CHAR_TABLE[v & 0xF];
}
try {
res = new String(hex, "US-ASCII");
}
catch (UnsupportedEncodingException e) {
// Every Java implementation is required to support US-ASCII==>do nothing
}
return res;
}
}
/****************************************************
* Main and/or Testing Methods
*****************************************************/
public static void main(final String[] args) {
try {
//System.out.println("Current directory: " + System.getProperty("user.dir"));
//String path = "HelpFiles/sheetHelp.html";
// File f = Misc.ShowHelpAction.getResource(path);
// System.out.println(f);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}