/* * Copyright (C) 2012 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * 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 General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.snap.ui.io; import org.esa.snap.core.dataio.ProductIOPlugInManager; import org.esa.snap.core.dataio.ProductReaderPlugIn; import org.esa.snap.core.util.Guardian; import org.esa.snap.core.util.io.SnapFileFilter; import org.esa.snap.ui.GridBagUtils; import org.esa.snap.ui.SnapFileChooser; import org.esa.snap.ui.UIUtils; import org.esa.snap.ui.tool.ToolButtonFactory; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; /** * An UI-Component which represents a product file list with the ability to add and remove files. */ public class FileArrayEditor { private static final Dimension LIST_PREFERRED_SIZE = new Dimension(500, 200); private JPanel basePanel; private JFileChooser fileDialog; private FileArrayEditorListener listener; private final JList<File> listComponent; private final List<File> fileList; private final EditorParent parent; private final String label; /** * Constructs the object with default values * * @param parent the parent editor * @param label the label for this editor */ public FileArrayEditor(final EditorParent parent, String label) { Guardian.assertNotNullOrEmpty("label", label); this.parent = parent; this.label = label; fileList = new ArrayList<>(); listComponent = new JList<>(); setName(listComponent, this.label); } protected final EditorParent getParent() { return parent; } /** * Retrieves the editor UI. * * @return the editor UI */ public JComponent getUI() { if (basePanel == null) { createUI(); } return basePanel; } /** * Sets the list of files to be edited. The list currently held is overwritten. * * @param files {@code List} of {@code File}s to be set */ public void setFiles(final List<File> files) { Guardian.assertNotNull("files", files); fileList.clear(); fileList.addAll(files); listComponent.setListData(fileList.toArray(new File[fileList.size()])); notifyListener(); } /** * Retrieves the list of files currently edited * * @return a {@code List} of currently edited {@code File}s */ public List<File> getFiles() { return fileList; } /** * Sets the listener for this class * * @param listener the listener to associate with this editor */ public void setListener(final FileArrayEditorListener listener) { this.listener = listener; } /////////////////////////////////////////////////////////////////////////// ////// END OF PUBLIC /////////////////////////////////////////////////////////////////////////// /** * Creates the user interface */ private void createUI() { // the label final JLabel label = new JLabel(this.label + ":"); setName(label, this.label); // the list JComponent scrollPane = createFileArrayComponent(); // the add button final JButton addButton = createAddFileButton(); // the remove button final JButton removeButton = createRemoveFileButton(); // the button panel final JPanel buttonPanel = new JPanel(); setName(buttonPanel, this.label); buttonPanel.add(addButton); buttonPanel.add(removeButton); // the base panel basePanel = GridBagUtils.createDefaultEmptyBorderPanel(); setName(basePanel, this.label); final GridBagConstraints gbc = GridBagUtils.createConstraints(null); gbc.anchor = GridBagConstraints.WEST; gbc.weightx = 1; gbc.gridy++; basePanel.add(label, gbc); gbc.anchor = GridBagConstraints.EAST; basePanel.add(buttonPanel, gbc); gbc.gridy++; gbc.anchor = GridBagConstraints.WEST; gbc.gridwidth = 2; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.weighty = 1; basePanel.add(scrollPane, gbc); } public JButton createRemoveFileButton() { final JButton removeButton = (JButton) ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/Minus16.gif"), false); setName(removeButton, "removeButton"); removeButton.addActionListener(e -> onRemoveButton()); return removeButton; } public JButton createAddFileButton() { final JButton addButton = (JButton) ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/Plus16.gif"), false); setName(addButton, "addButton"); addButton.addActionListener(e -> onAddButton()); return addButton; } public JComponent createFileArrayComponent() { JScrollPane scrollPane = new JScrollPane(listComponent); setName(scrollPane, label); scrollPane.setPreferredSize(LIST_PREFERRED_SIZE); return scrollPane; } private void setName(final Component comp, String name) { comp.setName(name); } /* * Callback invoked by the add button */ private void onAddButton() { fileDialog = getFileDialogSafe(); final File userInputDir = parent.getUserInputDir(); final int retVal; fileDialog.setCurrentDirectory(userInputDir); retVal = fileDialog.showOpenDialog(basePanel); if (retVal == JFileChooser.APPROVE_OPTION) { File[] selected = fileDialog.getSelectedFiles(); fileList.addAll(Arrays.asList(selected)); listComponent.setListData(fileList.toArray(new File[fileList.size()])); notifyListener(); parent.setUserInputDir(fileDialog.getCurrentDirectory()); } } /* * Callback invoked by the remove button */ private void onRemoveButton() { final List<File> selectedFiles = listComponent.getSelectedValuesList(); selectedFiles.forEach(fileList::remove); listComponent.setListData(fileList.toArray(new File[fileList.size()])); notifyListener(); } /* * Retrieves the file chooser object. If none is present, an object is constructed */ private JFileChooser getFileDialogSafe() { if (fileDialog == null) { fileDialog = createFileChooserDialog(); } return fileDialog; } protected JFileChooser createFileChooserDialog() { final JFileChooser chooser = new SnapFileChooser(); chooser.setAcceptAllFileFilterUsed(true); chooser.setMultiSelectionEnabled(true); final Iterator<ProductReaderPlugIn> iterator = ProductIOPlugInManager.getInstance().getAllReaderPlugIns(); List<SnapFileFilter> sortedFileFilters = SnapFileFilter.getSortedFileFilters(iterator); sortedFileFilters.forEach(chooser::addChoosableFileFilter); chooser.setFileFilter(chooser.getAcceptAllFileFilter()); return chooser; } /* * Calls the listener about changes - if necessary */ private void notifyListener() { if ((listener != null)) { listener.updatedList(fileList.toArray(new File[fileList.size()])); } } public interface EditorParent { File getUserInputDir(); void setUserInputDir(File newDir); } public interface FileArrayEditorListener { void updatedList(File[] files); } }