/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package de.cismet.tools.gui;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.List;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import de.cismet.tools.Static2DTools;
/**
* DOCUMENT ME!
*
* @author thorsten.hell@cismet.de
* @version $Revision$, $Date$
*/
public class StaticSwingTools {
//~ Static fields/initializers ---------------------------------------------
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(StaticSwingTools.class);
//~ Methods ----------------------------------------------------------------
/**
* DOCUMENT ME!
*
* @param tree DOCUMENT ME!
*/
public static void jTreeExpandAllNodes(final JTree tree) {
int row = 0;
while (row < tree.getRowCount()) {
tree.expandRow(row);
row++;
}
}
/**
* DOCUMENT ME!
*
* @param tree DOCUMENT ME!
*/
public static void jTreeExpandAllNodesAndScroll2Last(final JTree tree) {
// expand to the last leaf from the root
final DefaultMutableTreeNode root;
root = (DefaultMutableTreeNode)tree.getModel().getRoot();
tree.scrollPathToVisible(new TreePath(root.getLastLeaf().getPath()));
}
/**
* DOCUMENT ME!
*
* @param tree DOCUMENT ME!
*/
public static void jTreeCollapseAllNodes(final JTree tree) {
final TreePath p = tree.getSelectionPath();
int row = tree.getRowCount() - 1;
tree.setSelectionPath(p);
while (row >= 0) {
tree.collapseRow(row);
row--;
}
tree.setSelectionPath(p);
}
/**
* DOCUMENT ME!
*
* @param <T> DOCUMENT ME!
* @param c DOCUMENT ME!
* @param clazz DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
@SuppressWarnings("unchecked")
public static <T extends Component> T findSpecificParentComponent(Container c, final Class<T> clazz) {
// while (c != null && !(c.getClass().equals(clazz))) {
while ((c != null) && !(clazz.isAssignableFrom(c.getClass()))) {
c = c.getParent();
}
return (T)c;
}
/**
* From The Java Developers Almanac.
*
* @param table DOCUMENT ME!
* @param rowIndex DOCUMENT ME!
* @param vColIndex DOCUMENT ME!
*/
public static void jTableScrollToVisible(final JTable table, final int rowIndex, final int vColIndex) {
if (!(table.getParent() instanceof JViewport)) {
return;
}
final JViewport viewport = (JViewport)table.getParent();
// This rectangle is relative to the table where the
// northwest corner of cell (0,0) is always (0,0).
final Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
// The location of the viewport relative to the table
final Point pt = viewport.getViewPosition();
// Translate the cell location so that it is relative
// to the view, assuming the northwest corner of the
// view is (0,0)
rect.setLocation(rect.x - pt.x, rect.y - pt.y);
// Scroll the area into view
viewport.scrollRectToVisible(rect);
}
/**
* DOCUMENT ME!
*
* @param dtde DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static String getLinkFromDropEvent(final DropTargetDropEvent dtde) {
// System.out.println("getLinkFromDropEvent");
final String link = null;
final Transferable t = dtde.getTransferable();
final DataFlavor[] flavors = t.getTransferDataFlavors();
for (int i = 0; i < flavors.length; i++) {
final DataFlavor flavor = flavors[i];
try {
if (flavor.equals(DataFlavor.javaFileListFlavor)) {
// System.out.println("importData: FileListFlavor");
final List l = (List)t.getTransferData(DataFlavor.javaFileListFlavor);
final Iterator iter = l.iterator();
while (iter.hasNext()) {
final File file = (File)iter.next();
System.out.println(file);
try {
final String can = file.getCanonicalPath();
return can;
} catch (IOException ex) {
log.warn("Fehler bei file.getCanonicalPath()", ex); // NOI18N
}
}
} else if (flavor.equals(DataFlavor.stringFlavor)) {
final String fileOrURL = (String)t.getTransferData(flavor);
if (log.isDebugEnabled()) {
log.debug("GOT STRING: " + fileOrURL); // NOI18N
}
try {
final URL url = new URL(fileOrURL);
return url.toString();
} catch (MalformedURLException ex) {
log.warn("Illegal URL", ex); // NOI18N
return null;
}
} else {
// log.warn("importData rejected: "+ flavor);
// mach nix und probiers weiter
}
} catch (IOException ex) {
log.warn("IOError getting data: " + ex); // NOI18N
} catch (UnsupportedFlavorException e) {
log.warn("Unsupported Flavor: ", e); // NOI18N
}
}
return null;
}
/**
* DOCUMENT ME!
*
* @param tabPane DOCUMENT ME!
* @param text DOCUMENT ME!
* @param comp DOCUMENT ME!
*/
public static void jTabbedPaneWithVerticalTextAddTab(final JTabbedPane tabPane,
final String text,
final JComponent comp) {
jTabbedPaneWithVerticalTextAddTab(tabPane, text, null, comp);
}
/**
* DOCUMENT ME!
*
* @param tabPane DOCUMENT ME!
* @param text DOCUMENT ME!
* @param icon DOCUMENT ME!
* @param comp DOCUMENT ME!
*/
public static void jTabbedPaneWithVerticalTextAddTab(final JTabbedPane tabPane,
final String text,
final Icon icon,
final JComponent comp) {
final int tabPlacement = tabPane.getTabPlacement();
final Object textIconGap = UIManager.get("TabbedPane.textIconGap"); // NOI18N
final Insets tabInsets = UIManager.getInsets("TabbedPane.tabInsets"); // NOI18N
tabInsets.set(tabInsets.left, tabInsets.top, tabInsets.right, tabInsets.bottom);
UIManager.put("TabbedPane.textIconGap", new Integer(1)); // NOI18N
// UIManager.put("TabbedPane.tabInsets", new Insets(tabInsets.left, tabInsets.top, tabInsets.right,
// tabInsets.bottom));
UIManager.put("TabbedPane.tabInsets", tabInsets); // NOI18N
SwingUtilities.updateComponentTreeUI(tabPane);
switch (tabPlacement) {
case JTabbedPane.LEFT:
case JTabbedPane.RIGHT: {
if (icon == null) {
tabPane.addTab(null, new VerticalTextIcon(text, tabPlacement == JTabbedPane.RIGHT), comp);
} else {
Icon newIcon;
if (tabPlacement == JTabbedPane.RIGHT) {
final Icon[] icons = new Icon[2];
icons[0] = new VerticalTextIcon(text, tabPlacement == JTabbedPane.RIGHT);
icons[1] = icon;
newIcon = Static2DTools.joinIcons(icons, 6, Static2DTools.VERTICAL, Static2DTools.CENTER);
} else {
final Icon[] icons = new Icon[2];
icons[1] = icon;
icons[0] = new VerticalTextIcon(text, tabPlacement == JTabbedPane.RIGHT);
newIcon = Static2DTools.joinIcons(icons, 6, Static2DTools.VERTICAL, Static2DTools.CENTER);
}
if (log.isDebugEnabled()) {
log.debug("newIconHeight" + newIcon.getIconHeight()); // NOI18N
}
tabPane.addTab(null, newIcon, comp);
}
break;
}
default: {
tabPane.addTab(text, null, comp);
}
}
tabInsets.set(tabInsets.left, tabInsets.top, tabInsets.right, tabInsets.bottom);
UIManager.put("TabbedPane.tabInsets", tabInsets); // NOI18N
}
/**
* DOCUMENT ME!
*
* @param tabPane DOCUMENT ME!
* @param text DOCUMENT ME!
* @param comp DOCUMENT ME!
*/
public static void jTabbedPaneWithVerticalTextSetNewText(final JTabbedPane tabPane,
final String text,
final JComponent comp) {
jTabbedPaneWithVerticalTextSetNewText(tabPane, text, null, comp);
}
/**
* DOCUMENT ME!
*
* @param tabPane DOCUMENT ME!
* @param text DOCUMENT ME!
* @param icon DOCUMENT ME!
* @param comp DOCUMENT ME!
*/
public static void jTabbedPaneWithVerticalTextSetNewText(final JTabbedPane tabPane,
final String text,
final Icon icon,
final JComponent comp) {
jTabbedPaneWithVerticalTextSetNewText(tabPane, text, icon, Color.black, comp);
}
/**
* DOCUMENT ME!
*
* @param tabPane DOCUMENT ME!
* @param text DOCUMENT ME!
* @param icon DOCUMENT ME!
* @param textColor DOCUMENT ME!
* @param comp DOCUMENT ME!
*/
public static void jTabbedPaneWithVerticalTextSetNewText(final JTabbedPane tabPane,
final String text,
final Icon icon,
final Color textColor,
final JComponent comp) {
final int tabPlacement = tabPane.getTabPlacement();
switch (tabPlacement) {
case JTabbedPane.LEFT:
case JTabbedPane.RIGHT: {
if (icon == null) {
tabPane.setIconAt(tabPane.indexOfComponent(comp),
new VerticalTextIcon(text, tabPlacement == JTabbedPane.RIGHT, textColor));
} else {
Icon newIcon;
if (tabPlacement == JTabbedPane.RIGHT) {
final Icon[] icons = new Icon[2];
icons[0] = new VerticalTextIcon(text, tabPlacement == JTabbedPane.RIGHT, textColor);
icons[1] = icon;
newIcon = Static2DTools.joinIcons(icons, 6, Static2DTools.VERTICAL, Static2DTools.CENTER);
} else {
final Icon[] icons = new Icon[2];
icons[1] = icon;
icons[0] = new VerticalTextIcon(text, tabPlacement == JTabbedPane.RIGHT, textColor);
newIcon = Static2DTools.joinIcons(icons, 6, Static2DTools.VERTICAL, Static2DTools.CENTER);
}
if (log.isDebugEnabled()) {
log.debug("newIconHeight" + newIcon.getIconHeight()); // NOI18N
}
tabPane.setIconAt(tabPane.indexOfComponent(comp), newIcon);
}
return;
}
default: {
tabPane.setTitleAt(tabPane.indexOfComponent(comp), text);
}
}
}
/**
* DOCUMENT ME!
*
* @param tabPlacement DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static JTabbedPane jTabbedPaneWithVerticalTextCreator(final int tabPlacement) {
final java.util.Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
final Object key = keys.nextElement();
final Object value = UIManager.get(key);
if (key.toString().indexOf("abbed") != -1) { // NOI18N
if (log.isDebugEnabled()) {
log.debug(key + "," + value); // NOI18N
}
}
}
switch (tabPlacement) {
case JTabbedPane.LEFT:
case JTabbedPane.RIGHT: {
// Object textIconGap = UIManager.get("TabbedPane.textIconGap");
// Insets tabInsets = UIManager.getInsets("TabbedPane.tabInsets");
// tabInsets.set(tabInsets.left, tabInsets.top, tabInsets.right, tabInsets.bottom);
// UIManager.put("TabbedPane.textIconGap", new Integer(1));
// // UIManager.put("TabbedPane.tabInsets", new Insets(tabInsets.left, tabInsets.top, tabInsets.right, tabInsets.bottom));
// UIManager.put("TabbedPane.tabInsets", tabInsets);
final JTabbedPane tabPane = new JTabbedPane(tabPlacement);
//
// UIManager.put("TabbedPane.textIconGap", textIconGap);
// UIManager.put("TabbedPane.tabInsets", tabInsets);
// //SwingUtilities.updateComponentTreeUI(tabPane);
// tabInsets.set(tabInsets.left, tabInsets.top, tabInsets.right, tabInsets.bottom);
// UIManager.put("TabbedPane.tabInsets", tabInsets);
return tabPane;
}
default: {
return new JTabbedPane(tabPlacement);
}
}
}
/**
* DOCUMENT ME!
*
* @param tabPlacement DOCUMENT ME!
* @param tabLayoutPolicy DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static JTabbedPane jTabbedPaneWithVerticalTextCreator(final int tabPlacement, final int tabLayoutPolicy) {
final JTabbedPane jtp = jTabbedPaneWithVerticalTextCreator(tabPlacement);
return jtp;
}
/**
* DOCUMENT ME!
*
* @param sPane DOCUMENT ME!
*/
public static void setNiftyScrollBars(final JScrollPane sPane) {
try {
Dimension d = sPane.getVerticalScrollBar().getPreferredSize();
sPane.getVerticalScrollBar().getComponent(0).setVisible(false);
sPane.getVerticalScrollBar().getComponent(1).setVisible(false);
sPane.getVerticalScrollBar().setPreferredSize(new Dimension(8, d.height));
d = sPane.getHorizontalScrollBar().getPreferredSize();
sPane.getHorizontalScrollBar().getComponent(0).setVisible(false);
sPane.getHorizontalScrollBar().getComponent(1).setVisible(false);
sPane.getHorizontalScrollBar().setPreferredSize(new Dimension(d.width, 8));
sPane.setBackground(sPane.getViewport().getBackground());
sPane.getHorizontalScrollBar().setBackground(sPane.getViewport().getBackground());
sPane.getVerticalScrollBar().setBackground(sPane.getViewport().getBackground());
} catch (Exception e) {
log.warn("Cannot create the nifty scrollbars.", e);
}
}
/**
* DOCUMENT ME!
*
* @param c DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static Frame getFirstParentFrame(final Component c) {
return getParentFrame(c, true);
}
/**
* DOCUMENT ME!
*
* @param c DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static Frame getParentFrame(final Component c) {
return getParentFrame(c, false);
}
/**
* DOCUMENT ME!
*
* @param c DOCUMENT ME!
* @param first DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static Frame getParentFrame(final Component c, final boolean first) {
try {
Object o = c;
do {
o = ((Component)o).getParent();
if (log.isDebugEnabled()) {
log.debug("getParent:" + o); // NOI18N
}
} while (!(((o instanceof Frame) && (((Component)o).getParent() == null)) || first));
if (log.isDebugEnabled()) {
log.debug("getParentFrame returns " + o); // NOI18N
}
return (Frame)o;
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.warn("getParentFrame returns null", e); // NOI18N
}
return null;
}
}
/**
* Returns the parent frame of the given component or the given component if there is no parent frame.
*
* @param c component whose parent frame shall be determined
*
* @return parent frame or c if there is no parent frame
*/
public static Component getParentFrameIfNotNull(final Component c) {
final Component parent = getParentFrame(c);
if (parent == null) {
return c;
}
return parent;
}
/**
* DOCUMENT ME!
*
* @param components DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static Rectangle getComponentsExtent(final Component... components) {
final Rectangle r = new Rectangle();
Integer maxX = null;
Integer minX = null;
Integer maxY = null;
Integer minY = null;
for (final Component comp : components) {
// firsttimecheck
if (maxX == null) {
minX = comp.getX();
minY = comp.getY();
maxX = comp.getWidth() + minX;
maxY = comp.getHeight() + minY;
} else {
// min
minX = Math.min(minX, comp.getX());
minY = Math.min(minY, comp.getY());
// max
maxX = Math.max(maxX, comp.getX() + comp.getWidth());
maxY = Math.max(maxY, comp.getY() + comp.getHeight());
}
}
r.setRect(minX, minY, maxX - minX, maxY - minY);
return r;
}
/**
* Shows given dialog centered relative to the given parent.
*
* @param parent dialog parent
* @param dialog dialog
* @param isRelativeToParentFrame true if the dialog shall be centered relative to the parent frame (determined by
* the given parent), false otherwise
*/
public static void showDialog(final Component parent,
final JDialog dialog,
final boolean isRelativeToParentFrame) {
if (dialog.isVisible()) {
dialog.toFront();
} else {
if (isRelativeToParentFrame && (parent != null)) {
final Frame parentFrame = getParentFrame(parent);
// UGLY BUT IT WORKS - this part is for Windows users
// enforcing dialog to be set on top of other dialogs to prevent
// that the dialog becomes unreachable behind another modal dialog
dialog.setAlwaysOnTop(true);
dialog.toFront();
dialog.requestFocus();
dialog.setAlwaysOnTop(false);
if (parentFrame == null) {
centerWindowOnScreen(dialog);
} else {
dialog.setLocationRelativeTo(parentFrame);
dialog.setVisible(true);
}
} else {
centerWindowOnScreen(dialog);
}
}
}
/**
* Centers a Window instance on the screen on which the mouse pointer is located.
*
* @param w window instance to be centered
*/
public static void centerWindowOnScreen(final Window w) {
final PointerInfo pInfo = MouseInfo.getPointerInfo();
final Point pointerLocation = pInfo.getLocation();
// determine screen boundaries w.r.t. the current mouse position
final GraphicsConfiguration[] cfgArr = pInfo.getDevice().getConfigurations();
Rectangle bounds = null;
for (int i = 0; i < cfgArr.length; i++) {
bounds = cfgArr[i].getBounds();
if (pointerLocation.x <= bounds.x) {
break;
}
}
// determine coordinates in the center of the current mouse location
final int x = bounds.x + ((bounds.width - w.getWidth()) / 2);
final int y = bounds.y + ((bounds.height - w.getHeight()) / 2);
// show window
w.setLocation(x, y);
w.setVisible(true);
}
/**
* Determines the bounds of a component to centers it on the screen on which the mouse pointer is located.
*
* @param c Component instance to be centered
*
* @return The bounds of the component
*/
public static Rectangle getCenterBoundsForComponent(final Component c) {
final PointerInfo pInfo = MouseInfo.getPointerInfo();
final Point pointerLocation = pInfo.getLocation();
// determine screen boundaries w.r.t. the current mouse position
final GraphicsConfiguration[] cfgArr = pInfo.getDevice().getConfigurations();
Rectangle bounds = null;
for (int i = 0; i < cfgArr.length; i++) {
bounds = cfgArr[i].getBounds();
if (pointerLocation.x <= bounds.x) {
break;
}
}
// determine coordinates in the center of the current mouse location
final int x = bounds.x + ((bounds.width - c.getWidth()) / 2);
final int y = bounds.y + ((bounds.height - c.getHeight()) / 2);
return new Rectangle(x, y, c.getWidth(), c.getHeight());
}
/**
* Shows given dialog centered relative to its parent frame.
*
* @param dialog dialog
*/
public static void showDialog(final JDialog dialog) {
showDialog(dialog.getParent(), dialog, true);
}
/**
* Shows given dialog centered relative to its parent frame.
*
* @param dialog dialog
* @param isRelativeToParentFrame true if the dialog shall be centered relative to the parent frame (determined by
* the given parent), false if it shall be centered relative to its parent
*/
public static void showDialog(final JDialog dialog, final boolean isRelativeToParentFrame) {
showDialog(dialog.getParent(), dialog, isRelativeToParentFrame);
}
/**
* Calls pack() on a parent JDialog if available. Very useful to resize JDialogs from an embedded JPanel.
*
* @param component The component from which a parent JDialog is searched.
*/
public static void tryPackingMyParentDialog(final Component component) {
Component parent = component;
while (!(parent instanceof JDialog) && (parent != null)) {
parent = parent.getParent();
}
if (parent instanceof JDialog) {
((JDialog)parent).pack();
}
}
/**
* Adds a change listener to the given slider which ensures that the current value of the slider is permanently
* shown in the tooltip. Found here: http://www.jroller.com/santhosh/entry/tooltips_can_say_more
*
* @param slider The slider to modify.
* @param format The format to be used to print the value (e. g. "Percentage: {0,number,#0.0}%").
* @param factor A factor for the value. E. g. if the slider allows sliding between 0 and 1000 but we want to show
* the percentage, we have to multiply the value by 0.1D. Set to Double.NaN if it shouldn't be used.
*/
public static void enableSliderToolTips(final JSlider slider,
final MessageFormat format,
final double factor) {
slider.addChangeListener(new ChangeListener() {
private boolean adjusting = false;
private String oldTooltip;
@Override
public void stateChanged(final ChangeEvent e) {
if (slider.getModel().getValueIsAdjusting()) {
if (!adjusting) {
oldTooltip = slider.getToolTipText();
adjusting = true;
}
final double value = slider.getValue() * (Double.isNaN(factor) ? 1D : factor);
slider.setToolTipText(
(format != null) ? format.format(new Object[] { value }) : Double.toString(value));
hideToolTip(slider); // to avoid flickering
postToolTip(slider);
} else {
hideToolTip(slider);
slider.setToolTipText(oldTooltip);
adjusting = false;
oldTooltip = null;
}
}
});
}
/**
* Shows a component's tooltip.
*
* @param comp The component whose tooltip shall appear.
*/
public static void postToolTip(final JComponent comp) {
final Action action = comp.getActionMap().get("postTip");
if (action == null) {
// no tooltip
return;
}
final ActionEvent actionEvent = new ActionEvent(
comp,
ActionEvent.ACTION_PERFORMED,
"postTip",
EventQueue.getMostRecentEventTime(),
0);
action.actionPerformed(actionEvent);
}
/**
* Hides a component's tooltip.
*
* @param comp The component whose tooltip shall disappear.
*/
public static void hideToolTip(final JComponent comp) {
final Action action = comp.getActionMap().get("hideTip");
if (action == null) {
// no tooltip
return;
}
final ActionEvent actionEvent = new ActionEvent(
comp,
ActionEvent.ACTION_PERFORMED,
"hideTip",
EventQueue.getMostRecentEventTime(),
0);
action.actionPerformed(actionEvent);
}
/**
* DOCUMENT ME!
*
* @param cbo DOCUMENT ME!
*/
public static void decorateWithFixedAutoCompleteDecorator(final JComboBox cbo) {
AutoCompleteDecorator.decorate(cbo);
final JList pop = ((ComboPopup)cbo.getUI().getAccessibleChild(cbo, 0)).getList();
final JTextField txt = (JTextField)cbo.getEditor().getEditorComponent();
txt.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(final KeyEvent event) {
if ((event.getKeyCode() == KeyEvent.VK_DOWN) || (event.getKeyCode() == KeyEvent.VK_UP)) {
final Object selectedValue = pop.getSelectedValue();
if (selectedValue != null) {
txt.setText(String.valueOf(selectedValue));
}
txt.selectAll();
}
}
});
}
/**
* A Method to make UIManger.put comands configurable via a json file.
*
* <p>The json File has to placed to <code>/de/cismet/tools/gui/uitweaks.json</code>.</p>
*
* <p>An example json file can be found on <a href="https://github.com/cismet/cismet-gui-commons/issues/39">
* GitHub</a>.</p>
*/
public static void tweakUI() {
final ObjectMapper mapper = new ObjectMapper();
try {
final UITweaks config = mapper.readValue(UITweaks.class.getResourceAsStream(
"/de/cismet/tools/gui/uitweaks.json"),
UITweaks.class);
config.apply();
} catch (Exception e) {
log.warn("Problem during TweakingUI", e);
}
}
/**
* Opens a JFileChooser with a filter for the given file extensions and checks if the chosen file has the right
* extension. If not the first right extension is added.
*
* @param currentDirectoryPath The currebnt path that should be shown in the dialog
* @param isSaveDialog True, if a save dialog should be shown. Otherwise a open dialog will be shown
* @param allowedFileExtension all allowed file extensions or null, if every extension should be allowed
* @param fileExtensionDescription The description of the file extension.
* @param parent the parent component of the dialog
*
* @return DOCUMENT ME!
*/
public static File chooseFile(final String currentDirectoryPath,
final boolean isSaveDialog,
final String[] allowedFileExtension,
final String fileExtensionDescription,
final Component parent) {
JFileChooser fc;
try {
fc = new ConfirmationJFileChooser(currentDirectoryPath);
} catch (Exception bug) {
// Bug Workaround http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6544857
fc = new JFileChooser(currentDirectoryPath, new RestrictedFileSystemView());
}
final FileFilter fileFilter = new FileFilter() {
@Override
public boolean accept(final File f) {
boolean fileAllowed = f.isDirectory();
if (allowedFileExtension == null) {
fileAllowed = true;
} else if (!fileAllowed) {
final String extension = (f.getName().contains(".")
? f.getName().substring(f.getName().indexOf(".") + 1) : "");
for (final String allowedExt : allowedFileExtension) {
if (extension.equals(allowedExt)) {
fileAllowed = true;
break;
}
}
}
return fileAllowed;
}
@Override
public String getDescription() {
String description = fileExtensionDescription;
if ((description == null) && (allowedFileExtension != null)) {
for (final String allowedExt : allowedFileExtension) {
if (description == null) {
description = allowedExt;
} else {
description += ", " + allowedExt;
}
}
} else {
description += "";
}
return description;
}
};
fc.setAcceptAllFileFilterUsed(false);
fc.setFileFilter(fileFilter);
final int state = (isSaveDialog ? fc.showSaveDialog(parent) : fc.showOpenDialog(parent));
if (log.isDebugEnabled()) {
log.debug("state:" + state); // NOI18N
}
if (state == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
if (!fileFilter.accept(file)) {
file = new File(file.getAbsolutePath() + "." + allowedFileExtension[0]);
}
return file;
} else {
return null;
}
}
}