se.trixon.toolbox.relocator.RelocatorTopComponent.java Source code

Java tutorial

Introduction

Here is the source code for se.trixon.toolbox.relocator.RelocatorTopComponent.java

Source

/* 
 * Copyright 2015 Patrik Karlsson.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package se.trixon.toolbox.relocator;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFileChooser;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.windows.*;
import se.trixon.almond.SwingHelper;
import se.trixon.almond.dialogs.FileChooserPanel;
import se.trixon.almond.dialogs.Message;
import se.trixon.almond.dictionary.Dict;
import se.trixon.almond.icon.Pict;
import se.trixon.toolbox.core.Toolbox;
import se.trixon.toolbox.core.base.ToolTopComponent;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(dtd = "-//se.trixon.toolbox.relocator//Relocator//EN", autostore = false)
@TopComponent.Description(preferredID = "RelocatorTopComponent",
        //iconBase="SET/PATH/TO/ICON/HERE",
        persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = false)
public final class RelocatorTopComponent extends ToolTopComponent
        implements FileChooserPanel.FileChooserButtonListener, OperationListener {

    private static final int ICON_SIZE = TOOLBAR_ICON_SIZE;
    private final RelocatorController mController;
    private final Options mOptions = Options.INSTANCE;

    public RelocatorTopComponent() {
        mBundle = NbBundle.getBundle(RelocatorTopComponent.class);
        mToolName = mBundle.getString("Tool-Name");
        initComponents();
        setName(mToolName);
        mController = new RelocatorController(this);
        init();
    }

    @Override
    public HelpCtx getHelpCtx() {
        return new HelpCtx(mHelpId);
    }

    @Override
    public void onOperationFailed(String message) {
    }

    @Override
    public void onOperationFinished(String message) {
        SwingHelper.enableComponents(this, true);
        followLinksCheckBox.setEnabled(!SystemUtils.IS_OS_WINDOWS);
        makeBusy(false);
        new Thread(() -> {
            Message.information(Dict.OPERATION_COMPLETED.getString(), message);
        }).start();
    }

    @Override
    public void onOperationInterrupted() {
        SwingHelper.enableComponents(this, true);
        followLinksCheckBox.setEnabled(!SystemUtils.IS_OS_WINDOWS);
        makeBusy(false);
    }

    @Override
    public void onOperationLog(String message) {
        appendLog(message);
    }

    @Override
    public void onOperationStarted() {
        SwingHelper.enableComponents(this, false);
        helpButton.setEnabled(true);
        makeBusy(true);
    }

    @Override
    public void onOperationProcessingStarted() {
    }

    private void init() {
        mHelpId = "se.trixon.toolbox.relocator.about";

        startButton.setIcon(Pict.Actions.ARROW_RIGHT.get(ICON_SIZE));
        startButton.setToolTipText(Dict.START.getString());

        helpButton.setIcon(Pict.Actions.HELP_CONTENTS.get(ICON_SIZE));
        helpButton.setToolTipText(Dict.HELP.getString());

        opComboBox.setModel(new DefaultComboBoxModel(mBundle.getString("operations").split("\\|")));
        dateSourceComboBox.setModel(new DefaultComboBoxModel(mBundle.getString("dateSource").split("\\|")));
        followLinksCheckBox.setEnabled(!SystemUtils.IS_OS_WINDOWS);

        sourceChooserPanel.setDropMode(FileChooserPanel.DropMode.MULTI);
        sourceChooserPanel.setHeader(Dict.SOURCE.getString());
        sourceChooserPanel.setMode(JFileChooser.FILES_AND_DIRECTORIES);
        sourceChooserPanel.getFileChooser().setMultiSelectionEnabled(true);
        sourceChooserPanel.setButtonListener(this);

        previewDateFormat();

        dateFormatTextField.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void changedUpdate(DocumentEvent e) {
                previewDateFormat();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                previewDateFormat();
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                previewDateFormat();
            }

        });

        loadOptions();
    }

    private void loadOptions() {
        dateFormatTextField.setText(mOptions.getDatePattern());
        dateSourceComboBox.setSelectedIndex(mOptions.getDateSource());
        destChooserPanel.setPath(mOptions.getDestPath());
        dryRunCheckBox.setSelected(mOptions.isDryRun());
        followLinksCheckBox.setSelected(mOptions.isFollowLinks());
        opComboBox.setSelectedIndex(mOptions.getOperation());
        patternTextField.setText(mOptions.getSourcePattern());
        recursiveCheckBox.setSelected(mOptions.isRecursive());
        sourceChooserPanel.setPath(mOptions.getSourcePaths());
    }

    private void saveOptions() {
        mOptions.setDatePattern(dateFormatTextField.getText());
        mOptions.setDateSource(dateSourceComboBox.getSelectedIndex());
        mOptions.setDestPath(destChooserPanel.getPath());
        mOptions.setDryRun(dryRunCheckBox.isSelected());
        mOptions.setFollowLinks(followLinksCheckBox.isSelected());
        mOptions.setOperation(opComboBox.getSelectedIndex());
        mOptions.setRecursive(recursiveCheckBox.isSelected());
        mOptions.setSourcePaths(sourceChooserPanel.getPath());
        mOptions.setSourcePattern(patternTextField.getText());
    }

    private void previewDateFormat() {
        String datePreview;

        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormatTextField.getText());
            datePreview = simpleDateFormat.format(new Date(System.currentTimeMillis()));
        } catch (IllegalArgumentException ex) {
            datePreview = Dict.ERROR.getString();
        }

        String dateLabel = String.format("%s (%s)", Dict.DATE_PATTERN.getString(), datePreview);
        dateFormatLabel.setText(dateLabel);
    }

    private void start() {
        mLogBuilder = new StringBuilder();

        if (mInputOutput != null) {
            mInputOutput.closeInputOutput();
        }

        mInputOutput = IOProvider.getDefault().getIO(mToolName, false);
        mInputOutput.select();

        appendLog(Toolbox.getDefaultDateFormat().format(Calendar.getInstance().getTime()) + "\n");

        File file = new File(mOptions.getDestPath());

        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(mOptions.getDatePattern());
            if (file.isDirectory() && file.canWrite()) {
                Operation operation = new Operation(this);
                operation.start();
            } else {
                Message.error(Dict.IO_ERROR_TITLE.getString(), Dict.INVALID_DESTINATION.getString());
            }
        } catch (IllegalArgumentException ex) {
            Message.error(Dict.ERROR.getString(), ex.getLocalizedMessage());
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        toolBar = new javax.swing.JToolBar();
        startButton = new javax.swing.JButton();
        opComboBox = new javax.swing.JComboBox();
        recursiveCheckBox = new javax.swing.JCheckBox();
        followLinksCheckBox = new javax.swing.JCheckBox();
        dryRunCheckBox = new javax.swing.JCheckBox();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        helpButton = new javax.swing.JButton();
        sourceChooserPanel = new se.trixon.almond.dialogs.FileChooserPanel();
        destChooserPanel = new se.trixon.almond.dialogs.FileChooserPanel();
        optionsPanel = new javax.swing.JPanel();
        patternPanel = new javax.swing.JPanel();
        patternLabel = new javax.swing.JLabel();
        patternTextField = new javax.swing.JTextField();
        dateSourcePanel = new javax.swing.JPanel();
        dateSourceLabel = new javax.swing.JLabel();
        dateSourceComboBox = new javax.swing.JComboBox();
        dateFormatPanel = new javax.swing.JPanel();
        dateFormatLabel = new javax.swing.JLabel();
        dateFormatTextField = new javax.swing.JTextField();

        toolBar.setFloatable(false);

        startButton.setFocusable(false);
        startButton.setHorizontalAlignment(javax.swing.SwingConstants.LEADING);
        startButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startButtonActionPerformed(evt);
            }
        });
        toolBar.add(startButton);

        opComboBox.setMaximumSize(new java.awt.Dimension(200, 32767));
        toolBar.add(opComboBox);

        org.openide.awt.Mnemonics.setLocalizedText(recursiveCheckBox, Dict.RECURSIVE.getString());
        recursiveCheckBox.setFocusable(false);
        recursiveCheckBox.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        toolBar.add(recursiveCheckBox);

        org.openide.awt.Mnemonics.setLocalizedText(followLinksCheckBox, Dict.FOLLOW_LINKS.getString());
        followLinksCheckBox.setFocusable(false);
        followLinksCheckBox.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        toolBar.add(followLinksCheckBox);

        org.openide.awt.Mnemonics.setLocalizedText(dryRunCheckBox, Dict.DRY_RUN.getString());
        dryRunCheckBox.setFocusable(false);
        dryRunCheckBox.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        toolBar.add(dryRunCheckBox);
        toolBar.add(jSeparator1);

        helpButton.setFocusable(false);
        helpButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        helpButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        helpButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                helpButtonActionPerformed(evt);
            }
        });
        toolBar.add(helpButton);

        sourceChooserPanel.setHeader(Dict.SOURCE.getString());

        destChooserPanel.setHeader(Dict.DESTINATION.getString());

        optionsPanel.setLayout(new java.awt.GridLayout(1, 0));

        org.openide.awt.Mnemonics.setLocalizedText(patternLabel, Dict.FILE_PATTERN.getString());

        patternTextField.setText("*"); // NOI18N

        javax.swing.GroupLayout patternPanelLayout = new javax.swing.GroupLayout(patternPanel);
        patternPanel.setLayout(patternPanelLayout);
        patternPanelLayout.setHorizontalGroup(patternPanelLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(patternPanelLayout.createSequentialGroup().addGap(0, 0, 0)
                        .addGroup(patternPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(patternPanelLayout.createSequentialGroup().addComponent(patternLabel)
                                        .addGap(0, 0, Short.MAX_VALUE))
                                .addComponent(patternTextField))
                        .addContainerGap()));
        patternPanelLayout.setVerticalGroup(patternPanelLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(patternPanelLayout.createSequentialGroup().addComponent(patternLabel).addGap(0, 0, 0)
                        .addComponent(patternTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE)));

        optionsPanel.add(patternPanel);

        org.openide.awt.Mnemonics.setLocalizedText(dateSourceLabel, org.openide.util.NbBundle
                .getMessage(RelocatorTopComponent.class, "RelocatorTopComponent.dateSourceLabel.text")); // NOI18N

        javax.swing.GroupLayout dateSourcePanelLayout = new javax.swing.GroupLayout(dateSourcePanel);
        dateSourcePanel.setLayout(dateSourcePanelLayout);
        dateSourcePanelLayout.setHorizontalGroup(
                dateSourcePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(dateSourcePanelLayout.createSequentialGroup().addGap(0, 0, 0)
                                .addGroup(dateSourcePanelLayout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(dateSourcePanelLayout.createSequentialGroup()
                                                .addComponent(dateSourceLabel).addGap(0, 0, Short.MAX_VALUE))
                                        .addComponent(dateSourceComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                Short.MAX_VALUE))
                                .addContainerGap()));
        dateSourcePanelLayout.setVerticalGroup(dateSourcePanelLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(dateSourcePanelLayout.createSequentialGroup().addComponent(dateSourceLabel)
                        .addGap(0, 0, 0)
                        .addComponent(dateSourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE)));

        optionsPanel.add(dateSourcePanel);

        org.openide.awt.Mnemonics.setLocalizedText(dateFormatLabel, Dict.DATE_PATTERN.getString());

        dateFormatTextField.setToolTipText(
                "<html>\n <h3>Date and Time Patterns</h3>\n <p>\n Date and time formats are specified by <em>date and time pattern</em>\n strings.\n Within date and time pattern strings, unquoted letters from\n <code>'A'</code> to <code>'Z'</code> and from <code>'a'</code> to\n <code>'z'</code> are interpreted as pattern letters representing the\n components of a date or time string.\n Text can be quoted using single quotes (<code>'</code>) to avoid\n interpretation.\n <code>\"''\"</code> represents a single quote.\n All other characters are not interpreted; they're simply copied into the\n output string during formatting or matched against the input string\n during parsing.\n <p>\nThe following pattern letters are defined (all other characters from\n <code>'A'</code> to <code>'Z'</code> and from <code>'a'</code> to\n <code>'z'</code> are reserved):\n <blockquote>\n <table border=0 cellspacing=3 cellpadding=0 summary=\"Chart shows pattern letters, date/time component, presentation, and examples.\">\n     <tr style=\"background-color: rgb(204, 204, 255);\">\n         <th align=left>Letter\n         <th align=left>Date or Time Component\n         <th align=left>Presentation\n         <th align=left>Examples\n     <tr>\n         <td><code>G</code>\n         <td>Era designator\n         <td><a href=\"#text\">Text</a>\n         <td><code>AD</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>y</code>\n         <td>Year\n         <td><a href=\"#year\">Year</a>\n         <td><code>1996</code>; <code>96</code>\n     <tr>\n         <td><code>Y</code>\n         <td>Week year\n         <td><a href=\"#year\">Year</a>\n         <td><code>2009</code>; <code>09</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>M</code>\n         <td>Month in year (context sensitive)\n         <td><a href=\"#month\">Month</a>\n         <td><code>July</code>; <code>Jul</code>; <code>07</code>\n     <tr>\n         <td><code>L</code>\n         <td>Month in year (standalone form)\n         <td><a href=\"#month\">Month</a>\n         <td><code>July</code>; <code>Jul</code>; <code>07</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>w</code>\n         <td>Week in year\n         <td><a href=\"#number\">Number</a>\n         <td><code>27</code>\n     <tr>\n         <td><code>W</code>\n         <td>Week in month\n         <td><a href=\"#number\">Number</a>\n         <td><code>2</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>D</code>\n         <td>Day in year\n         <td><a href=\"#number\">Number</a>\n         <td><code>189</code>\n     <tr>\n         <td><code>d</code>\n         <td>Day in month\n         <td><a href=\"#number\">Number</a>\n         <td><code>10</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>F</code>\n         <td>Day of week in month\n         <td><a href=\"#number\">Number</a>\n         <td><code>2</code>\n     <tr>\n         <td><code>E</code>\n         <td>Day name in week\n         <td><a href=\"#text\">Text</a>\n         <td><code>Tuesday</code>; <code>Tue</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>u</code>\n         <td>Day number of week (1 = Monday, ..., 7 = Sunday)\n         <td><a href=\"#number\">Number</a>\n         <td><code>1</code>\n     <tr>\n         <td><code>a</code>\n         <td>Am/pm marker\n         <td><a href=\"#text\">Text</a>\n         <td><code>PM</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>H</code>\n         <td>Hour in day (0-23)\n         <td><a href=\"#number\">Number</a>\n         <td><code>0</code>\n     <tr>\n         <td><code>k</code>\n         <td>Hour in day (1-24)\n         <td><a href=\"#number\">Number</a>\n         <td><code>24</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>K</code>\n         <td>Hour in am/pm (0-11)\n         <td><a href=\"#number\">Number</a>\n         <td><code>0</code>\n     <tr>\n         <td><code>h</code>\n         <td>Hour in am/pm (1-12)\n         <td><a href=\"#number\">Number</a>\n         <td><code>12</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>m</code>\n         <td>Minute in hour\n         <td><a href=\"#number\">Number</a>\n         <td><code>30</code>\n     <tr>\n         <td><code>s</code>\n         <td>Second in minute\n         <td><a href=\"#number\">Number</a>\n         <td><code>55</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>S</code>\n         <td>Millisecond\n         <td><a href=\"#number\">Number</a>\n         <td><code>978</code>\n     <tr>\n         <td><code>z</code>\n         <td>Time zone\n         <td><a href=\"#timezone\">General time zone</a>\n         <td><code>Pacific Standard Time</code>; <code>PST</code>; <code>GMT-08:00</code>\n     <tr style=\"background-color: rgb(238, 238, 255);\">\n         <td><code>Z</code>\n         <td>Time zone\n         <td><a href=\"#rfc822timezone\">RFC 822 time zone</a>\n         <td><code>-0800</code>\n     <tr>\n         <td><code>X</code>\n         <td>Time zone\n         <td><a href=\"#iso8601timezone\">ISO 8601 time zone</a>\n         <td><code>-08</code>; <code>-0800</code>;  <code>-08:00</code>\n </table>\n </blockquote>"); // NOI18N

        javax.swing.GroupLayout dateFormatPanelLayout = new javax.swing.GroupLayout(dateFormatPanel);
        dateFormatPanel.setLayout(dateFormatPanelLayout);
        dateFormatPanelLayout.setHorizontalGroup(dateFormatPanelLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(dateFormatPanelLayout
                        .createSequentialGroup().addComponent(dateFormatLabel).addGap(0, 0, Short.MAX_VALUE))
                .addComponent(dateFormatTextField));
        dateFormatPanelLayout.setVerticalGroup(dateFormatPanelLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(dateFormatPanelLayout.createSequentialGroup().addComponent(dateFormatLabel)
                        .addGap(0, 0, 0)
                        .addComponent(dateFormatTextField, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

        optionsPanel.add(dateFormatPanel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(toolBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
                        Short.MAX_VALUE)
                .addGroup(layout.createSequentialGroup().addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(sourceChooserPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(destChooserPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(optionsPanel, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addContainerGap()));
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                        .addComponent(toolBar, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(sourceChooserPanel, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(destChooserPanel, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(optionsPanel, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
    }// </editor-fold>//GEN-END:initComponents

    private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed
        saveOptions();
        start();
    }//GEN-LAST:event_startButtonActionPerformed

    private void helpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_helpButtonActionPerformed
        displayHelp(mHelpId);
    }//GEN-LAST:event_helpButtonActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel dateFormatLabel;
    private javax.swing.JPanel dateFormatPanel;
    private javax.swing.JTextField dateFormatTextField;
    private javax.swing.JComboBox dateSourceComboBox;
    private javax.swing.JLabel dateSourceLabel;
    private javax.swing.JPanel dateSourcePanel;
    private se.trixon.almond.dialogs.FileChooserPanel destChooserPanel;
    private javax.swing.JCheckBox dryRunCheckBox;
    private javax.swing.JCheckBox followLinksCheckBox;
    private javax.swing.JButton helpButton;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JComboBox opComboBox;
    private javax.swing.JPanel optionsPanel;
    private javax.swing.JLabel patternLabel;
    private javax.swing.JPanel patternPanel;
    private javax.swing.JTextField patternTextField;
    private javax.swing.JCheckBox recursiveCheckBox;
    private se.trixon.almond.dialogs.FileChooserPanel sourceChooserPanel;
    private javax.swing.JButton startButton;
    private javax.swing.JToolBar toolBar;
    // End of variables declaration//GEN-END:variables

    void writeProperties(java.util.Properties p) {
        p.setProperty("version", "1.0");
        saveOptions();

    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
    }

    @Override
    public void onFileChooserCancel(FileChooserPanel fileChooserPanel) {
        // nvm
    }

    @Override
    public void onFileChooserCheckBoxChange(FileChooserPanel fileChooserPanel, boolean isSelected) {
        // nvm
    }

    @Override
    public void onFileChooserDrop(FileChooserPanel fileChooserPanel) {
        if (fileChooserPanel == sourceChooserPanel) {
        }
    }

    @Override
    public void onFileChooserOk(FileChooserPanel fileChooserPanel, File file) {
        JFileChooser fileChooser = fileChooserPanel.getFileChooser();

        if (fileChooserPanel == sourceChooserPanel) {
            if (fileChooser.isMultiSelectionEnabled()) {
                String paths = StringUtils.join(fileChooser.getSelectedFiles(), SystemUtils.PATH_SEPARATOR);
                fileChooserPanel.setPath(paths);
            }
        }
    }

    @Override
    public void onFileChooserPreSelect(FileChooserPanel fileChooserPanel) {
        if (fileChooserPanel == sourceChooserPanel) {
            final String[] paths = sourceChooserPanel.getPath().split(SystemUtils.PATH_SEPARATOR);
            File[] files = new File[paths.length];

            for (int i = 0; i < files.length; i++) {
                files[i] = new File(paths[i]);
            }

            sourceChooserPanel.getFileChooser().setSelectedFiles(files);
        }
    }
}