net.sf.filePiper.gui.PiperMainPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of file-piper Show documentation
Show all versions of file-piper Show documentation
This project is a GUI utility for processing files. It allows selecting a set of source files and a pipeline
of processes to apply onto those files. The applications shows in a nice-looking user interface where you can
define profiles for your repetitive tasks.
It provides pre-defined processors doing usual file manipulation tasks like: Copy, Head, Tail, Chunk, Search, Replace, Zip, Unzip...
But the biggest value of this file processor tool is the ability to add easily custom file processors written in java.
The newest version!
package net.sf.filePiper.gui;
import java.awt.Component;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.sf.filePiper.gui.borders.FileProcessorBorder;
import net.sf.filePiper.model.FileProcessor;
import net.sf.filePiper.model.Pipeline;
import net.sf.filePiper.model.ToolModel;
import net.sf.sfac.gui.ExceptionDialog;
import net.sf.sfac.gui.cmp.ConsoleDialog;
import net.sf.sfac.gui.editor.ObjectEditor;
import net.sf.sfac.gui.framework.AboutlHelper;
import net.sf.sfac.gui.framework.ActionRepository;
import net.sf.sfac.gui.framework.SharedResources;
import net.sf.sfac.gui.layout.MultiBorder;
import net.sf.sfac.gui.layout.MultiBorderConstraints;
import net.sf.sfac.gui.layout.MultiBorderLayout;
import net.sf.sfac.setting.ProfilesClient;
import net.sf.sfac.setting.Settings;
import org.apache.log4j.Logger;
public class PiperMainPanel extends JPanel implements ProfilesClient {
private static final String ABOUT_TEXT = "The File Piper
version 1.0
"
+ "
General-purpose file processing tool
"
+ "
by
Olivier Berlanger ";
private static final String ABOUT_LICENSE = "This software is distributed with Apache 2 license.
"
+ "© 2010 Olivier Berlanger
"
+ "
It uses following open-source librarires"
+ "- Commons-logging and log4j from
the Apache Software Foundation"
+ " - The Swing Framework and Components
(SFaC) project
"
+ "See the NOTICE.txt file for more info.";
private static Logger log = Logger.getLogger(PiperMainPanel.class);
private final FileProcessorBorder.Listener BORDER_LISTENER = new FileProcessorBorder.Listener() {
public void addActionPerformed(FileProcessorBorder source) {
addProcessorAt(source);
}
public void removeActionPerformed(FileProcessorBorder source) {
removeProcessor(source);
}
};
ToolModel model;
/** The value of model.getCurrentPipeline().isSourceMultiFile() used to build GUI */
private boolean currentSourceMultiFile;
private PipeEndsEditor endsEditor;
private List processorEditors;
private List borders;
private StatusBar sourceStatus;
private StatusBar destinationStatus;
private List processorStatus;
private GuiPipelineEnvironment guiEnvironment;
private Action processAction;
private Action abortAction;
private Action showConsoleAction;
private ConsoleDialog console;
public PiperMainPanel(ToolModel mainModel, ActionRepository repo) {
super(new MultiBorderLayout());
MultiBorderLayout layout = (MultiBorderLayout) getLayout();
layout.setGlobalInsets(new Insets(8, 15, 8, 15));
model = mainModel;
endsEditor = new PipeEndsEditor(model.getSettings(), this);
endsEditor.edit(model.getPipeline());
processorEditors = new ArrayList();
borders = new ArrayList();
createActions(repo);
buildGui();
model.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
rebuildGui();
}
});
updateActionState(false);
}
public Settings getSettings() {
return model.getSettings();
}
StatusBar getSourceStatus() {
return sourceStatus;
}
StatusBar getDestinationStatus() {
return destinationStatus;
}
List getProcessorStatus() {
return processorStatus;
}
public ConsoleDialog getConsole() {
if (console == null) {
console = new ConsoleDialog(JOptionPane.getFrameForComponent(this), "Console", getSettings());
console.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
console.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent newE) {
setConsoleVisible(false);
}
});
}
return console;
}
public boolean isConsoleVisible() {
if (console == null) return false;
return getConsole().isVisible();
}
public void setConsoleVisible(boolean visible) {
try {
if (visible != isConsoleVisible()) {
getConsole().setVisible(visible);
if (visible != ActionRepository.isActionSelected(showConsoleAction)) {
ActionRepository.setActionSelected(showConsoleAction, visible);
}
}
} catch (Exception e) {
log.error("Unable to show the console", e);
ExceptionDialog.showExceptionDialog(this, "Processing error", "Unable to show the console", e);
}
}
// -------------------------------------------- User actions --------------------------
public void exit() {
log.info("Exit application ...");
try {
updateModel();
getSettings().save();
} catch (Exception e) {
log.error("Cannot save settings in " + getSettings().getPropertyFilePath(), e);
ExceptionDialog.showExceptionDialog(this, "Settings error", "Unable to save settings in file:\n"
+ getSettings().getPropertyFilePath(), e);
}
System.exit(0);
}
void process() {
log.info("Start file processing ...");
try {
updateModel();
// start the file processing
updateActionState(true);
Pipeline pipeline = model.getPipeline();
guiEnvironment = new GuiPipelineEnvironment(pipeline, this);
guiEnvironment.startUpdate();
pipeline.process(guiEnvironment);
} catch (Exception e) {
log.error("Cannot process file(s)", e);
ExceptionDialog.showExceptionDialog(this, "Processing error", "Unable to process file(s)", e);
}
}
void abort() {
log.info("Abort current file processing ...");
try {
if (guiEnvironment != null) guiEnvironment.abortProcessing();
else log.warn("The process cannot be aborted because current GUI environment is null");
} catch (Exception e) {
log.error("The current file processing cannot be aborted", e);
ExceptionDialog.showExceptionDialog(this, "Processing error", "Unable to abort", e);
}
}
void addProcessorAt(FileProcessorBorder source) {
int index = borders.indexOf(source);
log.info("Add processor at " + index);
try {
updateModel();
model.getPipeline().duplicateProcessor(index);
rebuildGui();
} catch (Exception e) {
log.error("Cannot add processor at index " + index, e);
ExceptionDialog.showExceptionDialog(this, "Internal error", "Unable to add processor", e);
}
}
void removeProcessor(FileProcessorBorder source) {
int index = borders.indexOf(source);
log.info("Remove processor at " + index);
try {
updateModel();
model.getPipeline().removeProcessor(index);
rebuildGui();
} catch (Exception e) {
log.error("Cannot remove processor at index " + index, e);
ExceptionDialog.showExceptionDialog(this, "Internal error", "Unable to remove processor", e);
}
}
// -------------------------------------------- Implementation --------------------------
void finished() {
updateActionState(false);
}
void rebuildGui() {
currentSourceMultiFile = model.getPipeline().isSourceMultiFile();
endsEditor.edit(model.getPipeline());
buildGui();
revalidate();
repaint();
}
void updateModel() {
if (log.isDebugEnabled()) log.debug("------ Update tool model");
endsEditor.updateModel();
for (ObjectEditor ed : processorEditors) {
ed.updateModel();
}
}
private void updateView() {
endsEditor.updateView();
for (ObjectEditor ed : processorEditors) {
ed.updateView();
}
}
private void updateActionState(boolean running) {
processAction.setEnabled(!running);
abortAction.setEnabled(running);
endsEditor.setEditable(!running);
for (ObjectEditor ed : processorEditors) {
ed.setEditable(!running);
}
}
private void buildGui() {
removeAll();
MultiBorderConstraints constr = new MultiBorderConstraints();
Insets defaultInsets = new Insets(10, 0, 0, 0);
Insets processorInsets = new Insets(10, 10, 0, 10);
constr.insets = defaultInsets;
constr.gridx = 1;
constr.gridy = MultiBorderConstraints.NEXT;
constr.anchor = MultiBorderConstraints.CENTER;
constr.weightx = 0.6;
constr.fill = MultiBorderConstraints.HORIZONTAL;
MultiBorderConstraints statusConstr = new MultiBorderConstraints(constr);
statusConstr.fill = MultiBorderConstraints.HORIZONTAL;
MultiBorderConstraints spaceConstr = new MultiBorderConstraints(constr);
spaceConstr.weightx = 0.2;
// source
Pipeline pipeline = model.getPipeline();
currentSourceMultiFile = pipeline.isSourceMultiFile();
endsEditor.checkCardinality();
MultiBorder srcBorder = new MultiBorder("Source");
constr.addBorder(srcBorder);
statusConstr.addBorder(srcBorder);
sourceStatus = new StatusBar();
add(endsEditor.getSourcePanel(), constr);
constr.weightx = 0.0;
add(new JLabel(" "), spaceConstr.setConstraints(0, 0));
add(new JLabel(" "), spaceConstr.setConstraints(2, 0));
add(sourceStatus, statusConstr);
constr.removeBorder(srcBorder);
statusConstr.removeBorder(srcBorder);
int fromCardinality = currentSourceMultiFile ? FileProcessor.MANY : FileProcessor.ONE;
int toCardinality = fromCardinality;
// processor
constr.setConstraints(0, MultiBorderConstraints.NEXT, 3, 1);
statusConstr.setConstraints(0, MultiBorderConstraints.NEXT, 3, 1);
List processors = pipeline.getProcessors();
processorStatus = new ArrayList();
processorEditors.clear();
borders.clear();
int len = processors.size();
for (int i = 0; i < len; i++) {
constr.insets = null;
add(getLabel(fromCardinality, toCardinality), constr);
constr.insets = processorInsets;
FileProcessor fp = processors.get(i);
JComboBox combo = createProcessorCombo();
combo.setSelectedItem(model.getPrototype(fp));
combo.addItemListener(new ComboListener(i));
FileProcessorBorder procBorder = new FileProcessorBorder(combo);
borders.add(procBorder);
procBorder.addBorderListsner(BORDER_LISTENER);
constr.addBorder(procBorder);
statusConstr.addBorder(procBorder);
StatusBar bar = new StatusBar();
processorStatus.add(bar);
ObjectEditor ed = fp.getEditor();
ed.edit(fp);
processorEditors.add(ed);
JComponent cmp = ed.getEditorComponent();
cmp.setBorder(null);
add(cmp, constr);
add(bar, statusConstr);
constr.removeBorder(procBorder);
statusConstr.removeBorder(procBorder);
fromCardinality = toCardinality;
toCardinality = fp.getOutputCardinality(fromCardinality);
}
setRemoveProcessButtonEnabled();
// destination
constr.insets = null;
add(getLabel(fromCardinality, toCardinality), constr);
constr.setConstraints(1, MultiBorderConstraints.NEXT, 1, 1);
statusConstr.setConstraints(1, MultiBorderConstraints.NEXT, 1, 1);
constr.insets = defaultInsets;
MultiBorder destBorder = new MultiBorder("Destination");
constr.addBorder(destBorder);
statusConstr.addBorder(destBorder);
destinationStatus = new StatusBar();
add(endsEditor.getDestinationPanel(), constr);
add(destinationStatus, statusConstr);
constr.removeBorder(destBorder);
statusConstr.removeBorder(destBorder);
updateView();
}
public void checkCardinality() {
if (currentSourceMultiFile != model.getPipeline().isSourceMultiFile()) {
rebuildGui();
}
}
private JLabel getLabel(int fromCardinality, int toCardinality) {
JLabel label;
if (fromCardinality == FileProcessor.MANY) {
switch (toCardinality) {
case FileProcessor.NONE:
label = new JLabel(SharedResources.getIcon("manyToNone.png"));
break;
case FileProcessor.ONE:
label = new JLabel(SharedResources.getIcon("manyToOne.png"));
break;
default:
label = new JLabel(SharedResources.getIcon("manyToMany.png"));
break;
}
} else {
switch (toCardinality) {
case FileProcessor.NONE:
label = new JLabel(SharedResources.getIcon("oneToNone.png"));
break;
case FileProcessor.ONE:
label = new JLabel(SharedResources.getIcon("oneToOne.png"));
break;
default:
label = new JLabel(SharedResources.getIcon("oneToMany.png"));
break;
}
}
label.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
return label;
}
private void setRemoveProcessButtonEnabled() {
boolean enabled = borders.size() > 1;
for (FileProcessorBorder border : borders) {
border.setRemoveButtonEnabled(enabled);
}
}
void comboStateChanged(int processorIndex, FileProcessor proto) {
updateModel();
Pipeline pipeline = model.getPipeline();
pipeline.changeProcessorAt(processorIndex, proto);
buildGui();
revalidate();
repaint();
}
private JComboBox createProcessorCombo() {
List availableProcessors = model.getAvailableProcessors();
ComboBoxModel comboModel = new DefaultComboBoxModel(availableProcessors.toArray());
JComboBox combo = new JComboBox(comboModel);
combo.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
String text = (value == null) ? "" : ((FileProcessor) value).getProcessorName();
return super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus);
}
});
return combo;
}
private void createActions(ActionRepository repo) {
// exit
/* exitAction= */repo.addAction("exit", "Exit", "Exit the application", "File", "a/z9", null, null,
new AbstractAction() {
public void actionPerformed(ActionEvent ae) {
exit();
}
});
// process
processAction = repo.addAction("process", "Process", "Process file(s)", "Action", "b/a1", "a1", SharedResources
.getIcon("process.gif"), new AbstractAction() {
public void actionPerformed(ActionEvent ae) {
process();
}
});
// abort
abortAction = repo.addAction("abort", "Abort", "Abort processing", "Action", "b/a2", "a2", SharedResources
.getIcon("abort.gif"), new AbstractAction() {
public void actionPerformed(ActionEvent ae) {
abort();
}
});
// showConsole
showConsoleAction = repo.addAction("showConsole", "Show/Hide Console", "Show/Hide the console", "View", "d/a2", "a3",
SharedResources.getIcon("viewToolBar.png"), new AbstractAction() {
public void actionPerformed(ActionEvent ae) {
boolean visible = ActionRepository.isActionSelected(this);
setConsoleVisible(visible);
}
});
ActionRepository.setToggleAction(showConsoleAction);
ActionRepository.setActionSelected(showConsoleAction, isConsoleVisible());
// about dialog
AboutlHelper about = new AboutlHelper(this);
about.setDirectText("About the File Piper", ABOUT_TEXT, ABOUT_LICENSE);
about.setAboutIcon(SharedResources.getIcon("PiperAbout.png"));
about.createAction(repo);
}
class ComboListener implements ItemListener {
private int processorIndex;
ComboListener(int index) {
processorIndex = index;
}
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
comboStateChanged(processorIndex, (FileProcessor) e.getItem());
}
}
}
// ----------------- ProfileClient interface implementation --------------------------------------------------------------
public Settings getGlobalSettings() {
return model.getSettings();
}
public Settings getCurrentSubSettings() {
updateModel();
return model.getPipelineSettings();
}
public void updateCurrentSubSettings(Settings profile) {
model.updatePipelineSettings(profile);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy