/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.framework.uitools; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileFilter; import org.eclipse.persistence.tools.workbench.framework.context.ApplicationContext; import org.eclipse.persistence.tools.workbench.framework.ui.view.AbstractPanel; import org.eclipse.persistence.tools.workbench.uitools.app.PropertyValueModel; import org.eclipse.persistence.tools.workbench.uitools.app.swing.DocumentAdapter; /** * a panel with a labeled entry field and a Browse button that opens * a file chooser */ public class FileChooserPanel extends AbstractPanel { /** the value must be a String */ private PropertyValueModel filePathHolder; /** used by the file chooser when selecting a relative file path */ private FileHolder fileChooserRootFileHolder; /** used by the file chooser to filter files */ private FileFilter fileChooserFileFilter; /** used by the file chooser as a starting point */ private FileHolder fileChooserDefaultDirectoryHolder; private static final long serialVersionUID = 1L; // **************** Constructors / Initialization ************************* public FileChooserPanel(ApplicationContext context, PropertyValueModel filePathHolder, String labelKey) { this(context, filePathHolder, labelKey, null, JFileChooser.FILES_ONLY, false); } public FileChooserPanel(ApplicationContext context, PropertyValueModel filePathHolder, String labelKey, boolean topAlignment) { this(context, filePathHolder, labelKey, null, JFileChooser.FILES_ONLY, topAlignment); } public FileChooserPanel(ApplicationContext context, PropertyValueModel filePathHolder, String labelKey, String browseButtonKey) { this(context, filePathHolder, labelKey, browseButtonKey, JFileChooser.FILES_ONLY, false); } public FileChooserPanel(ApplicationContext context, PropertyValueModel filePathHolder, String labelKey, String browseButtonKey, boolean topAlignment) { this(context, filePathHolder, labelKey, browseButtonKey, JFileChooser.FILES_ONLY, topAlignment); } /** * fileSelectionMode options: * JFileChooser.FILES_ONLY * JFileChooser.DIRECTORIES_ONLY * JFileChooser.FILES_AND_DIRECTORIES * * @see JFileChooser.#setFileSelectionMode */ public FileChooserPanel(ApplicationContext context, PropertyValueModel filePathHolder, String labelKey, int fileSelectionMode) { this(context, filePathHolder, labelKey, null, fileSelectionMode); } public FileChooserPanel(ApplicationContext context, PropertyValueModel filePathHolder, String labelKey, int fileSelectionMode, boolean topAlignment) { this(context, filePathHolder, labelKey, null, fileSelectionMode, topAlignment); } public FileChooserPanel(ApplicationContext context, PropertyValueModel filePathHolder, String labelKey, String browseButtonKey, int fileSelectionMode) { this(context, filePathHolder, labelKey, null, fileSelectionMode, false); } public FileChooserPanel(ApplicationContext context, PropertyValueModel filePathHolder, String labelKey, String browseButtonKey, int fileSelectionMode, boolean topAlignment) { super(context); this.filePathHolder = filePathHolder; this.fileChooserRootFileHolder = new SimpleFileHolder(); this.fileChooserDefaultDirectoryHolder = new SimpleFileHolder(); this.initialize(labelKey, browseButtonKey, fileSelectionMode, topAlignment); } private void initialize(String labelKey, String browseButtonKey, int fileSelectionMode, boolean topAlignment) { GridBagConstraints constraints = new GridBagConstraints(); boolean labelVisible = labelVisible(); // File label JLabel fileLabel = this.buildLabel(labelKey); fileLabel.setVisible(labelVisible); constraints.gridx = 0; constraints.gridy = 0; constraints.gridwidth = topAlignment ? 2 : 1; constraints.gridheight = 1; constraints.weightx = 0; constraints.weighty = 0; constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.LINE_START; constraints.insets = new Insets(0, 0, 0, 0); this.add(fileLabel, constraints); this.addAlignLeft(fileLabel); // File text field JTextField fileTextField = new JTextField(new DocumentAdapter(this.filePathHolder), null, 1); constraints.gridx = topAlignment ? 0 : 1; constraints.gridy = topAlignment ? 1 : 0; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 1; constraints.weighty = 0; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.CENTER; constraints.insets = new Insets(topAlignment ? 1 : 0, topAlignment ? 0 : labelVisible ? 5 : 0, 0, 0); this.add(fileTextField, constraints); fileLabel.setLabelFor(fileTextField); // File chooser button JButton fileChooserButton = this.buildFileChooserButton(browseButtonKey, fileSelectionMode); SwingComponentFactory.updateButtonAccessibleName(fileLabel, fileChooserButton); constraints.gridx = topAlignment ? 1 : 2; constraints.gridy = topAlignment ? 1 : 0; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 0; constraints.weighty = 0; constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.CENTER; constraints.insets = new Insets(topAlignment ? 1 : 0, 5, 0, 0); this.add(fileChooserButton, constraints); this.addAlignRight(fileChooserButton); } protected JButton buildFileChooserButton(String browseButtonKey, int fileSelectionMode) { String buttonText = (browseButtonKey != null) ? browseButtonKey : this.browseButtonKey(); JButton fileChooserButton = this.buildButton(buttonText); fileChooserButton.addActionListener(this.buildFileActionListener(fileSelectionMode)); return fileChooserButton; } protected String browseButtonKey() { return "FILE_CHOOSER_PANEL.BROWSE_BUTTON_TEXT"; } protected boolean labelVisible() { return true; } private ActionListener buildFileActionListener(final int fileSelectionMode) { return new ActionListener() { public void actionPerformed(ActionEvent e) { FileChooserPanel.this.promptForFile(fileSelectionMode); } }; } // ********** public API ********** public void setEnabled(boolean enabled) { super.setEnabled(enabled); Component[] components = this.getComponents(); for (int i = 0; i < components.length; i++) { components[i].setEnabled(enabled); } } public void requestFocus() { this.getComponent(1).requestFocus(); // 1 for the text field } /** * used for file chooser relative path; * this can be a read-only file holder - we won't try to write to it */ public void setFileChooserRootFileHolder(FileHolder fileChooserRootFileHolder) { if (fileChooserRootFileHolder == null) { throw new NullPointerException(); } this.fileChooserRootFileHolder = fileChooserRootFileHolder; } public void setFileChooserFileFilter(FileFilter fileChooserFileFilter) { this.fileChooserFileFilter = fileChooserFileFilter; } public void setFileChooserDefaultDirectoryHolder(FileHolder fileChooserDefaultDirectoryHolder) { if (fileChooserDefaultDirectoryHolder == null) { throw new NullPointerException(); } this.fileChooserDefaultDirectoryHolder = fileChooserDefaultDirectoryHolder; } // ********** internal methods ********** private String getFilePath() { return (String) this.filePathHolder.getValue(); } protected File getFileChooserDefaultDirectory() { return this.fileChooserDefaultDirectoryHolder.getFile(); } private void setFileChooserDefaultDirectory(File directory) { this.fileChooserDefaultDirectoryHolder.setFile(directory); } private File getFile() { String filePath = this.getFilePath(); if ((filePath == null) || (filePath.length() == 0)) { return null; } return new File(filePath); } private void setFilePath(String filePath) { this.filePathHolder.setValue(filePath); } void promptForFile(int fileSelectionMode) { Window window = SwingUtilities.getWindowAncestor(this); File file = this.getFile(); FileChooser fileChooser = new FileChooser(this.getFileChooserDefaultDirectory(), this.fileChooserRootFileHolder.getFile()); fileChooser.setFileSelectionMode(fileSelectionMode); fileChooser.setSelectedFile(file); fileChooser.setMultiSelectionEnabled(false); fileChooser.setFileFilter(this.fileChooserFileFilter); if (fileChooser.showOpenDialog(window) == JFileChooser.APPROVE_OPTION) { this.setFilePath(fileChooser.getSelectedFile().getPath()); this.setFileChooserDefaultDirectory(fileChooser.getCurrentDirectory()); } } // ********** client-implemented interface ********** /** * Used to indirectly reference a File, * typically retrieved from the node currently associated with * a properties page (since the node can change over time). */ public interface FileHolder { /** * Return the current file. */ File getFile(); /** * Set the current file. * This operation is optional. */ void setFile(File file); } public class SimpleFileHolder implements FileHolder { private File file; public File getFile() { return this.file; } public void setFile(File file) { this.file = file; } } }