/* DelegatingFilterDialog.java created 2008-03-04
*
*/
package org.signalml.app.view.book.filter;
import static org.signalml.app.util.i18n.SvarogI18n._;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.signalml.app.model.components.validation.ValidationErrors;
import org.signalml.app.util.IconUtils;
import org.signalml.app.util.SwingUtils;
import org.signalml.app.view.common.components.cellrenderers.FileListCellRenderer;
import org.signalml.domain.book.filter.DelegatingAtomFilter;
import org.signalml.plugin.export.SignalMLException;
import org.signalml.plugin.export.view.FileChooser;
import org.signalml.util.Util;
/** DelegatingFilterDialog
*
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
public class DelegatingFilterDialog extends AbstractFilterDialog {
private static final long serialVersionUID = 1L;
private FileChooser fileChooser;
private DefaultListModel classPathListModel;
private JList classPathList;
private JScrollPane classPathScrollPane;
private JTextField fqClassNameTextField;
private QuickFileAction quickFileAction;
private AddDirectoryEntryAction addDirectoryEntryAction;
private AddJarEntryAction addJarEntryAction;
private RemoveEntryAction removeEntryAction;
private JButton quickFileButton;
private JButton addDirectoryEntryButton;
private JButton addJarEntryButton;
private JButton removeEntryButton;
public DelegatingFilterDialog(Window w, boolean isModal) {
super(w, isModal);
}
@Override
protected void initialize() {
setTitle(_("Custom atom filter"));
setIconImage(IconUtils.loadClassPathImage("org/signalml/app/icon/filter.png"));
quickFileAction = new QuickFileAction();
addDirectoryEntryAction = new AddDirectoryEntryAction();
addJarEntryAction = new AddJarEntryAction();
removeEntryAction = new RemoveEntryAction();
super.initialize();
setResizable(false);
}
@Override
public JComponent createInterface() {
JPanel classPathPanel = new JPanel(new BorderLayout(5,5));
classPathPanel.setBorder(new CompoundBorder(
new TitledBorder(_("Choose class path")),
new EmptyBorder(3,3,3,3)
));
JPanel rightPanel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel(new GridLayout(3,1,3,3));
SwingUtils.makeButtonsSameSize(new JButton[] { getQuickFileButton(), getAddDirectoryEntryButton(), getAddJarEntryButton(), getRemoveEntryButton() });
buttonPanel.add(getAddDirectoryEntryButton());
buttonPanel.add(getAddJarEntryButton());
buttonPanel.add(getRemoveEntryButton());
rightPanel.add(buttonPanel, BorderLayout.NORTH);
rightPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER);
classPathPanel.add(getClassPathScrollPane(), BorderLayout.CENTER);
classPathPanel.add(rightPanel, BorderLayout.EAST);
JPanel fqClassNamePanel = new JPanel(new BorderLayout(5,5));
fqClassNamePanel.setBorder(new CompoundBorder(
new TitledBorder(_("Choose fully qualified filter class name")),
new EmptyBorder(3,3,3,3)
));
fqClassNamePanel.add(getFqClassNameTextField(), BorderLayout.CENTER);
fqClassNamePanel.add(getQuickFileButton(), BorderLayout.EAST);
JPanel interfacePanel = new JPanel(new BorderLayout());
interfacePanel.add(getNamePanel(), BorderLayout.NORTH);
interfacePanel.add(classPathPanel, BorderLayout.CENTER);
interfacePanel.add(fqClassNamePanel, BorderLayout.SOUTH);
return interfacePanel;
}
public DefaultListModel getClassPathListModel() {
if (classPathListModel == null) {
classPathListModel = new DefaultListModel();
}
return classPathListModel;
}
public JList getClassPathList() {
if (classPathList == null) {
classPathList = new JList(getClassPathListModel());
classPathList.setCellRenderer(new FileListCellRenderer());
classPathList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
classPathList.setFont(classPathList.getFont().deriveFont(Font.PLAIN, 12));
classPathList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
removeEntryAction.setEnabled(classPathList.getSelectedIndex() >= 0);
}
});
}
return classPathList;
}
public JScrollPane getClassPathScrollPane() {
if (classPathScrollPane == null) {
classPathScrollPane = new JScrollPane(getClassPathList());
classPathScrollPane.setPreferredSize(new Dimension(400,300));
}
return classPathScrollPane;
}
public JTextField getFqClassNameTextField() {
if (fqClassNameTextField == null) {
fqClassNameTextField = new JTextField();
fqClassNameTextField.setPreferredSize(new Dimension(400,25));
}
return fqClassNameTextField;
}
public JButton getQuickFileButton() {
if (quickFileButton == null) {
quickFileButton = new JButton(quickFileAction);
}
return quickFileButton;
}
public JButton getAddDirectoryEntryButton() {
if (addDirectoryEntryButton == null) {
addDirectoryEntryButton = new JButton(addDirectoryEntryAction);
}
return addDirectoryEntryButton;
}
public JButton getAddJarEntryButton() {
if (addJarEntryButton == null) {
addJarEntryButton = new JButton(addJarEntryAction);
}
return addJarEntryButton;
}
public JButton getRemoveEntryButton() {
if (removeEntryButton == null) {
removeEntryButton = new JButton(removeEntryAction);
}
return removeEntryButton;
}
@Override
public void fillDialogFromModel(Object model) throws SignalMLException {
DelegatingAtomFilter filter = (DelegatingAtomFilter) model;
super.fillDialogFromFilter(filter);
ArrayList<File> classPath = filter.getClassPath();
DefaultListModel listModel = getClassPathListModel();
listModel.clear();
for (File file : classPath) {
listModel.addElement(file);
}
getFqClassNameTextField().setText(filter.getFqClassName());
}
@Override
public void fillModelFromDialog(Object model) throws SignalMLException {
DelegatingAtomFilter filter = (DelegatingAtomFilter) model;
super.fillFilterFromDialog(filter);
fillFilterFromDialog(filter);
filter.initialize();
}
protected void fillFilterFromDialog(DelegatingAtomFilter filter) {
DefaultListModel listModel = getClassPathListModel();
int cnt = listModel.size();
ArrayList<File> classPath = new ArrayList<File>(cnt);
for (int i=0; i<cnt; i++) {
classPath.add((File) listModel.getElementAt(i));
}
filter.setClassPath(classPath);
filter.setFqClassName(getFqClassNameTextField().getText());
}
@Override
public void validateDialog(Object model, ValidationErrors errors) throws SignalMLException {
super.validateDialog(model, errors);
if (getClassPathListModel().size() == 0) {
errors.addError(_("At least one class path entry is required"));
}
String fqClassName = getFqClassNameTextField().getText();
if (fqClassName == null || fqClassName.isEmpty()) {
errors.addError(_("Fully qualified class name is required"));
} else {
fqClassName.trim();
getFqClassNameTextField().setText(fqClassName);
if (!Util.validateFqClassName(fqClassName)) {
errors.addError(_("Invalid fully qualified class name"));
}
}
if (!errors.hasErrors()) {
DelegatingAtomFilter filter = new DelegatingAtomFilter();
fillFilterFromDialog(filter);
try {
filter.initialize();
} catch (Throwable t) {
logger.error("Filter failed to initialize", t);
errors.addError(_("Failed to initialize filter. See log file for details."));
}
}
}
@Override
public boolean supportsModelClass(Class<?> clazz) {
return DelegatingAtomFilter.class.isAssignableFrom(clazz);
}
public FileChooser getFileChooser() {
return fileChooser;
}
public void setFileChooser(FileChooser fileChooser) {
this.fileChooser = fileChooser;
}
protected class QuickFileAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public QuickFileAction() {
super(_("Quick file"));
putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/find.png"));
putValue(AbstractAction.SHORT_DESCRIPTION, _("Select a single java or class file. Contained class must be in default package"));
}
public void actionPerformed(ActionEvent ev) {
File file = fileChooser.chooseCodeFile(DelegatingFilterDialog.this.getRootPane());
if (file == null) {
return;
}
String name = file.getName();
int lastDot = name.lastIndexOf('.');
if (lastDot >= 0) {
name = name.substring(0, lastDot);
}
getFqClassNameTextField().setText(name);
DefaultListModel listModel = getClassPathListModel();
listModel.clear();
File parent = file.getParentFile();
if (parent != null) {
listModel.addElement(parent);
}
}
}
protected class AddDirectoryEntryAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public AddDirectoryEntryAction() {
super(_("Add directories"));
putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/adddirectoryentry.png"));
}
public void actionPerformed(ActionEvent ev) {
File[] files = fileChooser.chooseClassPathDirectories(DelegatingFilterDialog.this.getRootPane());
if (files == null) {
return;
}
DefaultListModel listModel = getClassPathListModel();
for (File file : files) {
listModel.addElement(file);
}
}
}
protected class AddJarEntryAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public AddJarEntryAction() {
super(_("Add jar files"));
putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/addjarentry.png"));
}
public void actionPerformed(ActionEvent ev) {
File[] files = fileChooser.chooseJarFiles(DelegatingFilterDialog.this.getRootPane());
if (files == null) {
return;
}
DefaultListModel listModel = getClassPathListModel();
for (File file : files) {
listModel.addElement(file);
}
}
}
protected class RemoveEntryAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public RemoveEntryAction() {
super(_("Remove"));
putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/removeentry.png"));
setEnabled(false);
}
public void actionPerformed(ActionEvent ev) {
JList list = getClassPathList();
int selectedIndex = list.getSelectedIndex();
if (selectedIndex < 0) {
return;
}
DefaultListModel listModel = getClassPathListModel();
listModel.remove(selectedIndex);
int size = listModel.size();
if (size > 0) {
if (selectedIndex >= size) {
selectedIndex--;
}
list.setSelectedIndex(selectedIndex);
}
}
}
}