//$Header: /cvsroot-fuse/mec-as2/39/mendelson/util/MecFileChooser.java,v 1.1 2012/04/18 14:10:41 heller Exp $ package de.mendelson.util; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.zip.Adler32; import javax.swing.AbstractAction; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JTextField; import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileView; import javax.swing.text.JTextComponent; /* * Copyright (C) mendelson-e-commerce GmbH Berlin Germany * * This software is subject to the license agreement set forth in the license. * Please read and agree to all terms before using this software. * Other product and brand names are trademarks of their respective owners. */ /** * This shows a file chooser, it is possible to select a native or the * swing file chooser. * @author S.Heller * @version $Revision: 1.1 $ */ public class MecFileChooser extends JFileChooser { //supports only one type of choosers at the moment public static int TYPE_SWING = 1; /**ResourceBundle to store localized informations*/ private MecResourceBundle rb = null; /**ParentFrame of this component*/ private Frame parent = null; /**indicates if the user canceled the dialog*/ private boolean canceled = false; /**Remind the selected directories and restore them if the widget is called in the same context again*/ public final static Map<Long, File> lastGoodSelectionMap = new HashMap<Long, File>(); /**Stores a unique id for this call*/ private Long uniqueId = null; /** Creates new MecFileChooser * Creates a new FileChooser with the given default directory * @param defaultDirectory Directory to start by default, may be a file * @param dialogTitle Title to show at the chooser * @param parent parent component * @param TYPE type of the dialog to choose as defined in the class *@deprecated use the same method without the type settings */ public MecFileChooser(Frame parent, String defaultDirectory, String dialogTitle, final int TYPE) { this(parent, dialogTitle); this.setPreselectedFile(new File(defaultDirectory)); } /** Creates new MecFileChooser * Creates a new FileChooser with the given default directory * @param defaultDirectory Directory to start by default, may be a file * @param dialogTitle Title to show at the chooser * @param parent parent component */ public MecFileChooser(Frame parent, String dialogTitle) { super(FileSystemView.getFileSystemView()); //Load default resourcebundle try { this.rb = (MecResourceBundle) ResourceBundle.getBundle( ResourceBundleMecFileChooser.class.getName()); } //load up default english resourcebundle catch (MissingResourceException e) { throw new RuntimeException("Oops..resource bundle " + e.getClassName() + " not found"); } this.parent = parent; this.setDialogTitle(dialogTitle); this.setMultiSelectionEnabled(false); //trow an exception to get the call stack. Then build a hash on this call stack to figure out the context try { throw new Exception("get callstack"); } catch (Exception e) { StackTraceElement[] traceElements = e.getStackTrace(); StringBuilder buffer = new StringBuilder(); for (int i = 0; i < traceElements.length; i++) { buffer.append(traceElements[i].toString()); if (i > 3) { break; } } Adler32 adler32 = new Adler32(); adler32.update(buffer.toString().getBytes()); this.uniqueId = Long.valueOf(adler32.getValue()); //does this call context already exist? if (lastGoodSelectionMap.containsKey(this.uniqueId)) { File lastGoodFile = lastGoodSelectionMap.get(this.uniqueId); if (lastGoodFile.exists()) { if (lastGoodFile.isDirectory()) { this.setCurrentDirectory(lastGoodFile); } else { this.setSelectedFile(lastGoodFile); } } } } } /**Set a new file view to the chooser, e.g. to display new icons etc*/ @Override public void setFileView(FileView fileview) { super.setFileView(fileview); } /**Sets the type of the chooser: load*/ public void setTypeLoad() { this.setDialogType(JFileChooser.OPEN_DIALOG); } /**Sets the type of the chooser: save*/ public void setTypeSave() { this.setDialogType(JFileChooser.SAVE_DIALOG); } /**Creates a chooser dialog and displays it*/ private void showChooserDialog() { this.setApproveButtonText(this.rb.getResourceString("button.select")); final JDialog dialog = this.createDialog(this.parent); // Add listener for approve and cancel events this.addActionListener(new AbstractAction() { @Override public void actionPerformed(ActionEvent evt) { if (JFileChooser.CANCEL_SELECTION.equals(evt.getActionCommand())) { canceled = true; dialog.setVisible(false); } else if (JFileChooser.APPROVE_SELECTION.equals(evt.getActionCommand())) { dialog.setVisible(false); } } }); // Add listener for window closing events dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { canceled = true; } }); dialog.setVisible(true); } /**Browses for a filename and returns it * @param parent Parent component * @return null if the user cancels the action! */ public String browseFilename() { this.showChooserDialog(); if (this.canceled) { return (null); } File file = this.getSelectedFile(); lastGoodSelectionMap.put(this.uniqueId, file); return (file.getAbsolutePath()); } /**Browses the directory for a filename * @param component JComponent where the chosen filename will displayed * @param filter FileFilters that are accepted */ public String browseFilename(JComponent component, String[] filter) { if (filter != null) { this.addChoosableFileFilter(new MecFileFilter(filter)); //component is a text field } if (component instanceof JTextField) { JTextField textField = (JTextField) component; //if there is something typed in in the text field the already predefined file //or directory should be ignored if (textField.getText().length() > 0) { this.setPreselectedFile(new File(textField.getText())); } } this.showChooserDialog(); if (this.canceled) { return (null); } File file = this.getSelectedFile(); if (component != null) { if (component instanceof JTextComponent) { ((JTextComponent) component).setText(file.getAbsolutePath()); } if (component instanceof JComboBox) { this.setItem((JComboBox) component, file.getAbsolutePath()); } } return (file.getAbsolutePath()); } /**Sets the preselected file in the directory chooser and returns if this was successful*/ public void setPreselectedFile(File preselectedFile) { if (!preselectedFile.exists()) { //preselection file does not exist: first try to set the parent directory as default. //if this does not work use the users home directory File parentDir = preselectedFile.getParentFile(); if( parentDir != null && parentDir.exists()){ this.setCurrentDirectory(parentDir); }else{ this.setCurrentDirectory(new File(System.getProperty("user.dir"))); } } else if (!preselectedFile.isDirectory()) { String localParent = preselectedFile.getParent(); if (localParent != null) { this.setCurrentDirectory(new File(localParent)); } this.setSelectedFile(preselectedFile); } else { this.setCurrentDirectory(preselectedFile); } } /**Sets the preselected directory in the directory chooser*/ @Override public void setCurrentDirectory(File preselectedDir) { if (preselectedDir != null && !preselectedDir.exists()) { super.setCurrentDirectory(new File(System.getProperty("user.dir"))); } else { super.setCurrentDirectory(preselectedDir); } } /**Adds an item to a comboBox. If the item already exists, * it is set as selected * @param comboBox Component to set the item * @param item Object to write into the ComboBox */ private void setItem(JComboBox comboBox, Object item) { //Check if element exists. if the item exists, set it and return for (int i = 0; i < comboBox.getItemCount(); i++) { if (comboBox.getItemAt(i).equals(item)) { comboBox.setSelectedIndex(i); return; } } comboBox.addItem(item); comboBox.setSelectedItem(item); } /**Browses the directory for a filename, all files are accepted. If there is * already a file name displayed in the component, its path will set as * default path. * @param component JComponent where the chosen filename will displayed *@return null if the user cancels the action! */ public String browseFilename(JComponent component) { return (this.browseFilename(component, null)); } /**Browses directories ONLY, no file selection allowed * @param component TextComponent where the chosen filename will displayed */ public String browseDirectory(JComponent component) { this.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); return (this.browseFilename(component)); } /**Browses directories ONLY, no file selection allowed */ public String browseDirectory() { this.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); return (this.browseFilename()); } /**Filefilter for the chooser*/ public static class MecFileFilter extends javax.swing.filechooser.FileFilter { private String filePath = ""; /**Stores the possible file filter extentions*/ protected String[] filter = null; public MecFileFilter(String[] filter) { super(); this.filter = filter; } @Override public boolean accept(File file) { if (file.isDirectory()) { return (true); } this.filePath = file.getPath().toLowerCase(); //check accept if (this.filter != null) { boolean accept = false; for (int i = 0; i < this.filter.length; i++) { if (this.filePath.endsWith(this.filter[i])) { accept = true; break; } } return (accept); } return (true); } /**return descriptions of choosable file extentions*/ @Override public String getDescription() { if (this.filePath.endsWith(".xsl")) { return ("Format conversion (*.xsl)"); } if (this.filePath.endsWith(".xml")) { return ("Extended Markup Language (*.xml)"); } if (this.filePath.endsWith(".properties")) { return ("Properties File (*.properties)"); } return (""); } } }