/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.libraries.designtime.swing.filechooser; import javax.swing.*; import javax.swing.filechooser.FileFilter; import java.awt.*; import java.io.File; public class SwingFileChooserService implements CommonFileChooser { private static class FileSelectionTask implements Runnable { private FileFilter[] filters; private Component parent; private int mode; private int retval; private File[] selectedFiles; private boolean allowMultiSelection; private File currentDirectory; private FileSelectionTask( final Component parent, final int mode, final FileFilter[] filters, final File[] selectedFiles, final File currentDirectory, final boolean allowMultiSelection ) { this.parent = parent; this.mode = mode; this.filters = filters; this.selectedFiles = selectedFiles; this.currentDirectory = currentDirectory; this.allowMultiSelection = allowMultiSelection; } public int getRetval() { return retval; } public File[] getSelectedFiles() { return selectedFiles; } /** * When an object implementing interface <code>Runnable</code> is used to create a thread, starting the thread * causes the object's <code>run</code> method to be called in that separately executing thread. * <p/> * The general contract of the method <code>run</code> is that it may take any action whatsoever. * * @see Thread#run() */ public void run() { if ( fileChooser == null ) { fileChooser = new JFileChooser(); } fileChooser.setMultiSelectionEnabled( allowMultiSelection ); fileChooser.setCurrentDirectory( currentDirectory ); fileChooser.setSelectedFiles( selectedFiles ); fileChooser.updateUI(); fileChooser.resetChoosableFileFilters(); for ( int i = 0; i < filters.length; i++ ) { fileChooser.addChoosableFileFilter( filters[ i ] ); } if ( mode == JFileChooser.OPEN_DIALOG ) { retval = fileChooser.showOpenDialog( parent ); } else { retval = fileChooser.showSaveDialog( parent ); } if ( retval == JFileChooser.APPROVE_OPTION ) { if ( fileChooser.isMultiSelectionEnabled() ) { selectedFiles = fileChooser.getSelectedFiles(); } else { selectedFiles = new File[] { fileChooser.getSelectedFile() }; } } else { selectedFiles = EMPTY_FILES; } } } protected static final File[] EMPTY_FILES = new File[ 0 ]; protected static final FileFilter[] EMPTY_FILEFILTER = new FileFilter[ 0 ]; protected static final Object lock = new Object(); private static JFileChooser fileChooser; private String fileType; private File[] selectedFiles; private boolean allowMultiSelection; private FileFilter[] filters; public SwingFileChooserService( final String fileType ) { this.fileType = fileType; this.selectedFiles = EMPTY_FILES; this.filters = EMPTY_FILEFILTER; } public String getFileType() { return fileType; } public File[] getSelectedFiles() { return selectedFiles.clone(); } public File getSelectedFile() { if ( selectedFiles.length == 0 ) { return null; } return selectedFiles[ 0 ]; } public void setSelectedFile( final File selectedFile ) { if ( selectedFile == null ) { this.selectedFiles = EMPTY_FILES; } else { this.selectedFiles = new File[] { selectedFile }; } } public void setSelectedFiles( final File[] selectedFiles ) { this.selectedFiles = selectedFiles.clone(); } public boolean isAllowMultiSelection() { return allowMultiSelection; } public void setAllowMultiSelection( final boolean allowMultiSelection ) { this.allowMultiSelection = allowMultiSelection; } public FileFilter[] getFilters() { return filters.clone(); } public void setFilters( final FileFilter[] filters ) { this.filters = filters.clone(); } public boolean showDialog( final Component parent, final int mode ) { File currentDirectory = null; if ( selectedFiles.length == 0 ) { if ( FileChooserService.getInstance().isStoreLocations( getFileType() ) ) { final File lastLocation = FileChooserService.getInstance().getLastLocation( getFileType() ); if ( lastLocation != null ) { if ( lastLocation.isDirectory() ) { currentDirectory = lastLocation; setSelectedFile( null ); } else { currentDirectory = lastLocation.getParentFile(); setSelectedFile( lastLocation ); } } } else { final File staticLocation = FileChooserService.getInstance().getStaticLocation( getFileType() ); if ( staticLocation != null ) { if ( staticLocation.isDirectory() ) { currentDirectory = staticLocation; setSelectedFile( null ); } else { currentDirectory = staticLocation.getParentFile(); setSelectedFile( staticLocation ); } } } } final FileSelectionTask task = new FileSelectionTask ( parent, mode, getFilters(), getSelectedFiles(), currentDirectory, isAllowMultiSelection() ); if ( SwingUtilities.isEventDispatchThread() ) { task.run(); } else { try { SwingUtilities.invokeAndWait( task ); } catch ( Exception e ) { return false; } } if ( task.getRetval() == JFileChooser.APPROVE_OPTION ) { selectedFiles = task.getSelectedFiles(); final File selectedFile = getSelectedFile(); if ( selectedFile != null && FileChooserService.getInstance().isStoreLocations( getFileType() ) ) { FileChooserService.getInstance().setLastLocation( getFileType(), selectedFile ); } return true; } else { return false; } } }