All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bidib.wizard.dialog.FileDialog Maven / Gradle / Ivy

There is a newer version: 2.0.0-M1
Show newest version
package org.bidib.wizard.dialog;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.io.File;

import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;

import org.bidib.wizard.locale.Resources;
import org.bidib.wizard.mvc.preferences.model.Preferences;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class FileDialog {
    private static final Logger LOGGER = LoggerFactory.getLogger(FileDialog.class);

    public static final int OPEN = JFileChooser.OPEN_DIALOG;

    public static final int SAVE = JFileChooser.SAVE_DIALOG;

    private static File workingDirectory;

    private final JFileChooser fileChooser;

    private final JPanel fillPanel;

    private String approveButtonText;

    private Component parent;

    protected final int dialogType;

    static {
        String storedWorkingDirectory = Preferences.getInstance().getWorkingDirectory();

        if (storedWorkingDirectory != null) {
            workingDirectory = new File(storedWorkingDirectory);
        }
    }

    public FileDialog(Component parent, int dialogType, String fileName, FileFilter filter) {
        this.parent = parent;
        this.dialogType = dialogType;
        fillPanel = new JPanel();
        fileChooser = new JFileChooser() {
            private static final long serialVersionUID = 1L;

            @Override
            protected JDialog createDialog(Component parent) throws HeadlessException {
                JDialog dialog = super.createDialog(parent);

                // on windows system adjust the position of the additional panel
                if ("com.sun.java.swing.plaf.windows.WindowsFileChooserUI".equals(fileChooser
                    .getUI().getClass().getName())) {
                    LOGGER.debug("We have the windows filechooser.");
                    try {
                        Container container = (Container) dialog.getContentPane().getComponent(0);
                        for (Component comp : container.getComponents()) {
                            if ("sun.swing.WindowsPlacesBar".equals(comp.getClass().getName())) {
                                int width = comp.getWidth() + 5;
                                LOGGER.debug("width of placesBar: {}", width);

                                fillPanel.setSize(width, 1);
                                fillPanel.setPreferredSize(new Dimension(width, 1));
                                break;
                            }
                        }
                    }
                    catch (Exception ex) {
                        LOGGER.warn("Adjust width of fillerPanel failed.", ex);
                    }
                }
                return dialog;
            }
        };
        fileChooser.setAcceptAllFileFilterUsed(false);
        fileChooser.setCurrentDirectory(workingDirectory);
        fileChooser.setDialogType(dialogType);
        if (filter != null) {
            fileChooser.setFileFilter(filter);
        }
        else {
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        }
        fileChooser.setMultiSelectionEnabled(false);
        Component additionalPanel = getAdditionalPanel();
        if (additionalPanel != null) {
            LOGGER.info("Adding additional data panel to south: {}", additionalPanel);
            LOGGER.info("Current filechooser UI: {}", fileChooser.getUI().getClass().getName());
            if ("com.sun.java.swing.plaf.windows.WindowsFileChooserUI".equals(fileChooser.getUI().getClass().getName())) {
                LOGGER
                    .info("We have the windows filechooser and will try to adjust the position of the additional panel.");

                JPanel southPanel = new JPanel(new BorderLayout());
                southPanel.add(additionalPanel, BorderLayout.CENTER);
                southPanel.add(fillPanel, BorderLayout.WEST);

                additionalPanel = southPanel;

                fileChooser.add(additionalPanel, BorderLayout.SOUTH);
            }
            else if (fileChooser.getLayout() instanceof BorderLayout) {
                LOGGER.info("The layout of the current filechooser is borderlayout.");

                JPanel southPanel = new JPanel(new BorderLayout());
                southPanel.add(additionalPanel, BorderLayout.CENTER);

                LOGGER.info("FileChooserUI with Borderlayout detected.");

                try {
                    BorderLayout layout = (BorderLayout) fileChooser.getLayout();
                    Component originalSouthPanel = layout.getLayoutComponent(BorderLayout.SOUTH);

                    LOGGER.info("Original south panel: {}", originalSouthPanel);
                    southPanel.add(originalSouthPanel, BorderLayout.SOUTH);

                    additionalPanel = southPanel;

                    fileChooser.add(additionalPanel, BorderLayout.SOUTH);
                }
                catch (Exception ex) {
                    LOGGER.warn("Get the original south panel failed.", ex);
                }
            }
        }
        if (fileName != null) {
            fileChooser.setSelectedFile(new File(workingDirectory, fileName));
        }
    }

    /**
     * Show the file dialog.
     */
    public void showDialog() {
        boolean retry;
        do {
            retry = false;
            try {
                if (fileChooser.showDialog(JOptionPane.getFrameForComponent(parent), approveButtonText) == JFileChooser.APPROVE_OPTION) {

                    checkValidFilename(fileChooser.getSelectedFile());

                    if (fileChooser.getDialogType() == FileDialog.SAVE) {

                        if (!checkOverrideExisting(fileChooser.getSelectedFile())) {
                            LOGGER.info("User canceled override existing file.");
                            return;
                        }
                    }

                    setWorkingDirectory(fileChooser.getCurrentDirectory());
                    approve(fileChooser.getSelectedFile().toString());
                }
            }
            catch (RuntimeException ex) {
                LOGGER.warn("Approve failed.", ex);
                JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(parent), ex.getMessage(),
                    Resources.getString(FileDialog.class, "open"), JOptionPane.ERROR_MESSAGE);
                retry = true;
            }
        }
        while (retry);
    }

    private void checkValidFilename(File file) {
        try {
            file.getCanonicalPath();
        }
        catch (Exception ex) {
            LOGGER.warn("File is not writeable.", ex);
            throw new IllegalArgumentException(ex.getLocalizedMessage());
        }
    }

    /**
     * Check if the existing file should be overwritten
     * 
     * @param file
     *            the existing file
     * @return true: override, false: do not override
     */
    protected boolean checkOverrideExisting(File file) {
        if (file.exists()) {
            // ask the user if override is allowed

            int result =
                JOptionPane.showConfirmDialog(JOptionPane.getFrameForComponent(parent),
                    Resources.getString(FileDialog.class, "override_existing_file", new Object[] { file.getName() }),
                    Resources.getString(FileDialog.class, "save_file"), JOptionPane.OK_CANCEL_OPTION);
            if (result != JOptionPane.OK_OPTION) {
                LOGGER.info("User canceled override existing file.");
                return false;
            }
            return true;
        }
        return true;
    }

    public void updateFileFilter(FileFilter filter, String fileName) {
        updateFileFilter(new FileFilter[] { filter }, fileName);
    }

    public void updateFileFilter(FileFilter[] filters, String fileName) {
        fileChooser.removeChoosableFileFilter(fileChooser.getFileFilter());

        if (filters != null) {
            for (FileFilter filter : filters) {
                fileChooser.addChoosableFileFilter(filter);
            }

            fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        }
        else {
            fileChooser.setFileFilter(null);
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        }

        if (fileName != null) {
            LOGGER.info("Set selected fileName: {}", fileName);
            fileChooser.setSelectedFile(new File(workingDirectory, fileName));
        }
    }

    /**
     * @return the addtional panel that will be added to the south of the filechooser dialog
     */
    protected Component getAdditionalPanel() {
        return null;
    }

    public abstract void approve(String fileName);

    private void setWorkingDirectory(File newWorkingDirectory) {
        workingDirectory = newWorkingDirectory;

        Preferences preferences = Preferences.getInstance();

        if (!workingDirectory.toString().equals(preferences.getWorkingDirectory())) {
            preferences.setWorkingDirectory(workingDirectory.toString());
            preferences.save(null);
        }
    }

    /**
     * @return the approveButtonText
     */
    public String getApproveButtonText() {
        return approveButtonText;
    }

    /**
     * @param approveButtonText
     *            the approveButtonText to set
     */
    public void setApproveButtonText(String approveButtonText) {
        this.approveButtonText = approveButtonText;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy