Package xplanetconfigurator.gui

Source Code of xplanetconfigurator.gui.MainFrame

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

/*
* MainFrame.java
*
* Created on 24.04.2009, 11:27:43
*/
package xplanetconfigurator.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.text.JTextComponent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import xplanetconfigurator.downloader.DownloadTimer;
import xplanetconfigurator.downloader.DownloadStarter;
import xplanetconfigurator.find.ExpressionFinder;
import xplanetconfigurator.find.Findable;
import xplanetconfigurator.find.FoundExpressions;
import xplanetconfigurator.find.ISearchable;
import xplanetconfigurator.find.Selection;
import xplanetconfigurator.util.CheckXPlanetFiles;
import xplanetconfigurator.util.XPlanetRessourceFinder;
import xplanetconfigurator.util.FileUtil;
import xplanetconfigurator.util.MonitorUtil;
import xplanetconfigurator.util.OwnPreferences;
import xplanetconfigurator.util.TimeStamp;
import xplanetconfigurator.util.logging.JFrameLogginConfigurator;

/**
*
* @author tom
*/
public class MainFrame extends javax.swing.JFrame implements TreeSelectionListener, Findable, FeedbackReceiver {

    /**
     * The user migth have more than one place one the same computer from
     * where he starts this programm with (GUI) or just the downloader.
     *
     * @return the absolute path to the executable. It is xplanet.exe for windows.
     */
    public static String getXPLANET_EXECUTABLE() {
        if (MainFrame.PATH_XPLANET_EXECUTABLE == null) {
            MainFrame.PATH_XPLANET_EXECUTABLE = "";
        }
        return MainFrame.PATH_XPLANET_EXECUTABLE;
    }

    /**
     *
     * @param aNAME_XPLANET_EXECUTABLE the file name of the executable.
     * Unter Windows this should be the absolute path to xplanet.exe
     */
    public static void setXPLANET_EXECUTABLE(String path) {
        MainFrame.PATH_XPLANET_EXECUTABLE = path;
    }

    /**
     *
     * @return the CONFIG_NAME
     */
    public static String getCONFIG_NAME() {
        return CONFIG_NAME;
    }

    /**
     * @param aCONFIG_NAME the CONFIG_NAME to set
     */
    public static void setCONFIG_NAME(String aCONFIG_NAME) {
        Logger.getLogger(MainFrame.class.getName()).finer("Setting the config name to: " + aCONFIG_NAME);
        CONFIG_NAME = aCONFIG_NAME;
    }

    /** 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.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        buttonGroupOrigin = new javax.swing.ButtonGroup();
        buttonGroupViewAtBodyOrAlongPath = new javax.swing.ButtonGroup();
        buttonGroupViewFromOrigin = new javax.swing.ButtonGroup();
        buttonGroupProjection = new javax.swing.ButtonGroup();
        jPanelMain = new javax.swing.JPanel();
        jSplitPaneMainControlsCommand = new javax.swing.JSplitPane();
        jPanelMainTreeControls = new javax.swing.JPanel();
        jSplitPaneTreeControls = new javax.swing.JSplitPane();
        jPanelTree = new javax.swing.JPanel();
        jScrollPaneTree = new javax.swing.JScrollPane();
        jTreeMain = new javax.swing.JTree();
        jPanelControls = new javax.swing.JPanel();
        jPanelMainControlsCommand = new javax.swing.JPanel();
        jTabbedPaneMainControlsCommand = new javax.swing.JTabbedPane();
        jPanelMessagesXPlanet = new javax.swing.JPanel();
        jScrollPaneExternalMessages = new javax.swing.JScrollPane();
        jTextAreaXPlanetMessages = new javax.swing.JTextArea();
        jPanelMessagesDownloader = new javax.swing.JPanel();
        jScrollPaneDownloaderMessages = new javax.swing.JScrollPane();
        jTextAreaDownloaderMessages = new javax.swing.JTextArea();
        jPanelCommandLineParameters = new javax.swing.JPanel();
        jScrollPaneCommandLineParameters = new javax.swing.JScrollPane();
        jTextAreaCommandLineParameters = new javax.swing.JTextArea();
        jPanelConfigFile = new javax.swing.JPanel();
        jScrollPaneConfigFile = new javax.swing.JScrollPane();
        jTextAreaConfigFile = new javax.swing.JTextArea();
        jPanelDownloader = new javax.swing.JPanel();
        jScrollPaneExternal = new javax.swing.JScrollPane();
        jTextAreaDownloader = new javax.swing.JTextArea();
        jToolBarMain = new javax.swing.JToolBar();
        jButtonPreview = new javax.swing.JButton();
        jSeparator10 = new javax.swing.JToolBar.Separator();
        jButtonStart = new javax.swing.JButton();
        jButtonStop = new javax.swing.JButton();
        jSeparator4 = new javax.swing.JToolBar.Separator();
        jButtonSave = new javax.swing.JButton();
        jSeparator5 = new javax.swing.JToolBar.Separator();
        jButtonFind = new javax.swing.JButton();
        jButtonFindAgain = new javax.swing.JButton();
        jSeparator6 = new javax.swing.JToolBar.Separator();
        jCheckBoxExpertMode = new javax.swing.JCheckBox();
        jMenuBarMain = new javax.swing.JMenuBar();
        jMenuFile = new javax.swing.JMenu();
        jMenuItemPreview = new javax.swing.JMenuItem();
        jSeparator9 = new javax.swing.JSeparator();
        jMenuItemStart = new javax.swing.JMenuItem();
        jMenuItemStop = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JSeparator();
        jMenuItemSave = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JSeparator();
        jMenuItemHideInSystemTray = new javax.swing.JMenuItem();
        jMenuItemExit = new javax.swing.JMenuItem();
        jMenuEdit = new javax.swing.JMenu();
        jMenuItemFind = new javax.swing.JMenuItem();
        jMenuItemFindAgain = new javax.swing.JMenuItem();
        jSeparatorMenuEdit = new javax.swing.JSeparator();
        jMenuOptions = new javax.swing.JMenu();
        jMenuItemProxy = new javax.swing.JMenuItem();
        jMenuItemLogging = new javax.swing.JMenuItem();
        jSeparator7 = new javax.swing.JSeparator();
        jCheckBoxMenuItemAllowInternetConnection = new javax.swing.JCheckBoxMenuItem();
        jMenuItemGuessRessources = new javax.swing.JMenuItem();
        jSeparator8 = new javax.swing.JSeparator();
        jCheckBoxMenuItemShowHideDialog = new javax.swing.JCheckBoxMenuItem();
        jCheckBoxMenuItemRunAtStartUp = new javax.swing.JCheckBoxMenuItem();
        jMenuHelp = new javax.swing.JMenu();
        jMenuItemAbout = new javax.swing.JMenuItem();
        jMenuItemHelp = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        jMenuItemSystem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("XPlanet Configurator"); // NOI18N
        setName("Form"); // NOI18N
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                MainFrame.this.windowClosing(evt);
            }
            public void windowIconified(java.awt.event.WindowEvent evt) {
                formWindowIconified(evt);
            }
        });
        getContentPane().setLayout(new java.awt.GridBagLayout());

        jPanelMain.setName("jPanelMain"); // NOI18N
        jPanelMain.setLayout(new java.awt.GridBagLayout());

        jSplitPaneMainControlsCommand.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPaneMainControlsCommand.setName("jSplitPaneMainControlsCommand"); // NOI18N

        jPanelMainTreeControls.setMinimumSize(new java.awt.Dimension(500, 200));
        jPanelMainTreeControls.setName("jPanelMainTreeControls"); // NOI18N
        jPanelMainTreeControls.setPreferredSize(new java.awt.Dimension(500, 200));
        jPanelMainTreeControls.setLayout(new java.awt.GridBagLayout());

        jSplitPaneTreeControls.setName("jSplitPaneTreeControls"); // NOI18N

        jPanelTree.setName("jPanelTree"); // NOI18N
        jPanelTree.setLayout(new java.awt.GridBagLayout());

        jScrollPaneTree.setName("jScrollPaneTree"); // NOI18N

        jTreeMain.setName("jTreeMain"); // NOI18N
        jScrollPaneTree.setViewportView(jTreeMain);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelTree.add(jScrollPaneTree, gridBagConstraints);

        jSplitPaneTreeControls.setLeftComponent(jPanelTree);

        jPanelControls.setName("jPanelControls"); // NOI18N
        jPanelControls.setLayout(new java.awt.GridBagLayout());
        jSplitPaneTreeControls.setRightComponent(jPanelControls);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelMainTreeControls.add(jSplitPaneTreeControls, gridBagConstraints);

        jSplitPaneMainControlsCommand.setLeftComponent(jPanelMainTreeControls);

        jPanelMainControlsCommand.setName("jPanelMainControlsCommand"); // NOI18N
        jPanelMainControlsCommand.setLayout(new java.awt.GridBagLayout());

        jTabbedPaneMainControlsCommand.setMinimumSize(new java.awt.Dimension(100, 100));
        jTabbedPaneMainControlsCommand.setName("jTabbedPaneMainControlsCommand"); // NOI18N

        jPanelMessagesXPlanet.setName("jPanelMessagesXPlanet"); // NOI18N
        jPanelMessagesXPlanet.setLayout(new java.awt.GridBagLayout());

        jScrollPaneExternalMessages.setName("jScrollPaneExternalMessages"); // NOI18N

        jTextAreaXPlanetMessages.setColumns(20);
        jTextAreaXPlanetMessages.setRows(5);
        jTextAreaXPlanetMessages.setName("jTextAreaXPlanetMessages"); // NOI18N
        jScrollPaneExternalMessages.setViewportView(jTextAreaXPlanetMessages);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelMessagesXPlanet.add(jScrollPaneExternalMessages, gridBagConstraints);

        jTabbedPaneMainControlsCommand.addTab("XPlanet Messages", jPanelMessagesXPlanet);

        jPanelMessagesDownloader.setName("jPanelMessagesDownloader"); // NOI18N
        jPanelMessagesDownloader.setLayout(new java.awt.GridBagLayout());

        jScrollPaneDownloaderMessages.setName("jScrollPaneDownloaderMessages"); // NOI18N

        jTextAreaDownloaderMessages.setColumns(20);
        jTextAreaDownloaderMessages.setRows(5);
        jTextAreaDownloaderMessages.setName("jTextAreaDownloaderMessages"); // NOI18N
        jScrollPaneDownloaderMessages.setViewportView(jTextAreaDownloaderMessages);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelMessagesDownloader.add(jScrollPaneDownloaderMessages, gridBagConstraints);

        jTabbedPaneMainControlsCommand.addTab("Downloader Messages", jPanelMessagesDownloader);

        jPanelCommandLineParameters.setName("jPanelCommandLineParameters"); // NOI18N
        jPanelCommandLineParameters.setLayout(new java.awt.GridBagLayout());

        jScrollPaneCommandLineParameters.setName("jScrollPaneCommandLineParameters"); // NOI18N

        jTextAreaCommandLineParameters.setColumns(20);
        jTextAreaCommandLineParameters.setLineWrap(true);
        jTextAreaCommandLineParameters.setRows(5);
        jTextAreaCommandLineParameters.setName("jTextAreaCommandLineParameters"); // NOI18N
        jTextAreaCommandLineParameters.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                jTextAreaCommandLineParametersCaretUpdate(evt);
            }
        });
        jScrollPaneCommandLineParameters.setViewportView(jTextAreaCommandLineParameters);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelCommandLineParameters.add(jScrollPaneCommandLineParameters, gridBagConstraints);

        jTabbedPaneMainControlsCommand.addTab("Command Line Parameters", jPanelCommandLineParameters);

        jPanelConfigFile.setName("jPanelConfigFile"); // NOI18N
        jPanelConfigFile.setLayout(new java.awt.GridBagLayout());

        jScrollPaneConfigFile.setName("jScrollPaneConfigFile"); // NOI18N

        jTextAreaConfigFile.setColumns(20);
        jTextAreaConfigFile.setRows(5);
        jTextAreaConfigFile.setName("jTextAreaConfigFile"); // NOI18N
        jTextAreaConfigFile.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                jTextAreaConfigFileCaretUpdate(evt);
            }
        });
        jScrollPaneConfigFile.setViewportView(jTextAreaConfigFile);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelConfigFile.add(jScrollPaneConfigFile, gridBagConstraints);

        jTabbedPaneMainControlsCommand.addTab("Config File (-config)", jPanelConfigFile);

        jPanelDownloader.setName("jPanelDownloader"); // NOI18N
        jPanelDownloader.setLayout(new java.awt.GridBagLayout());

        jScrollPaneExternal.setName("jScrollPaneExternal"); // NOI18N

        jTextAreaDownloader.setColumns(20);
        jTextAreaDownloader.setEditable(false);
        jTextAreaDownloader.setRows(5);
        jTextAreaDownloader.setName("jTextAreaDownloader"); // NOI18N
        jTextAreaDownloader.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                jTextAreaDownloaderCaretUpdate(evt);
            }
        });
        jScrollPaneExternal.setViewportView(jTextAreaDownloader);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelDownloader.add(jScrollPaneExternal, gridBagConstraints);

        jTabbedPaneMainControlsCommand.addTab("Downloader", jPanelDownloader);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelMainControlsCommand.add(jTabbedPaneMainControlsCommand, gridBagConstraints);

        jSplitPaneMainControlsCommand.setBottomComponent(jPanelMainControlsCommand);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelMain.add(jSplitPaneMainControlsCommand, gridBagConstraints);

        jToolBarMain.setName("jToolBarMain"); // NOI18N

        jButtonPreview.setMnemonic('P');
        jButtonPreview.setText("Preview");
        jButtonPreview.setToolTipText("Still experimental: Show preview Image");
        jButtonPreview.setEnabled(false);
        jButtonPreview.setFocusable(false);
        jButtonPreview.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonPreview.setName("jButtonPreview"); // NOI18N
        jButtonPreview.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonPreview.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonPreviewActionPerformed(evt);
            }
        });
        jToolBarMain.add(jButtonPreview);

        jSeparator10.setName("jSeparator10"); // NOI18N
        jToolBarMain.add(jSeparator10);

        jButtonStart.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/Play24.gif"))); // NOI18N
        jButtonStart.setToolTipText("Start / Restart XPlanet");
        jButtonStart.setFocusable(false);
        jButtonStart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonStart.setName("jButtonStart"); // NOI18N
        jButtonStart.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonStartActionPerformed(evt);
            }
        });
        jToolBarMain.add(jButtonStart);

        jButtonStop.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/Stop24.gif"))); // NOI18N
        jButtonStop.setToolTipText("Stop XPlanet");
        jButtonStop.setEnabled(false);
        jButtonStop.setFocusable(false);
        jButtonStop.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonStop.setName("jButtonStop"); // NOI18N
        jButtonStop.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonStopActionPerformed(evt);
            }
        });
        jToolBarMain.add(jButtonStop);

        jSeparator4.setName("jSeparator4"); // NOI18N
        jToolBarMain.add(jSeparator4);

        jButtonSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/Save24.gif"))); // NOI18N
        jButtonSave.setToolTipText("Save");
        jButtonSave.setFocusable(false);
        jButtonSave.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonSave.setName("jButtonSave"); // NOI18N
        jButtonSave.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSaveActionPerformed(evt);
            }
        });
        jToolBarMain.add(jButtonSave);

        jSeparator5.setName("jSeparator5"); // NOI18N
        jToolBarMain.add(jSeparator5);

        jButtonFind.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/Find24.gif"))); // NOI18N
        jButtonFind.setToolTipText("Ctrl+F");
        jButtonFind.setFocusable(false);
        jButtonFind.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonFind.setName("jButtonFind"); // NOI18N
        jButtonFind.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonFind.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonFindActionPerformed(evt);
            }
        });
        jToolBarMain.add(jButtonFind);

        jButtonFindAgain.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/FindAgain24.gif"))); // NOI18N
        jButtonFindAgain.setToolTipText("Find Again - F3");
        jButtonFindAgain.setFocusable(false);
        jButtonFindAgain.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonFindAgain.setName("jButtonFindAgain"); // NOI18N
        jButtonFindAgain.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonFindAgain.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonFindAgainActionPerformed(evt);
            }
        });
        jToolBarMain.add(jButtonFindAgain);

        jSeparator6.setName("jSeparator6"); // NOI18N
        jToolBarMain.add(jSeparator6);

        jCheckBoxExpertMode.setMnemonic('E');
        jCheckBoxExpertMode.setText("Expert Mode");
        jCheckBoxExpertMode.setFocusable(false);
        jCheckBoxExpertMode.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        jCheckBoxExpertMode.setName("jCheckBoxExpertMode"); // NOI18N
        jCheckBoxExpertMode.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jCheckBoxExpertMode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxExpertModeActionPerformed(evt);
            }
        });
        jToolBarMain.add(jCheckBoxExpertMode);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        jPanelMain.add(jToolBarMain, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(jPanelMain, gridBagConstraints);

        jMenuBarMain.setName("jMenuBarMain"); // NOI18N

        jMenuFile.setMnemonic('F');
        jMenuFile.setText("File");
        jMenuFile.setName("jMenuFile"); // NOI18N
        jMenuFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuFileActionPerformed(evt);
            }
        });

        jMenuItemPreview.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemPreview.setMnemonic('P');
        jMenuItemPreview.setText("Preview");
        jMenuItemPreview.setName("jMenuItemPreview"); // NOI18N
        jMenuItemPreview.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemPreviewActionPerformed(evt);
            }
        });
        jMenuFile.add(jMenuItemPreview);

        jSeparator9.setName("jSeparator9"); // NOI18N
        jMenuFile.add(jSeparator9);

        jMenuItemStart.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, 0));
        jMenuItemStart.setMnemonic('E');
        jMenuItemStart.setText("Start XPlanet");
        jMenuItemStart.setToolTipText("Start XPlanet");
        jMenuItemStart.setName("jMenuItemStart"); // NOI18N
        jMenuItemStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemStartActionPerformed(evt);
            }
        });
        jMenuFile.add(jMenuItemStart);

        jMenuItemStop.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemStop.setText("Stop XPlanet");
        jMenuItemStop.setToolTipText("Stop XPlanet");
        jMenuItemStop.setName("jMenuItemStop"); // NOI18N
        jMenuItemStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemStopActionPerformed(evt);
            }
        });
        jMenuFile.add(jMenuItemStop);

        jSeparator2.setName("jSeparator2"); // NOI18N
        jMenuFile.add(jSeparator2);

        jMenuItemSave.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemSave.setMnemonic('S');
        jMenuItemSave.setText("Save");
        jMenuItemSave.setToolTipText("Save");
        jMenuItemSave.setName("jMenuItemSave"); // NOI18N
        jMenuFile.add(jMenuItemSave);

        jSeparator3.setName("jSeparator3"); // NOI18N
        jMenuFile.add(jSeparator3);

        jMenuItemHideInSystemTray.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_H, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemHideInSystemTray.setMnemonic('H');
        jMenuItemHideInSystemTray.setText("Hide in System Tray");
        jMenuItemHideInSystemTray.setName("jMenuItemHideInSystemTray"); // NOI18N
        jMenuItemHideInSystemTray.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemHideInSystemTrayActionPerformed(evt);
            }
        });
        jMenuFile.add(jMenuItemHideInSystemTray);

        jMenuItemExit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.ALT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemExit.setMnemonic('E');
        jMenuItemExit.setText("Exit");
        jMenuItemExit.setToolTipText("<html>Exit the Application<br>Do not hide in System Tray</html>");
        jMenuItemExit.setName("jMenuItemExit"); // NOI18N
        jMenuItemExit.setPreferredSize(new java.awt.Dimension(100, 22));
        jMenuItemExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemExitActionPerformed(evt);
            }
        });
        jMenuFile.add(jMenuItemExit);

        jMenuBarMain.add(jMenuFile);

        jMenuEdit.setMnemonic('E');
        jMenuEdit.setText("Edit");
        jMenuEdit.setName("jMenuEdit"); // NOI18N

        jMenuItemFind.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemFind.setMnemonic('F');
        jMenuItemFind.setText("Find...");
        jMenuItemFind.setToolTipText("Find");
        jMenuItemFind.setName("jMenuItemFind"); // NOI18N
        jMenuItemFind.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemFindActionPerformed(evt);
            }
        });
        jMenuEdit.add(jMenuItemFind);

        jMenuItemFindAgain.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F3, 0));
        jMenuItemFindAgain.setMnemonic('A');
        jMenuItemFindAgain.setText("Find Again");
        jMenuItemFindAgain.setToolTipText("Find Again - F3");
        jMenuItemFindAgain.setName("jMenuItemFindAgain"); // NOI18N
        jMenuItemFindAgain.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemFindAgainActionPerformed(evt);
            }
        });
        jMenuEdit.add(jMenuItemFindAgain);

        jSeparatorMenuEdit.setName("jSeparatorMenuEdit"); // NOI18N
        jMenuEdit.add(jSeparatorMenuEdit);

        jMenuBarMain.add(jMenuEdit);

        jMenuOptions.setText("Options");
        jMenuOptions.setName("jMenuOptions"); // NOI18N

        jMenuItemProxy.setMnemonic('P');
        jMenuItemProxy.setText("Proxy...");
        jMenuItemProxy.setName("jMenuItemProxy"); // NOI18N
        jMenuItemProxy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemProxyActionPerformed(evt);
            }
        });
        jMenuOptions.add(jMenuItemProxy);

        jMenuItemLogging.setMnemonic('L');
        jMenuItemLogging.setText("Logging...");
        jMenuItemLogging.setToolTipText("Loggin of this Application (not XPlanet)");
        jMenuItemLogging.setName("jMenuItemLogging"); // NOI18N
        jMenuItemLogging.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemLoggingActionPerformed(evt);
            }
        });
        jMenuOptions.add(jMenuItemLogging);

        jSeparator7.setName("jSeparator7"); // NOI18N
        jMenuOptions.add(jSeparator7);

        jCheckBoxMenuItemAllowInternetConnection.setMnemonic('A');
        jCheckBoxMenuItemAllowInternetConnection.setSelected(true);
        jCheckBoxMenuItemAllowInternetConnection.setText("Allow Internet Connection");
        jCheckBoxMenuItemAllowInternetConnection.setName("jCheckBoxMenuItemAllowInternetConnection"); // NOI18N
        jCheckBoxMenuItemAllowInternetConnection.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxMenuItemAllowInternetConnectionActionPerformed(evt);
            }
        });
        jMenuOptions.add(jCheckBoxMenuItemAllowInternetConnection);

        jMenuItemGuessRessources.setMnemonic('G');
        jMenuItemGuessRessources.setText("Guess XPlanet Ressources");
        jMenuItemGuessRessources.setName("jMenuItemGuessRessources"); // NOI18N
        jMenuItemGuessRessources.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemGuessRessourcesActionPerformed(evt);
            }
        });
        jMenuOptions.add(jMenuItemGuessRessources);

        jSeparator8.setName("jSeparator8"); // NOI18N
        jMenuOptions.add(jSeparator8);

        jCheckBoxMenuItemShowHideDialog.setMnemonic('S');
        jCheckBoxMenuItemShowHideDialog.setSelected(true);
        jCheckBoxMenuItemShowHideDialog.setText("Show Hide Dialog");
        jCheckBoxMenuItemShowHideDialog.setName("jCheckBoxMenuItemShowHideDialog"); // NOI18N
        jCheckBoxMenuItemShowHideDialog.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxMenuItemShowHideDialogActionPerformed(evt);
            }
        });
        jMenuOptions.add(jCheckBoxMenuItemShowHideDialog);

        jCheckBoxMenuItemRunAtStartUp.setSelected(true);
        jCheckBoxMenuItemRunAtStartUp.setText("Run XPlanet at Startup");
        jCheckBoxMenuItemRunAtStartUp.setName("jCheckBoxMenuItemRunAtStartUp"); // NOI18N
        jCheckBoxMenuItemRunAtStartUp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxMenuItemRunAtStartUpActionPerformed(evt);
            }
        });
        jMenuOptions.add(jCheckBoxMenuItemRunAtStartUp);

        jMenuBarMain.add(jMenuOptions);

        jMenuHelp.setMnemonic('H');
        jMenuHelp.setText("Help");
        jMenuHelp.setName("jMenuHelp"); // NOI18N
        jMenuHelp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuHelpActionPerformed(evt);
            }
        });

        jMenuItemAbout.setMnemonic('A');
        jMenuItemAbout.setText("About...");
        jMenuItemAbout.setName("jMenuItemAbout"); // NOI18N
        jMenuItemAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemAboutActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemAbout);

        jMenuItemHelp.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
        jMenuItemHelp.setMnemonic('H');
        jMenuItemHelp.setText("Help...");
        jMenuItemHelp.setToolTipText("Help");
        jMenuItemHelp.setName("jMenuItemHelp"); // NOI18N
        jMenuItemHelp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemHelpActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemHelp);

        jSeparator1.setName("jSeparator1"); // NOI18N
        jMenuHelp.add(jSeparator1);

        jMenuItemSystem.setMnemonic('S');
        jMenuItemSystem.setText("System...");
        jMenuItemSystem.setToolTipText("Show Information about your System");
        jMenuItemSystem.setName("jMenuItemSystem"); // NOI18N
        jMenuItemSystem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemSystemActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemSystem);

        jMenuBarMain.add(jMenuHelp);

        setJMenuBar(jMenuBarMain);

        pack();
    }// </editor-fold>//GEN-END:initComponents
    private void jMenuHelpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuHelpActionPerformed
        this.openHelpDialog();
    }//GEN-LAST:event_jMenuHelpActionPerformed

    private void jMenuItemAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemAboutActionPerformed
        this.openAboutDialog();
    }//GEN-LAST:event_jMenuItemAboutActionPerformed

    private void jMenuItemSystemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSystemActionPerformed
        this.openSystemInfoDialog();
    }//GEN-LAST:event_jMenuItemSystemActionPerformed

    private void jMenuItemLoggingActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemLoggingActionPerformed
        this.openLoggingConfiguration();
    }//GEN-LAST:event_jMenuItemLoggingActionPerformed

    private void jMenuItemExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemExitActionPerformed
        this.cleanUp();
}//GEN-LAST:event_jMenuItemExitActionPerformed

    private void windowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_windowClosing
//        JOptionPane.showMessageDialog(null,
//                        "<html>The Window is hiding in the System Tray<br><br>"
//                        + "To exit use:"
//                        + "<ul><li>Menu 'File' > 'Exit (Strg+Alt+X)</li>"
//                        + "<li>System Tray > Tray Ico 'XPlanet' > 'Exit'</li></ul></html>");

//        this.setVisible(false);
        this.cleanUp();
}//GEN-LAST:event_windowClosing

    private void jMenuItemHelpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemHelpActionPerformed
        this.openHelpDialog();
    }//GEN-LAST:event_jMenuItemHelpActionPerformed

    private void jMenuItemStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemStartActionPerformed
        // this.startXPlanetTimer();
        // this.executeXPlanet();
        // this.startXPlanetTimer();       
        this.startXPlanet();
}//GEN-LAST:event_jMenuItemStartActionPerformed

    private void jTextAreaCommandLineParametersCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_jTextAreaCommandLineParametersCaretUpdate
        if (!this.jTextAreaCommandLineParameters.hasFocus()) {
            this.logger.finest("Ignoring Carret Update because it has no focus.");
            return;
        }
        this.sendParametersToControlsAndSelect();
    }//GEN-LAST:event_jTextAreaCommandLineParametersCaretUpdate

    private void jButtonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSaveActionPerformed
        this.save();
    }//GEN-LAST:event_jButtonSaveActionPerformed

    private void jButtonFindActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonFindActionPerformed
        this.openFindDialog();
    }//GEN-LAST:event_jButtonFindActionPerformed

    private void jButtonFindAgainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonFindAgainActionPerformed
        this.findNext();
}//GEN-LAST:event_jButtonFindAgainActionPerformed

    private void jMenuItemFindActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemFindActionPerformed
        this.openFindDialog();
    }//GEN-LAST:event_jMenuItemFindActionPerformed

    private void jMenuItemFindAgainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemFindAgainActionPerformed
        this.findNext();
    }//GEN-LAST:event_jMenuItemFindAgainActionPerformed

    private void jButtonStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonStartActionPerformed
        this.startXPlanet();
}//GEN-LAST:event_jButtonStartActionPerformed

    private void jMenuFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuFileActionPerformed
        this.preview();
    }//GEN-LAST:event_jMenuFileActionPerformed

    private void jMenuItemStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemStopActionPerformed
        this.stopXPlanet();
}//GEN-LAST:event_jMenuItemStopActionPerformed

    private void jButtonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonStopActionPerformed
        this.stopXPlanet();
    }//GEN-LAST:event_jButtonStopActionPerformed

    private void jTextAreaConfigFileCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_jTextAreaConfigFileCaretUpdate
        if (!this.jTextAreaConfigFile.hasFocus()) {
            this.logger.finest("Ignoring Carret Update because it has no focus.");
            return;
        }
        this.sendParametersToConfigFileControlsAndSelect();
    }//GEN-LAST:event_jTextAreaConfigFileCaretUpdate

    private void jTextAreaDownloaderCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_jTextAreaDownloaderCaretUpdate
        if (!this.jTextAreaDownloader.hasFocus()) {
            this.logger.finest("Ignoring Carret Update because it has no focus.");
            return;
        }
        this.sendParametersToDownloaderControlsAndSelect();
    }//GEN-LAST:event_jTextAreaDownloaderCaretUpdate

    private void jCheckBoxExpertModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxExpertModeActionPerformed
        this.toggleExpertMode();
}//GEN-LAST:event_jCheckBoxExpertModeActionPerformed

    private void jMenuItemProxyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemProxyActionPerformed
        JFrameProxyConfigurator frame = JFrameProxyConfigurator.getInstance(this);
        frame.setVisible(true);
        frame.requestFocus();
        frame.toFront();
    }//GEN-LAST:event_jMenuItemProxyActionPerformed

    private void jMenuItemHideInSystemTrayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemHideInSystemTrayActionPerformed
        this.setVisible(false);
    }//GEN-LAST:event_jMenuItemHideInSystemTrayActionPerformed

    private void formWindowIconified(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowIconified
//        JOptionPane.showMessageDialog(null, "The Window is now hiding in the System Tray");
        OwnPreferences prefs =
                OwnPreferences.userNodeForPackage(MainFrame.class);
        boolean showHideDialog = prefs.getBoolean(MainFrame.KEY_SHOW_HIDE_DIALOG, true);
        if (showHideDialog) {
            JDialogHideMessage f = new JDialogHideMessage(this);
            f.setModalityType(ModalityType.APPLICATION_MODAL);
            f.setVisible(true);
        }
        this.setVisible(false);
        this.saveUserPrefs();
    }//GEN-LAST:event_formWindowIconified

    private void jCheckBoxMenuItemAllowInternetConnectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemAllowInternetConnectionActionPerformed
        if (!this.jCheckBoxMenuItemAllowInternetConnection.isSelected()) {
            this.cleanUpDownloadStarter();
        } else {
            this.startDownloader(null, null, false);
        }
    }//GEN-LAST:event_jCheckBoxMenuItemAllowInternetConnectionActionPerformed

    private void jMenuItemGuessRessourcesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemGuessRessourcesActionPerformed
        this.stopXPlanet();
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        rf.resetXPlanetDirs();
        this.checkWetherXPlanetRessourcesAreKnown();
    }//GEN-LAST:event_jMenuItemGuessRessourcesActionPerformed

    private void jCheckBoxMenuItemShowHideDialogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemShowHideDialogActionPerformed
        OwnPreferences prefs =
                OwnPreferences.userNodeForPackage(MainFrame.class);
        boolean showHideDialog = this.jCheckBoxMenuItemShowHideDialog.isSelected();
        prefs.putBoolean(MainFrame.KEY_SHOW_HIDE_DIALOG, showHideDialog);
    }//GEN-LAST:event_jCheckBoxMenuItemShowHideDialogActionPerformed

    private void jMenuItemPreviewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemPreviewActionPerformed
        this.preview();
    }//GEN-LAST:event_jMenuItemPreviewActionPerformed

    private void jButtonPreviewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonPreviewActionPerformed
        this.preview();
    }//GEN-LAST:event_jButtonPreviewActionPerformed

    private void jCheckBoxMenuItemRunAtStartUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemRunAtStartUpActionPerformed
        this.setIsRunAtStartup();
    }//GEN-LAST:event_jCheckBoxMenuItemRunAtStartUpActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        try {
            throw new java.lang.Exception("Do not use the main!");
        } catch (Exception ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.exit(1);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.ButtonGroup buttonGroupOrigin;
    private javax.swing.ButtonGroup buttonGroupProjection;
    private javax.swing.ButtonGroup buttonGroupViewAtBodyOrAlongPath;
    private javax.swing.ButtonGroup buttonGroupViewFromOrigin;
    private javax.swing.JButton jButtonFind;
    private javax.swing.JButton jButtonFindAgain;
    private javax.swing.JButton jButtonPreview;
    private javax.swing.JButton jButtonSave;
    private javax.swing.JButton jButtonStart;
    private javax.swing.JButton jButtonStop;
    private javax.swing.JCheckBox jCheckBoxExpertMode;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemAllowInternetConnection;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemRunAtStartUp;
    private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemShowHideDialog;
    private javax.swing.JMenuBar jMenuBarMain;
    private javax.swing.JMenu jMenuEdit;
    private javax.swing.JMenu jMenuFile;
    private javax.swing.JMenu jMenuHelp;
    private javax.swing.JMenuItem jMenuItemAbout;
    private javax.swing.JMenuItem jMenuItemExit;
    private javax.swing.JMenuItem jMenuItemFind;
    private javax.swing.JMenuItem jMenuItemFindAgain;
    private javax.swing.JMenuItem jMenuItemGuessRessources;
    private javax.swing.JMenuItem jMenuItemHelp;
    private javax.swing.JMenuItem jMenuItemHideInSystemTray;
    private javax.swing.JMenuItem jMenuItemLogging;
    private javax.swing.JMenuItem jMenuItemPreview;
    private javax.swing.JMenuItem jMenuItemProxy;
    private javax.swing.JMenuItem jMenuItemSave;
    private javax.swing.JMenuItem jMenuItemStart;
    private javax.swing.JMenuItem jMenuItemStop;
    private javax.swing.JMenuItem jMenuItemSystem;
    private javax.swing.JMenu jMenuOptions;
    private javax.swing.JPanel jPanelCommandLineParameters;
    private javax.swing.JPanel jPanelConfigFile;
    private javax.swing.JPanel jPanelControls;
    private javax.swing.JPanel jPanelDownloader;
    private javax.swing.JPanel jPanelMain;
    private javax.swing.JPanel jPanelMainControlsCommand;
    private javax.swing.JPanel jPanelMainTreeControls;
    private javax.swing.JPanel jPanelMessagesDownloader;
    private javax.swing.JPanel jPanelMessagesXPlanet;
    private javax.swing.JPanel jPanelTree;
    private javax.swing.JScrollPane jScrollPaneCommandLineParameters;
    private javax.swing.JScrollPane jScrollPaneConfigFile;
    private javax.swing.JScrollPane jScrollPaneDownloaderMessages;
    private javax.swing.JScrollPane jScrollPaneExternal;
    private javax.swing.JScrollPane jScrollPaneExternalMessages;
    private javax.swing.JScrollPane jScrollPaneTree;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator10;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JToolBar.Separator jSeparator4;
    private javax.swing.JToolBar.Separator jSeparator5;
    private javax.swing.JToolBar.Separator jSeparator6;
    private javax.swing.JSeparator jSeparator7;
    private javax.swing.JSeparator jSeparator8;
    private javax.swing.JSeparator jSeparator9;
    private javax.swing.JSeparator jSeparatorMenuEdit;
    private javax.swing.JSplitPane jSplitPaneMainControlsCommand;
    private javax.swing.JSplitPane jSplitPaneTreeControls;
    private javax.swing.JTabbedPane jTabbedPaneMainControlsCommand;
    private javax.swing.JTextArea jTextAreaCommandLineParameters;
    private javax.swing.JTextArea jTextAreaConfigFile;
    private javax.swing.JTextArea jTextAreaDownloader;
    private javax.swing.JTextArea jTextAreaDownloaderMessages;
    private javax.swing.JTextArea jTextAreaXPlanetMessages;
    private javax.swing.JToolBar jToolBarMain;
    private javax.swing.JTree jTreeMain;
    // End of variables declaration//GEN-END:variables
    //--------------------------------------------------------------------------
    private static final String FRAME_X = "visualiser_frame_x";
    private static final String FRAME_Y = "visualiser_frame_y";
    private static final String FRAME_HEIGHT = "visualiser_frame_height";
    private static final String FRAME_WIDTH = "visualiser_frame_width";
    private static final String GUI_DIVIDER_LOCATION_HORIZONTAL = "gui_divider_location_horizontal";
    private static final String GUI_DIVIDER_LOCATION_VERTICAL = "gui_divider_location_vertical";
    private static final String KEY_PATH_XPLANET_EXECUTABLE = "key_path_xplanet_executable";
    private static String PATH_XPLANET_EXECUTABLE;
    private static final String KEY_CONFIG_NAME = "key_config_name";
    private static final String KEY_USING_EXPERT_MODE = "key_using_expert_mode";
    private static final String KEY_ALLOW_INTERNET_CONNECTION = "key_allow_internet_connection";
    public static final String KEY_SHOW_HIDE_DIALOG = "key_do_not_show_hide_dialog";
    public static final String KEY_RUN_AT_STARTUP = "key_run_and_hide";
    /*
     * Behaviour for the loaded and saved configuration and command files:
     * <ul>
     * <li>
     * As program quits read the name of the configuration into the preferences during program quite.
     * </li>
     * <li>
     * At program start read the name of the configuration from the preferences.
     * </li>
     * <li>
     * If the config name is empty neither a command file nor a config file is read.
     * Therefor the textfields for the parameters and config file and controls are empty.
     * </li>
     * <li>
     * If the config name found in the user preferences are not empty the command file and the config file is read.
     * The textfields for the parameters and for the config file are filled.
     * </li>
     * <li>
     * The button "save" writes a command file (into directory of xplanet.exe) and a config file
     * into the config directory.
     * </li>
     * </ul>
     */
    private static String CONFIG_NAME;
    private static final String KEY_SUFFIX_CMD_FILE = "key_suffix_cmd_file";
    private static String FILE_EXTENSION_CMD_FILE;
    private static final String COMMENT_COMMAND_LINE_PARAMETERS = "# command line parameters:";
    private static final String COMMENT_COMMAND_LINE_PARAMETERS_REG_EXPR = "(?i)(# command line parameters:)(.*)";
    public static final String FILE_NAME_DOWNLOADER_CONFIG = "downloader.cfg";
    private static final String FILE_NAME_PROXY_CONFIG = "proxy.cfg";
    private static MainFrame instance;
    private Logger logger;
    private DefaultMutableTreeNode currentNode = null;
    private Map treeNodes = new HashMap();
    private FoundExpressions foundExpressions;
    private String findExpression = "";
    private XPlanetStarter xPlanetStarter;
    private DownloadStarter downloadStarter;
    private JPanelControlParametersSimpleConfiguration jPanelSimpleMode;
    private XPlanetSystemTray tray;
    private JPanel jPanelPreview;
    private boolean isPreview;

    /**
     * Creates JFrameMainWindowVisualiser.
     */
    private MainFrame() {
        // Do not warn the user if he starts the application
        logger = Logger.getLogger(this.getClass().getName());
        initComponents();
        new LoggingBoard(this.jTextAreaXPlanetMessages, this.jTextAreaDownloaderMessages);
        // Inits the -searchdir if known
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder(true);
        this.checkWetherXPlanetRessourcesAreKnown();
        this.guessXPlanetExecutable();
        this.loadUserPrefs();
        this.fillComponents();
        // this.board = new LoggingBoard(this.jTextAreaMessages);
        this.getRootPane().setDefaultButton(this.jButtonStart);
        this.toggleExpertMode();
        logger.finer("The application was created with the configuration file.");
        this.checkXPlanetRessources();
        this.checkRunAtStartUp();
    }

    /**
     * Returs an instance of the object
     * The instance will not be created.
     * @return An instance if created Null otherwise.
     */
    public static MainFrame getInstance() {
        if (instance == null) {
            instance = new MainFrame();
        }
        return instance;
    }

    /**
     * Open a frame to configure the logging of the application.
     */
    private void openLoggingConfiguration() {
        JFrameLogginConfigurator frame = JFrameLogginConfigurator.getInstance();
        frame.setVisible(true);
        frame.requestFocus();
        frame.toFront();
    }

    /**
     * Open the Help
     */
    private void openHelpDialog() {
        this.openHelpDialog("/xplanetconfigurator/resources/html/help.html");
    }

    /**
     * Open the Help
     */
    private void openHelpDialog(String url) {
        JFrameHelp d = JFrameHelp.getInstance(
                "Help", url);
        d.setVisible(true);
    }

    /**
     * Open the "About" dialog
     */
    private void openAboutDialog() {
        JDialogAbout d = new JDialogAbout(
                this, "/xplanetconfigurator/resources/html/about.html");
        d.setVisible(true);
    }

    /**
     * Open a Dialog to show information about the system
     */
    private void openSystemInfoDialog() {
        JDialogSystem d = new JDialogSystem(this);
        d.setVisible(true);
        d.requestFocus();
        d.toFront();
    }

    private void checkRunAtStartUp() {
        boolean runAndHide = this.jCheckBoxMenuItemRunAtStartUp.isSelected();
        if(runAndHide) {
//            this.setVisible(false);
//            this.setExtendedState(ICONIFIED);
            this.startXPlanet();
        } else {
//            this.setVisible(true);
//            this.setExtendedState(Frame.NORMAL);
        }
    }

    private void loadUserPrefs() {
        logger.finer("Getting user preferences...");
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());

        int xPos = 50;
        int yPos = 50;
        int with = 960;
        int height = 700;
        int x = prefs.getInt(MainFrame.FRAME_X, xPos);
        int y = prefs.getInt(MainFrame.FRAME_Y, yPos);
        int h = prefs.getInt(MainFrame.FRAME_HEIGHT, height);
        int w = prefs.getInt(MainFrame.FRAME_WIDTH, with);

        this.setSize(new Dimension(w, h));

        if (x == xPos && y == yPos) {
            logger.finer("Position in middle of window. Seems to be used for the first time.");
            this.setLocationRelativeTo(null); //center it
        } else {
            logger.finer("Position of window: x='" + x + "', y='" + y + "'. Size of window: h='" + h + "', w='" + w + "'.");
            this.setLocation(x, y);
        }

        this.restoreMainDividerLocation();
        int i = prefs.getInt(MainFrame.GUI_DIVIDER_LOCATION_VERTICAL, 200);
        this.jSplitPaneTreeControls.setDividerLocation(i);

        // Restore the file extension for command files. They are generated
        // every time the config is saved or started. On Windows this cmd will
        // start XPlanet and the Downloader.
        MainFrame.FILE_EXTENSION_CMD_FILE = prefs.get(MainFrame.KEY_SUFFIX_CMD_FILE, "cmd");
        String osName = System.getProperty("os.name");
        if (osName != null) {
            // Guess for Windows
            if (osName.matches("(?i).*windows.+")) {
                MainFrame.FILE_EXTENSION_CMD_FILE = prefs.get(MainFrame.KEY_SUFFIX_CMD_FILE, "cmd");
            }
            // TODO: Implement for Linux and Mac
        }

        // Restore the config name
        MainFrame.setCONFIG_NAME(prefs.get(MainFrame.KEY_CONFIG_NAME, ""));

        // Restore expert mode or non expert mode
        boolean b = prefs.getBoolean(MainFrame.KEY_USING_EXPERT_MODE, false);
        this.jCheckBoxExpertMode.setSelected(b);

        b = prefs.getBoolean(MainFrame.KEY_ALLOW_INTERNET_CONNECTION, true);
        this.jCheckBoxMenuItemAllowInternetConnection.setSelected(b);

        boolean showHideDialog = prefs.getBoolean(MainFrame.KEY_SHOW_HIDE_DIALOG, true);
        this.setIsShowinHideDialog(showHideDialog);

        boolean runAndHide = prefs.getBoolean(MainFrame.KEY_RUN_AT_STARTUP, false);
        this.jCheckBoxMenuItemRunAtStartUp.setSelected(runAndHide);
    }

    public void setIsShowinHideDialog(boolean show) {
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());
        prefs.putBoolean(MainFrame.KEY_SHOW_HIDE_DIALOG, show);
        this.jCheckBoxMenuItemShowHideDialog.setSelected(show);
    }

    public void setIsRunAtStartup() {
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());
        prefs.putBoolean(MainFrame.KEY_RUN_AT_STARTUP, this.jCheckBoxMenuItemRunAtStartUp.isSelected());
    }
   
    /**
     * Search for the xplanet executable in
     * <ul>
     * <li>The current directory</li>
     * <li>searchdir</li>
     * <li>subdirectories of searchdir</li>
     * <li>subdirectories of xplanet (if it exists in the current directory)</li>
     * <li>subdirectories of ${HOME}/.xplanet on X11</li>
     * <li>subdirectories of ${HOME}/Library/Xplanet on Mac OS X</li>
     * <li>subdirectories of DATADIR/xplanet</li>
     * <li>DATADIR is set at compile time and defaults to /usr/local/share.</li>
     * </ul>
     * The executable must match '(?i)xplanet|xplanet.exe'. If nothing is found
     * the program chooses 'xplanet.exe' for windows and 'xplanet' for Linux and
     * Mac OS without any preceeding path.
     */
    private void guessXPlanetExecutable() {
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());
        String executable = prefs.get(MainFrame.KEY_PATH_XPLANET_EXECUTABLE, null);
        // For first time usage this will set back the xplanet.dir.tested
        MainFrame.setXPLANET_EXECUTABLE(executable);
        if (MainFrame.PATH_XPLANET_EXECUTABLE != null && !"".equals(MainFrame.PATH_XPLANET_EXECUTABLE)) {
            this.logger.finer("Found the absolute path to the XPlanet executable in the user preferences: '" + MainFrame.PATH_XPLANET_EXECUTABLE + "'");
        } else {
            String dir = System.getProperty("user.dir");
            if (dir != null && !"".equals(dir)) {
                this.searchXPlanetExecutable(dir);
            }
        }
    }

    /**
     * The executable must match '(?i)xplanet|xplanet.exe'.
     *
     * @param dir where to search
     * @return true if the absolute path was found.
     */
    private boolean searchXPlanetExecutable(String dir) {
        this.logger.finer("Searching dir '" + dir + "' for the xplanet executable using the regular expression '(?i)xplanet|xplanet.exe'");
        File d = new File(dir);
        File[] files = d.listFiles();
        this.logger.finer("Found " + files.length + " files in the directory");
        for (int i = 0; i < files.length; i++) {
            File f = files[i];
            this.logger.finer("Looking at file '" + f.getAbsolutePath() + "'...");
            if (!f.isFile()) {
                this.logger.finer("'" + f.getAbsolutePath() + "' is not a file.");
                continue;
            }
            if (!f.canExecute()) {
                this.logger.finer("'" + f.getAbsolutePath() + "' can not be executed.");
                continue;
            }
            String filename = f.getName();
            if (filename.matches("(?i)xplanet|xplanet.exe")) {
                this.logger.info("Found/guessed file '" + f.getAbsolutePath() + "' as xplanet executable.");
                String executable = f.getAbsolutePath();
                this.logger.finer("Did guess the executable with '" + executable + "'");
                MainFrame.setXPLANET_EXECUTABLE(executable);
                return true;
            } else {
                this.logger.finer("'" + filename + "' does not match (?i)xplanet|xplanet.exe' as xplanet executable.");
            }
        }
        return false;
    }

    private void checkWetherXPlanetRessourcesAreKnown() {
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        String dir = rf.getXPlanetDirUsed();
        if (dir == null || "".equals(dir)) {
            String msg =
                    "Now starting XPlanet to analyse its output\n" +
                    "to guess the directory it uses for ressources.";
            this.popInfo(msg);
            this.testForXPlanetRessources();
        }
    }

    private void testForXPlanetRessources() {
        String executable = this.getOrGuessXPlanetExecutable();
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        String command = executable + " -config shouldNotExist -verbosity 4" + " -num_times 1";
        String searchdir = rf.getXPlanetSearchDir();
        if (!"".equals(searchdir)) {
            command = command + " -searchdir " + searchdir;
        }
        XPlanetTimer timer = new XPlanetTimer(this, 0, command);
        // Wait for the command. It will write its system.out and system.err
        // into the text area of 'XPlanet Messages'.
        this.jTextAreaXPlanetMessages.setText("");
        timer.exec();
        String messages = this.jTextAreaXPlanetMessages.getText();
        // if a dir was found it a stored automatically
        String dir = rf.getXPlanetDirTested(messages);
        if (dir != null) {
            String msg =
                    "Found the directory XPlanet uses\n" +
                    "to read the config file from. It is:\n" +
                    dir + "\n\n" +
                    "The Configurator will use it to write\n" +
                    "the config file and all ressources.";
            this.popInfo(msg);
        } else {
            String msg =
                    "Did not find the directory XPlanet uses to read the config file from.\n\n" +
                    "Windows:\n" +
                    "- Is the xplanet.jar in the same directory as xplanet.exe?\n\n" +
                    "Linux:\n" +
                    "- Is XPlanet really installed. Check by executing 'xplanet' in the terminal/console.\n\n" +
                    "Or try this:\n" +
                    "1. Tick Checkbox 'Expert Mode'. Than Tree > All > XPlanet > Choose the excutable.\n" +
                    "2. Menu 'Options' > 'Guess XPlanet Ressources'.";
            this.popError(msg);
        }
    }

    private void saveUserPrefs() {
        logger.finer("Saving user preferences...");
        int x = this.getX();
        int y = this.getY();
        Dimension d = this.getSize();
        int h = (int) d.getHeight();
        int w = (int) d.getWidth();

        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());

        // Frame position and size
        prefs.putInt(MainFrame.FRAME_X, x);
        prefs.putInt(MainFrame.FRAME_Y, y);
        prefs.putInt(MainFrame.FRAME_HEIGHT, h);
        prefs.putInt(MainFrame.FRAME_WIDTH, w);
        logger.finer("Saved position of window: x='" + x + "', y='" + y + "'. Size of window: h='" + h + "', w='" + w + "'.");

        this.storeMainDividerLocation();
        prefs.putInt(MainFrame.GUI_DIVIDER_LOCATION_VERTICAL, this.jSplitPaneTreeControls.getDividerLocation());

        String executable = MainFrame.getXPLANET_EXECUTABLE();
        prefs.put(MainFrame.KEY_PATH_XPLANET_EXECUTABLE, executable);
        prefs.put(MainFrame.KEY_SUFFIX_CMD_FILE, MainFrame.FILE_EXTENSION_CMD_FILE);

        prefs.putBoolean(MainFrame.KEY_USING_EXPERT_MODE, this.jCheckBoxExpertMode.isSelected());
        prefs.putBoolean(MainFrame.KEY_ALLOW_INTERNET_CONNECTION, this.jCheckBoxMenuItemAllowInternetConnection.isSelected());

        // Save the config name at "Save" only.
        // prefs.put(MainFrame.KEY_CONFIG_NAME, MainFrame.getCONFIG_NAME());
    }

    private void storeMainDividerLocation() {
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());
        prefs.putInt(MainFrame.GUI_DIVIDER_LOCATION_HORIZONTAL, this.jSplitPaneMainControlsCommand.getDividerLocation());
    }

    private void restoreMainDividerLocation() {
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());
        int i = prefs.getInt(MainFrame.GUI_DIVIDER_LOCATION_HORIZONTAL, 430);
        this.jSplitPaneMainControlsCommand.setDividerLocation(i);
    }

    /**
     * Stop all running processes.
     */
    public void cleanUp() {
        logger.fine("Cleaning up...");
        this.saveUserPrefs();
        this.setVisible(false);
        this.tray.cleanUp();
        this.cleanUpDownloadStarter();
        this.cleanUpXplanetStarter();
        this.dispose();
    }

    private void cleanUpDownloadStarter() {
        this.logger.finer("Cleaning up DownloadStarter...");
        if (this.downloadStarter != null) {
            DownloadTimer downloadTimer = this.downloadStarter.getTimer();
            if (downloadTimer != null) {
                downloadTimer.stopRuning();
            }
            this.logger.finer("About to cancel xPlanetStarter...");
            this.downloadStarter.cancel(true);
        }
    }

    private void cleanUpXplanetStarter() {
        this.logger.finer("Cleaning up XPlanetStarter...");
        if (this.xPlanetStarter != null) {
            XPlanetTimer xPlanetTimer = this.xPlanetStarter.getTimer();
            if (xPlanetTimer != null) {
                xPlanetTimer.stopRuning();
            }
            this.logger.finer("About to cance xPlanetStarter...");
            this.xPlanetStarter.cancel(true);
        }
        // LoggingBoard.clear();
    }

    private void fillComponents() {
        // Read the content of the command file for XPlanet
        // Read the content of the config file for XPlanet
        // Read the content of the config file for the application itself
        // Fill the Tree
        this.createSimpleControlPanel();
        this.createTree();
        this.loadConfigurationFromFiles();
        this.setIconImage(MainFrame.getImage());
        this.tray = new XPlanetSystemTray(this);
    }

    public static Image getImage() {
        URL u = null;
        try {
            u = MainFrame.class.getResource("/xplanetconfigurator/gui/resources/img/mgs.jpg");
            String file = u.getPath();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        Image image = Toolkit.getDefaultToolkit().getImage(u);
        return image;
    }

    public void loadConfigurationFromFiles() {
        // This overwrittes the command line parameters if defined in config file as comment
        this.readConfigFile();
        // Set caret
        this.jTextAreaConfigFile.setCaretPosition(0);
        // Load the downloader
        this.initDownloader();
        // Set caret
        this.jTextAreaDownloader.setCaretPosition(0);
    }

    /**
     * Search for the config file using XPlanets search behaviour.
     * <br>Read the config file.
     * <br>The first line in the config file should contain a commented line.
     * This line contains the command line parameters. Read them too.
     * <br>Fill the text areas for the command line and config file.
     * <br>Fill all Controls all over the GUI.
     */
    private void readConfigFile() {
        // Find the config directory XPlanet would probably use.
        XPlanetRessourceFinder f = new XPlanetRessourceFinder();
        // Do not use the -searchdir.
        // Use the -searchdir from the moment on it is known from the current
        // command line (that is unknowd at this moment, because it is still
        // not loaded from file).
        String configDir = f.getRessourceDirectory("config");
        // Now use the directory
        File cfg = new File(configDir + File.separator + MainFrame.getCONFIG_NAME());
        if (!cfg.exists()) {
            this.logger.fine("Found no config file " + cfg.getAbsolutePath());
            this.selectControlPanel("-config");
            return;
        }
        if (!cfg.isFile()) {
            this.logger.fine("Config file is not a file: " + cfg.getAbsolutePath());
            this.selectControlPanel("-config");
            return;
        }
        FileUtil util = new FileUtil();
        String configParameters = null;
        try {
            configParameters = util.getFileAsString(cfg);
        } catch (Exception ex) {
            this.logger.log(Level.SEVERE, null, ex);
            this.popError("Failed to read config file:\n" + cfg.getAbsolutePath() + "\n\n" + ex.getLocalizedMessage());
            return;
        }
        this.logger.config("Read config file: " + cfg.getAbsolutePath());

        // Read the command line parameters from the config file
        Pattern p = Pattern.compile(MainFrame.COMMENT_COMMAND_LINE_PARAMETERS_REG_EXPR);
        Matcher m = p.matcher(configParameters);
        if (m.find()) {
            String commandLineParameters = m.group(2);
            // Allays let the GUI set the -searchdir
            commandLineParameters = f.replaceSearchDir(commandLineParameters);
            this.jTextAreaCommandLineParameters.setText(commandLineParameters.trim());
            this.logger.finer("Setting command line parameters found in config file: " + cfg.toString());
            configParameters = configParameters.replaceAll(COMMENT_COMMAND_LINE_PARAMETERS_REG_EXPR, "");
            configParameters = COMMENT_COMMAND_LINE_PARAMETERS + commandLineParameters + "\n" + configParameters;
        }
        // Remove all emty lines
        configParameters = configParameters.replaceAll("(?m)^\\s*$^\\s*", "");
        this.jTextAreaConfigFile.setText(configParameters);
    }

    /**
     * Read an example configuration stored in the jar file.
     * Usage in the simple configurator.
     *
     * @param fileInClasspath an example config file stored in the jar file.
     * Example: Big_Moon will read the file /xplanetconfigurator/gui/resources/examples/Bin_Moon
     */
    public void readExampleConfigFile(String fileName) {
        FileUtil util = new FileUtil();
        String dirInClasspath = "/xplanetconfigurator/gui/resources/examples/";
        String file = dirInClasspath + fileName;
        String configParameters = null;
        try {
            configParameters = util.getRessourceAsString(file);
        } catch (Exception ex) {
            this.logger.log(Level.SEVERE, null, ex);
            this.popError("Failed to read example config file:\n" + fileName + "\n\n" + ex.getLocalizedMessage());
            return;
        }
        this.logger.config("Read example config file: " + fileName);
        this.jTextAreaConfigFile.setText(configParameters);

        // Read the command line parameters from the config file
        Pattern p = Pattern.compile(MainFrame.COMMENT_COMMAND_LINE_PARAMETERS_REG_EXPR);
        Matcher m = p.matcher(configParameters);
        if (m.find()) {
            String commandLineParameters = m.group(2);
            this.jTextAreaCommandLineParameters.setText(commandLineParameters.trim());
            this.logger.finer("Setting command line parameters found in example config file: " + fileName);
        }
        setCONFIG_NAME(fileName);
    }

    private void refreshDownloaderTextArea() {
        if (this.downloadStarter != null) {
            String s = this.downloadStarter.getTimer().getConfiguration();
            this.jTextAreaDownloader.setText(s);
        }
    }

    private void createTree() {
        //Create the nodes.
        ControlPanel controlPanel = new JPanelAll();
        controlPanel.setId("All");
        DefaultMutableTreeNode top = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("All", top);
        //Create a tree that allows one selection at a time.tree = new JTree(top);
        this.jTreeMain = new JTree(top);
        this.jTreeMain.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        //Listen for when the selection changes.
        this.jTreeMain.addTreeSelectionListener(this);
        this.jTreeMain.setCellRenderer(new MyRenderer());
        // Add the new JTree to the Parent Component
        jScrollPaneTree.setViewportView(jTreeMain);

        // Create the nodes
        DefaultMutableTreeNode category = null;
        DefaultMutableTreeNode subCategory = null;
        DefaultMutableTreeNode panel = null;

        //-- XPlanet -----------------------------------------------------------
        controlPanel = new JPanelControlParametersXPlanet();
        controlPanel.setId("XPlanet");
        category = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("XPlanet", category);
        top.add(category);

        //-- Parameters ........................................................
        controlPanel = new JPanelDummy();
        controlPanel.setId("Parameters");
        subCategory = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Parameters", subCategory);
        category.add(subCategory);

        controlPanel = new JPanelControlParametersConfig(this);
        controlPanel.setId("-config");
        controlPanel.setRegExpressionForParameters("(?i)(-config)(\\s*)([^-]*)|(-searchdir)(\\s*)([^-]*)");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("-config", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersBody(this);
        controlPanel.setId("Body");
        controlPanel.setRegExpressionForParameters("(?i)((-radius)(\\s*)(\\d*)(\\s*[^-]*))|((-range)(\\s*)(\\d*)(\\s*[^-]*))|((-rotate)(\\s*)(\\d*)(\\s*[^-]*))|((-body)(\\s*)(\\w*)(\\s*[^-]*))|((-target)(\\s*)(\\w*)(\\s*[^-]*))|((-north)(\\s*)(\\w*)(\\s*[^-]*))|((-path_relative_to)(\\s*)(\\w*)(\\s*[^-]*))|((-fov)(\\s*)(\\w*)(\\s*[^-]*))");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Body", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersOrigin(this);
        controlPanel.setId("Origin");
        controlPanel.setRegExpressionForParameters("(?i)(-origin)(\\s*)([^-]*)|(-random)|((-latitude\\b)(\\s*)((-$)|(-[^\\p{Alpha}])*)\\d*)|((-longitude\\b)(\\s*)((-$)|(-[^\\p{Alpha}])*)\\d*)|(-origin_file)(\\s*)([^-]*)|(-interpolate_origin_file)(\\s*)([^-]*)|(-dynamic_origin)(\\s*)([^-]*)");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Origin", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersTime(this);
        controlPanel.setRegExpressionForParameters("(?i)((-date)|(-jdate)|(-light_time)|(-timewarp))(\\s*)([^-]*)");
        controlPanel.setId("Time");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Time", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersLabel(this);
        controlPanel.setRegExpressionForParameters("(?i)((-label)|(-label_string)|(-color)|(-font)|(-fontsize)|(-pango)|(-date_format)|(-gmtlabel)|(-utclabel)|(-tt)|(-labelpos))(\\s*)([^-]*)");
        controlPanel.setId("Label");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Label", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersStars(this);
        controlPanel.setRegExpressionForParameters("(?i)((-log_magstep)|(-base_magnitude)|(-glare)|(-starmap)|(-arc_file)|(-arc_spacing)|(-marker_file)|(-fov))(\\s*)([^-]*)");
        controlPanel.setId("Stars");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Stars", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersSpice(this);
        controlPanel.setRegExpressionForParameters("(?i)((-spice_ephemeris)|(-spice_file))(\\s*)([^-]*)");
        controlPanel.setId("Spice");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Spice", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersProjection(this);
        controlPanel.setRegExpressionForParameters("(?i)((-background)|(-projection)|(-proj_param)|(-starfreq))(\\s*)([^-]*)");
        controlPanel.setId("Projection");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Projection", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersWindow(this);
        controlPanel.setRegExpressionForParameters("(?i)((-center)|(-geometry)|(-window_title)|(-window)|(-vroot)|(-xscreensaver))(\\s*)([^-]*)");
        controlPanel.setId("Window");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Window", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersMoreLayout(this);
        controlPanel.setRegExpressionForParameters("(?i)((-print_ephemeris)|(-quality)|(-transparency)|(-grs_longitude)|(-ephemeris_file))(\\s*)([^-]*)");
        controlPanel.setId("More Layout");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("More Layout", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersExecution(this);
        controlPanel.setRegExpressionForParameters("(?i)((-num_times)|(-wait)|(-fork)|(-hibernate)|(-idlewait)|(-post_command)|(-prev_command))(\\s*)([^-]*)");
        controlPanel.setId("Execution");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Execution", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersOutput(this);
        controlPanel.setRegExpressionForParameters("(?i)((-output)|(-output_start_index)|(-transpng)|(-save_desktop_file)|(-make_cloud_maps)|(-tmpdir)|(-markerbounds))(\\s*)([^-]*)");
        controlPanel.setId("Output");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Output", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlParametersInfo(this);
        controlPanel.setRegExpressionForParameters("(?i)((-verbosity)|(-version))(\\s*)([^-]*)");
        controlPanel.setId("Info");
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Info", panel);
        subCategory.add(panel);

        //-- Config File .......................................................
        controlPanel = new JPanelControlConfigFile(this);
        controlPanel.setId("Config File");
        subCategory = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Config File", subCategory);
        category.add(subCategory);

        // ... Default .........................................................
        String section = "Default";
        controlPanel = new JPanelDummy();
        controlPanel.setId(section);
        String infoText = "<html><p>The default section is the only section that " + "contains the parameters<ul>" + "<li>arc_color</li>" + "<li>arc_file</li>" + "<li>random_origin</li>" + "<li>random_target</li>" + "</ul></p>";
        ((JPanelDummy) controlPanel).setInfoText(infoText);
        DefaultMutableTreeNode subCategorySection = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put(section, subCategorySection);
        subCategory.add(subCategorySection);

        // Add control panels valid for all sections (bodies)
        this.addControlPanelsValidForAllBodies(section, subCategorySection);

        // In [default] only
        controlPanel = new JPanelControlConfigFileArcs(this);
        controlPanel.setRegExpressionForParameters("(?i)(?s)\\[" + section + "\\].*?(arc_color|arc_file)[^\\[]*");
        controlPanel.setId("Arc (" + section + ")");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Arcs (" + section + ")", panel);
        subCategorySection.add(panel);

        // In [default] only
        controlPanel = new JPanelControlConfigFileRandom(this);
        controlPanel.setRegExpressionForParameters("(?i)(?s)\\[" + section + "\\].*?(random_origin|random_target)[^\\[]*");
        controlPanel.setId("Random (" + section + ")");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Random (" + section + ")", panel);
        subCategorySection.add(panel);

        // ... Earth ...........................................................
        section = "Earth";
        controlPanel = new JPanelDummy();
        controlPanel.setId(section);
        infoText = "<html><p>The earth section is the only section that " + "contains the parameters for<ul>" + "<li>clouds</li>" + "<li>satellites</li>" + "</ul></p>";
        ((JPanelDummy) controlPanel).setInfoText(infoText);
        subCategorySection = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put(section, subCategorySection);
        subCategory.add(subCategorySection);

        // In [earth] only
        controlPanel = new JPanelControlConfigFileClouds(this);
        controlPanel.setRegExpressionForParameters("(?i)(?s)\\[" + section + "\\].*?(cloud_map|cloud_ssec|cloud_gamma|cloud_threshold)[^\\[]*");
        controlPanel.setId("clouds (" + section + ")");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("clouds (" + section + ")", panel);
        subCategorySection.add(panel);

        // In [earth] only
        controlPanel = new JPanelControlConfigFileSatellites(this);
        controlPanel.setRegExpressionForParameters("(?i)(?s)\\[" + section + "\\].*?(satellite_file)[^\\[]*");
        controlPanel.setId("satellites (" + section + ")");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("satellites (" + section + ")", panel);
        subCategorySection.add(panel);

        // Add control panels valid for all sections (bodies)
        this.addControlPanelsValidForAllBodies("earth", subCategorySection);

        // All others

        ArrayList bodyNames = new ArrayList();
        bodyNames.add("sun");
        bodyNames.add("mercury");
        bodyNames.add("venus");
        // bodyNames.add("earth");
        bodyNames.add("moon");
        bodyNames.add("mars");
        bodyNames.add("phobos");
        bodyNames.add("deimos");
        bodyNames.add("jupiter");
        bodyNames.add("io");
        bodyNames.add("europa");
        bodyNames.add("ganymede");
        bodyNames.add("callisto");
        bodyNames.add("saturn");
        bodyNames.add("mimas");
        bodyNames.add("enceladus");
        bodyNames.add("tethys");
        bodyNames.add("dione");
        bodyNames.add("rhea");
        bodyNames.add("titan");
        bodyNames.add("hyperion");
        bodyNames.add("iapetus");
        bodyNames.add("phoebe");
        bodyNames.add("uranus");
        bodyNames.add("miranda");
        bodyNames.add("ariel");
        bodyNames.add("umbriel");
        bodyNames.add("titania");
        bodyNames.add("oberon");
        bodyNames.add("neptune");
        bodyNames.add("triton");
        bodyNames.add("nereid");
        bodyNames.add("pluto");
        bodyNames.add("charon");

        Iterator it = bodyNames.iterator();
        while (it.hasNext()) {
            section = (String) it.next();
            // Add control panels valid for all sections (bodies)
            controlPanel = new JPanelDummy();
            controlPanel.setId(section);
            controlPanel.setSection(section);
            ((JPanelDummy) controlPanel).setInfoText(section);
            subCategorySection = new DefaultMutableTreeNode(controlPanel);
            this.treeNodes.put(section, subCategorySection);
            subCategory.add(subCategorySection);

            // Add control panels valid for all sections (bodies)
            this.addControlPanelsValidForAllBodies(section, subCategorySection);
        }

        //-- Configurator ------------------------------------------------------
        controlPanel = new JPanelDownloader();
        controlPanel.setId("Downloader");
        category = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Downloader", category);
        top.add(category);

        // clouds
        controlPanel = new JPanelControlDownloaderClouds(this);
        controlPanel.setId("clouds");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("clouds", panel);
        category.add(panel);

        // markers
        controlPanel = new JPanelControlDownloaderMarkers(this);
        controlPanel.setId("markers");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("markers", panel);
        category.add(panel);

        // satellites
        controlPanel = new JPanelControlDownloaderSatellites(this);
        controlPanel.setId("satellites");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("satellites", panel);
        category.add(panel);

        // arcs
        controlPanel = new JPanelControlDownloaderArcs(this);
        controlPanel.setId("arcs");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("arcs", panel);
        category.add(panel);

        // maps
        controlPanel = new JPanelControlDownloaderMaps(this);
        controlPanel.setId("maps");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("maps", panel);
        category.add(panel);

        // proxy settings
        controlPanel = new JPanelControlDownloaderProxySettings(this);
        controlPanel.setId("proxy");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("proxy", panel);
        category.add(panel);

        // Show the expanded tree
        // this.expandAll(this.jTreeMain, true);
        // Show Panel -config
        // TreeNode nodeToExpand = (TreeNode) this.treeNodes.get("XPlanet");
        // this.expandTree(nodeToExpand, true);
        // this.jTreeMain.setRootVisible(false);

        // Allways select the XPlanet node at program start
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeNodes.get("XPlanet");
        this.currentNode = node;
        this.jTreeMain.setSelectionPath(new TreePath(node));
    }

    private void addControlPanelsValidForAllBodies(String section, DefaultMutableTreeNode subCategory) {
        ControlPanel controlPanel = new JPanelControlConfigFileBody(this);
        controlPanel.setRegExpressionForParameters("(?i)(?s)\\[" + section + "\\].*?(magnify|grid|grid1|grid2|draw_orbit|orbit|orbit_color)[^\\[]*");
        controlPanel.setId("Body (" + section + ")");
        controlPanel.setSection(section);
        DefaultMutableTreeNode panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Body (" + section + ")", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlConfigFileMap(this);
        controlPanel.setRegExpressionForParameters("(?i)(?s)\\[" + section + "\\].*?(\\bimage\\b|\\bmap\\b|\\bcolor\\b|twilight|shade|night_map|specular_map|bump_map|bump_scale|mapbounds)[^\\[]*");
        controlPanel.setId("Map (" + section + ")");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Map (" + section + ")", panel);
        subCategory.add(panel);

        controlPanel = new JPanelControlConfigFileLabellingMarkers(this);
        controlPanel.setRegExpressionForParameters("(?i)(?s)\\[" + section + "\\].*?(text_color|marker_color|marker_file|marker_font|marker_fontsize|max_radius_for_label|min_radius_for_label|min_radius_for_markers)[^\\[]*");
        controlPanel.setId("Labelling / Markers (" + section + ")");
        controlPanel.setSection(section);
        panel = new DefaultMutableTreeNode(controlPanel);
        this.treeNodes.put("Labelling / Markers (" + section + ")", panel);
        subCategory.add(panel);
    }

    public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) this.jTreeMain.getLastSelectedPathComponent();
        if (node == null) {
            return;
        }
        this.logger.finer("Removing current control Panel because the jTree selection changed. Now the select node is: " + node);
        jPanelControls.removeAll();
        Object nodeControl = node.getUserObject();
        ControlPanel controlPanel = (ControlPanel) nodeControl;
        // String name = controlPanel.getId();
        // String s = "Node is leaf named: " + name;
        // this.appendMessage(s);

        GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanelControls.add(controlPanel, gridBagConstraints);
        // I really hate this jTree stuff and are not really willing to understand it.
        // TODO: Change this.
        controlPanel.setVisible(false);
        controlPanel.setVisible(true);
        this.logger.finer("Did set control panel to node: " + node);
        this.selectControlPanel(node);
    }

    private void selectControlPanel(String idControlPanel) {
        Collection coll = this.treeNodes.values();
        Iterator it = coll.iterator();
        while (it.hasNext()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) it.next();
            // Compare the typeId
            String nodeId = node.toString();
            if (nodeId.equals(idControlPanel)) {
                this.selectControlPanel(node);
                break;
            }
        }
    }

    private void selectControlPanel(DefaultMutableTreeNode node) {
        this.currentNode = node;
        this.logger.finer("Setting the selection path (of jTree) for node: " + node);
        this.jTreeMain.setSelectionPath(new TreePath(node));
        // the old selection does not vansich without
        // setVisible(false) and setVisible(true).
        // TODO: Find a solution.
        this.jTreeMain.setVisible(false);
        this.jTreeMain.setVisible(true);
        this.logger.finer("Selected Control Panel for node: " + node);
        // this.expandAll(this.jTreeMain, true);
        this.expandTree(node, null);
        // Show the right panel param or config
        Object nodeControl = node.getUserObject();
        ControlPanel controlPanel = (ControlPanel) nodeControl;
        String section = controlPanel.getSection();
        if (section != null) {
            if (controlPanel.isDownloaderControlPanel()) {
                this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelDownloader);
            } else {
                this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelConfigFile);
                this.setCaretPositionToCurrentSection(section);
            }
        } else {
            if (this.jCheckBoxExpertMode.isSelected()) {
                this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelCommandLineParameters);
            }
        }
    }

    /**
     * If expand is true, expands all nodes in the tree.
     * Otherwise, collapses all nodes in the tree.
     */
    private void expandAll(JTree tree, boolean expand) {
        TreeNode root = (TreeNode) tree.getModel().getRoot();
        // Traverse tree from root
        expandAll(tree, new TreePath(root), expand);
    }

    private void expandAll(JTree tree, TreePath parent, boolean expand) {
        // Traverse children
        TreeNode node = (TreeNode) parent.getLastPathComponent();
        if (node.getChildCount() >= 0) {
            for (Enumeration e = node.children(); e.hasMoreElements();) {
                TreeNode n = (TreeNode) e.nextElement();
                TreePath path = parent.pathByAddingChild(n);
                expandAll(tree, path, expand);
            }
        }
        // Expansion or collapse must be done bottom-up
        if (expand) {
            tree.expandPath(parent);
        } else {
            tree.collapsePath(parent);
        }
    }

    /**
     *
     * @param node
     * @param list
     */
    private void expandTree(TreeNode node, List list) {
        if (list == null) {
            list = new ArrayList();
        }
        TreeNode parent = node.getParent();
        if (parent != null) {
            this.expandTree(parent, list);
        } else {
            // is root
            list.add(this.jTreeMain.getModel().getRoot());
            return;
        }
        Object[] nodes = list.toArray();
        this.jTreeMain.expandPath(new TreePath(nodes));
        Rectangle rect = this.jTreeMain.getPathBounds(new TreePath(nodes));
        if (rect != null) {
            // TODO: Make this work.
            this.jScrollPaneTree.scrollRectToVisible(rect);
        }
        list.add(node);
    }

    private void reloadAllControllPanels() {
        Iterator it = this.treeNodes.values().iterator();
        while (it.hasNext()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) it.next();
            Object nodeControl = node.getUserObject();
            ControlPanel controlPanel = (ControlPanel) nodeControl;
            controlPanel.receiveCommandLineParameters();
        }
    }

    public void setFindExpr(String s) {
        this.findExpression = s;
        this.find();
    }

    private void find() {
        List controlPanels = new ArrayList();
        Iterator it = this.treeNodes.values().iterator();
        while (it.hasNext()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) it.next();
            Object nodeControl = node.getUserObject();
            ControlPanel controlPanel = (ControlPanel) nodeControl;
            controlPanels.add(controlPanel);
        }
        ExpressionFinder finder = new ExpressionFinder(this.findExpression, controlPanels);
        this.foundExpressions = finder.find();
        this.findNext();
    }

    private void findNext() {
        if (this.foundExpressions == null) {
            return;
        }
        Selection selection = this.foundExpressions.next();
        ISearchable seachable = selection.getSearchable(); // The ControlPanel
        int start = selection.getStart();
        int end = selection.getEnd();
        String idControlPanel = selection.toString();
        this.selectControlPanel(idControlPanel);
        JTextComponent textComponent = seachable.getTextComponent();
        // textComponent.setEditable(true);
        // textComponent.requestFocus();
        textComponent.setCaretColor(Color.BLUE);
        textComponent.setSelectionStart(start);
        textComponent.setCaretPosition(start);
        textComponent.setSelectionEnd(end);
        textComponent.requestFocus();
    }

    /**
     * ... and by the way switch the focus to the text area of the parameters.
     * @return
     */
    public String getParameters() {
        // this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelCommandLineParameters);
        String parameters = this.jTextAreaCommandLineParameters.getText();
        return parameters;
    }

    public void setDownloaderConfiguration(String config) {
        if (this.downloadStarter != null) {
            this.downloadStarter.getTimer().setConfiguration(config);
        }
        this.refreshDownloaderTextArea();
    }

    /**
     * Get the parameters for the downloader from the text area.
     * @return
     */
    public String getDownloaderConfig() {
        if (this.downloadStarter == null) {
            this.initDownloader();
            if (this.downloadStarter == null) {
                this.logger.warning("Download timer could not be initialised.");
                return "";
            }
        }
        DownloadTimer timer = this.downloadStarter.getTimer();
        String parameters = timer.getConfiguration();
        return parameters;
    }

    /**
     * ... and by the way switch the focus to the text area of the parameters.
     * @return
     */
    public String getConfigParameters() {
        // this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelCommandLineParameters);
        String parameters = this.jTextAreaConfigFile.getText();
        return parameters;
    }

    private void sendParametersToControlsAndSelect() {
        this.jButtonSave.setEnabled(true);
        this.jMenuItemSave.setEnabled(true);
        String parameters = this.jTextAreaCommandLineParameters.getText();
        String lastParamBeforCaret = this.getLastParameterBeforCaretPosition();
        Collection coll = this.treeNodes.values();
        Iterator it = coll.iterator();
        while (it.hasNext()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) it.next();
            ControlPanel controlPanel = (ControlPanel) node.getUserObject();
            try {
                // Check wether the control panel finds itself (its parameters)
                // in the text (parameters) of the text area
                boolean found = controlPanel.receiveCommandLineParameters(parameters);
                if (!found) {
                    continue;
                }
                // Yes, the control panel found itself (its parameters) in the
                // text of the text area.
                // Now check if the caret position points at one of the parameters
                // of the control panel. If true (found) then
                // select the Control Panel (where the user types or clicks)
                if (lastParamBeforCaret != null) {
                    boolean hasFound = controlPanel.findParameterString(lastParamBeforCaret);
                    if (hasFound) {
                        this.selectControlPanel(node);
                        break;
                    } else {
                        continue;
                    }
                }
                this.selectControlPanel(node);
                break;
            } catch (XPlanetException ex) {
                this.logger.log(Level.SEVERE, null, ex);
                this.popError(ex.getMessage());
            }
        }
    }

    private void sendParametersToConfigFileControlsAndSelect() {
        this.jButtonSave.setEnabled(true);
        this.jMenuItemSave.setEnabled(true);
        String parameters = this.jTextAreaConfigFile.getText();
        String sectionAndParameter = this.getSectionAndParameterAtCaretPosition();
        if (sectionAndParameter == null) {
            this.logger.finer("Did not found section with parameter. Do not select any control panel for the config file.");
            return;
        }
        Collection coll = this.treeNodes.values();
        Iterator it = coll.iterator();
        while (it.hasNext()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) it.next();
            ControlPanel controlPanel = (ControlPanel) node.getUserObject();
            // Check wether the control panel finds itself (its parameters)
            // in the text (parameters) of the text area
            boolean hasFound = controlPanel.findParameterString(sectionAndParameter);
            if (hasFound) {
                this.selectControlPanel(node);
                try {
                    // Fill the controls (textfields, checkboxes) of the control
                    boolean found = controlPanel.receiveCommandLineParameters(parameters);
                    // Check to be sure.
                    if (!found) {
                        this.logger.severe("Something went wrong. The control panel found ist parameters at caret position but not in all the parameters of the config file.");
                    }
                } catch (XPlanetException ex) {
                    this.logger.log(Level.SEVERE, null, ex);
                }
                break;
            } else {
                continue;
            }
        }
    }

    private void sendParametersToDownloaderControlsAndSelect() {
        String parameters = this.downloadStarter.getTimer().getConfiguration();
        String id = "clouds";
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) this.treeNodes.get(id);
        ControlPanel controlPanel = (ControlPanel) node.getUserObject();
        // Check wether the control panel finds itself (its parameters)
        // in the text (parameters) of the text area
        this.selectControlPanel(node);
        try {
            boolean found = controlPanel.receiveCommandLineParameters(parameters);
            // Check to be sure.
            if (!found) {
                this.logger.severe("Something went wrong. The control panel found ist parameters at caret position but not in all the parameters of the config file.");
            }
        } catch (XPlanetException ex) {
            this.logger.log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Download one file
     * @param typeId String like 'maps.earth'
     */
    public synchronized void startDownloaderOnce(String typeId) {
        // The downloader will figure out what it takes: the string or the list
        this.startDownloader(typeId, null, true);
        // Bring the messages of the downloader to front only if the user
        // pressed the download button explicitly. If the downloader is
        // started along with XPlanet it should play the second role for the
        // user.
        this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelMessagesDownloader);
    }

    /**
     * Download more than on file
     * @param typeIDs List of Strings like 'maps.earth' or 'maps.moon'
     */
    public synchronized void startDownloaderOnce(List typeIDs) {
        // The downloader will figure out what it takes: the string or the list
        this.startDownloader(null, typeIDs, true);
        // Bring the messages of the downloader to front only if the user
        // pressed the download button explicitly. If the downloader is
        // started along with XPlanet it should play the second role for the
        // user.
        this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelMessagesDownloader);
    }

    /**
     *
     * @param typeId Download one file. Value like 'markers.volcanos'. Can be null.
     * @param typeIDs Download more than one file. Value like 'markers.volcanos'. Can be null.
     * @param startOnceAndLeave If true the  downloader will download the type.id (parameter typeId) or
     * the list of type.id (parameter typeIDs) and finish. If false the downloader
     * is checking all URLs and downloading if due for update until it gets a stop
     * command.
     */
    public void startDownloader(String typeId, List typeIDs, boolean startOnceAndLeave) {
        // Use a new instance of the downloader
        // Otherwise it will get problems if more than one download is
        // started by the user via the GUI to test the download.
        // The second download would not start.
        DownloadTimer timer = this.initDownloader(); // Creates a new instance
        // Set the Downloader. It will do all the work started as Thread.
        timer.setFeedbackReceiver(this);
        // Choose how often the timer checks if something has to be downloaded
        timer.setSeconds(300)// Every 5 minutes
        timer.setCurrentDownloadTypeId(typeId);
        // Set the list of type Ids, e.g. maps.earth or maps.moon
        // If null the downloader will ignore the list and take the type.id
        timer.setCurrentDownloadTypeIDs(typeIDs);
        timer.setRunOnceAndLeave(startOnceAndLeave);
        // The starter is needed due to the SwingWorkerStuff. Main Purpose:
        // the GUI must not freeze.
        DownloadStarter starter = new DownloadStarter();
        starter.setTimer(timer);
        starter.execute();
    }

    /**
     * This is not for starting the download. The downloader reads in its
     * configuration file. The GUI needs the configuration of the downloader
     * to fill the control panels. The user can configure the downloader via
     * the control panels of the downloader.
     */
    private DownloadTimer initDownloader() {
        this.cleanUpDownloadStarter();
        XPlanetRessourceFinder f = new XPlanetRessourceFinder();
        String dirOnDisc = f.getRessourceDirectory("downloader");
        String cfgFileDownload = dirOnDisc + File.separator + MainFrame.FILE_NAME_DOWNLOADER_CONFIG;
        DownloadTimer downloadTimer = new DownloadTimer(cfgFileDownload);
        this.downloadStarter = new DownloadStarter();
        this.downloadStarter.setTimer(downloadTimer);
        // Fill the text area
        this.refreshDownloaderTextArea();
        return downloadTimer;
    }

    private void popError(String message) {
        JOptionPane.showMessageDialog(this, message, "XPlanet - Error", JOptionPane.ERROR_MESSAGE);
    }

    private void popInfo(String message) {
        JOptionPane.showMessageDialog(this, message, "XPlanet - Info", JOptionPane.INFORMATION_MESSAGE);
    }

    private String getLastParameterBeforCaretPosition() {
        int caretPosition = this.jTextAreaCommandLineParameters.getCaretPosition();
        String parameters = this.jTextAreaCommandLineParameters.getText();
        String beforCaret = parameters.substring(0, caretPosition);
        String s = null;
        // -config Earth_Clouds_Big_Moon -latitude -333 -origin sun -longitude 444
        // The user could click anywhere in '-latitude -333'
        String regExp = "(.*)(-[^\\d].*)";
        Pattern p = Pattern.compile(regExp);
        Matcher matcher = p.matcher(beforCaret);
        if (matcher.find()) {
            String found = matcher.group(2);
            if (found != null && !"".equals(found)) {
                beforCaret = found;
            }
        }
        String afterCaret = parameters.substring(caretPosition, parameters.length());
        if (afterCaret.contains("-")) {
            int i = afterCaret.indexOf("-");
            afterCaret = afterCaret.substring(0, i);
        }
        s = beforCaret + afterCaret;
        return s;
    }

    private String getSectionAndParameterAtCaretPosition() {
        int caretPosition = this.jTextAreaConfigFile.getCaretPosition();
        String parameters = this.jTextAreaConfigFile.getText();
        String beforCaret = parameters.substring(0, caretPosition);
        String afterCaret = parameters.substring(caretPosition, parameters.length());
        // Get all text befor until including own section (next one in front)
        Pattern p = Pattern.compile("(?i)(?s)\\[\\w+\\][^\\[]*");
        Matcher m = p.matcher(beforCaret);
        String lastFoundSection = null;
        while (m.find()) {
            // Take the last found
            lastFoundSection = m.group();
        }
        if (lastFoundSection == null) {
            return null;
        }
        // Store the section
        p = Pattern.compile("(?i)\\[\\w+\\]");
        m = p.matcher(lastFoundSection);
        String section = null;
        if (m.find()) {
            section = m.group(); // will always be found
        }
        // Get the text from the caret to the begin of the line
        // Do not care about if the paramter is commented by #
        p = Pattern.compile(".+");
        m = p.matcher(lastFoundSection);
        String caretToBeginOfLine = "";
        while (m.find()) {
            // Take the last found
            caretToBeginOfLine = m.group(); // will always be found
        }
        // Get the text from caret to the end of the line
        p = Pattern.compile("\\S+");
        m = p.matcher(afterCaret);
        String caretToEndOfString = "";
        if (m.find()) {
            // Take the first found
            caretToEndOfString = m.group(); // will always be found
        }
        // return a String containing of the section and parameter-value-pair
        String s = section + caretToBeginOfLine + caretToEndOfString;
        return s;
    }

    /**
     * Save the command file and the config file. Write the command file into
     * the directory of the xplanet executable. The file name is the name of the
     * configuration with the suffix given by the user. Write the config file
     * to the config directory. The file name is the same as the name of the
     * configuration without file ending (suffix).
     */
    private void save() {
        // At the moment windows command files are written only
        // TODO: Add other operating systems like mac and linux.
        this.saveWindowsCommandFile();
        this.saveConfigFile();
        this.downloadStarter.getTimer().saveConfiguration();
        // Read the config file again to refresh the command line parameters in the comment lin
        this.readConfigFile();
    }

    private void saveWindowsCommandFile() {
        // Command file ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // Find the config directory XPlanet would probably use.
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        // Do not use the -searchdir.
        // The Configurator will be confused when loading a config from the
        // drow downlist. -searchdir is a command line parameter. And the
        // command line parameters are a commented line in the config file.
        // Therefor it is not possible for the Configurator to know the correct
        // -searchdir in befor loading the configuration or put it the other way
        // around. -searchdir will lead to a storage of the configuration file
        // under some directory and not in the directory the Configurator will
        // know of. It will never find and load the configuration... The GUI
        // warns the user of this fact.
        String configDir = rf.getRootDirectoryForDownloads();
        if (MainFrame.getCONFIG_NAME().equals("")) {
            this.logger.fine("Found no config name.");
            // this might not be an error if the configuration is empty
            String parameters = this.getConfigParameters();
            // Check if only comments are in it
            String checkString = parameters.replaceAll("(?m)^\\s*#.*$", "");
            checkString = checkString.trim();
            if (!checkString.equals("")) {
                this.popError(
                        "You choose parameters that have\n" +
                        "to be saved in a configuration file.\n" +
                        "Please give a config name if.");
                // Change to corresponding Control Panel
                this.selectControlPanel("-config");
                return;
            }
        }
        // Assemble the file name
        String cmdFile = configDir + File.separator + MainFrame.getCONFIG_NAME() + ".cmd";
        File cmd = new File(cmdFile);
        FileUtil util = new FileUtil();
        // Read the parameters from the text area
        String parameters = this.jTextAreaCommandLineParameters.getText();
        // Insert the xplanet exectable at the beginning
        String executable = MainFrame.getXPLANET_EXECUTABLE();
        if (executable != null && !"".equals(executable)) {
            // Check for blanks under Windows
            String osName = System.getProperty("os.name");
            if (osName.matches("(?i).*windows.+")) {
                if (executable.contains(" ")) {
                    executable = "\"" + executable + "\"";
                    this.logger.finer("The windows executable '" + executable + "' contained blanks and where surroundet by \"");
                }
            }
        } else {
            executable = this.guessNameOfExecutable();
        }
        parameters = executable + " " + parameters;
        // insert the downloader
        String javacall = "start \"Downloader\" java -jar xplanet.jar -nogui";
        parameters = javacall + "\n" + parameters;
        this.logger.fine("Writing command file: " + cmdFile);
        try {
            util.printFile(cmdFile, parameters);
        } catch (Exception ex) {
            this.logger.log(Level.SEVERE, null, ex);
            this.popError("Failed to write command file:\n" + cmd.getAbsolutePath() + "\n\n" + ex.getLocalizedMessage());
            return;
        }
    }

    private void saveConfigFile() {
        // Config file +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        String configDir = rf.getRessourceDirectory("config");
        String filename = MainFrame.getCONFIG_NAME();
        if (filename != null && !filename.equals("")) {
            // do nothing
        } else {
            this.logger.fine("No file name for the config file is given. No config file will be written.");
            return;
        }
        String configFile = configDir + File.separator + filename;
        String configFileContent = this.jTextAreaConfigFile.getText();

        // Write the command line parameters as comment
        Pattern p = Pattern.compile(MainFrame.COMMENT_COMMAND_LINE_PARAMETERS_REG_EXPR);
        Matcher m = p.matcher(configFileContent);
        String parameters = this.jTextAreaCommandLineParameters.getText();
        String replacement = MainFrame.COMMENT_COMMAND_LINE_PARAMETERS + " " + parameters;
        if (m.find()) {
            // Replace the command line parameters
            configFileContent = configFileContent.replaceAll(MainFrame.COMMENT_COMMAND_LINE_PARAMETERS_REG_EXPR, replacement);
        } else {
            // Insert
            configFileContent = replacement + "\n" + configFileContent;
        }

        this.logger.fine("Writing config file: " + configFile);
        FileUtil util = new FileUtil();
        try {
            util.printFile(configFile, configFileContent);
        } catch (Exception ex) {
            this.logger.log(Level.SEVERE, null, ex);
            this.popError("Failed to write config file:\n" + configFile + "\n\n" + ex.getLocalizedMessage());
            return;
        }

        // Load the configurations into the list of the Control Panel "-config"
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) this.treeNodes.get("-config");
        JPanelControlParametersConfig panel = (JPanelControlParametersConfig) node.getUserObject();
        panel.loadConfigNames();

        // Save for the next start of the application
        OwnPreferences prefs = OwnPreferences.userNodeForPackage(this.getClass());
        prefs.put(MainFrame.KEY_CONFIG_NAME, MainFrame.getCONFIG_NAME());

        // Show that save succeeded
        this.jButtonSave.setEnabled(false);
        this.jMenuItemSave.setEnabled(false);
    }

    /**
     * Set the parameters. A control panel should do this if its parameters change.
     * @param parameters
     */
    public void setParameters(String parameters) {
        Component[] comps = this.jTabbedPaneMainControlsCommand.getComponents();
        for (int i = 0; i < comps.length; i++) {
            JPanel p = (JPanel) comps[i];
            if (p == this.jPanelCommandLineParameters) {
                this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelCommandLineParameters);
            }
        }
        parameters = parameters.replaceAll("\\s{2,}", " ");
        this.jTextAreaCommandLineParameters.setText(parameters.trim());
        // Content of Parameters changed
        this.jButtonSave.setEnabled(true);
        this.jMenuItemSave.setEnabled(true);
    }

    public String getConfigText() {
        return this.jTextAreaConfigFile.getText();
    }

    public void replaceConfigSection(String section, String textSection) {
        String oldText = this.jTextAreaConfigFile.getText();
        String regExprSection = "(?i)(?s)\\[" + section + "\\][^\\[]*";
        String newText = "";
        Pattern p = Pattern.compile(regExprSection);
        Matcher m = p.matcher(oldText);
        if (!m.find()) {
            // Section not in config
            if (section.equalsIgnoreCase("default")) {
                // Insert at begin but after comment lines
                Pattern p1 = Pattern.compile("(?i)(?s)([^\\[]*)(.*)"); // Ignore all until the first "["
                Matcher m1 = p1.matcher(oldText);
                if (m1.find()) {
                    String textBeforFirstSection = m1.group(1); // May contain the comment line with command line parameters
                    String textFromFristSectionToEnd = m1.group(2);
                    newText = textBeforFirstSection + "\n" + textSection + "\n" + textFromFristSectionToEnd;
                }
            } else {
                // Append to text
                newText = oldText + "\n" + textSection;
            }
        } else {
            // Section in config. Replace it.
            newText = oldText.replaceAll(regExprSection, textSection);
        }
        // Remove all empty lines
        newText = newText.replaceAll("(?m)^\\s*$^\\s*", "");
        // Now replace all spaces in curly braces
        p = Pattern.compile("\\{.+\\}");
        m = p.matcher(newText);
        while (m.find()) {
            String s = m.group();
            // Replace
            String replacement = s.replaceAll("\\s+", "");
            // Escape { and }
            s = s.replaceAll("\\{", "\\\\{");
            s = s.replaceAll("\\}", "\\\\}");
            newText = newText.replaceAll(s, replacement);
        }
        // Remove empty sections
        p = Pattern.compile("(?s)\\[\\w+?\\][^\\[]*");
        m = p.matcher(newText);
        List startEndIndices = new ArrayList();
        while (m.find()) {
            String s = m.group();
            // Replace
            if (s.indexOf("=") < 0) {
                // No key value pair found. Store for later removal.
                startEndIndices.add(s);
            }
        }
        if (!startEndIndices.isEmpty()) {
            int size = startEndIndices.size();
            for (int i = size; i > 0;) {
                String s = (String) startEndIndices.get(--i);
                int startIndex = newText.indexOf(s);
                String firstPart = newText.substring(0, startIndex);
                String secondPart = newText.substring(startIndex + s.length(), newText.length());
                newText = firstPart + secondPart;
            }
        }
        this.jTextAreaConfigFile.setText(newText.trim());
        // Show the text area in the tabbed pane

        Component[] comps = this.jTabbedPaneMainControlsCommand.getComponents();
        for (int i = 0; i < comps.length; i++) {
            JPanel panel = (JPanel) comps[i];
            if (panel == this.jPanelCommandLineParameters) {
                this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelConfigFile);
                this.setCaretPositionToCurrentSection(section);
                break;
            }
        }

        // Content of config changed
        this.jButtonSave.setEnabled(true);
        this.jMenuItemSave.setEnabled(true);
    }

    private void setCaretPositionToCurrentSection(String section) {
        if (this.jTextAreaConfigFile.hasFocus()) {
            return;
        }
        String text = this.jTextAreaConfigFile.getText();
        // Scroll to section
        int caretPosition = text.indexOf("[" + section.toLowerCase() + "]");
        if (caretPosition > -1) {
            this.jTextAreaConfigFile.setCaretPosition(caretPosition);
        }
    }

    private void openFindDialog() {
        JDialogFind dialog = new JDialogFind(this, true, this.findExpression);
        dialog.setVisible(true);
    }

    private void chooseXPlanetExecutable() {
        JFileChooser fc = new JFileChooser();
        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        // The jar file must reside in the same directory as xplanet.exe
        String sDir = System.getProperty("user.dir");
        File selectedFile = new File(sDir);
        fc.setSelectedFile(selectedFile);
        int returnVal = fc.showOpenDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            String fileName = file.getName();
            this.logger.fine("The user choose '" + fileName + "' as executable for xplanet.");
            MainFrame.setXPLANET_EXECUTABLE(fileName);
        } else {
            this.logger.fine("The user did not choose the xplanet executable.");
        }
    }

    private void startXPlanetTimer() {
        this.logger.finer("Start of XPlanetTimer was triggered.");
        this.hidePreviewPanel();
        this.cleanUpXplanetStarter();
        // Save the config to file. Otherwise it will have no effect
        this.save();
        String parameters = this.jTextAreaCommandLineParameters.getText();
        // Get the wait seconds
        int sec = 600;
        Pattern p = Pattern.compile("(?i)(-wait\\b)(\\s*)([^-]*)");
        Matcher m = p.matcher(parameters);
        if (m.find()) {
            String seconds = m.group(3);
            seconds = seconds.trim();
            if (!seconds.equals("")) {
                sec = (new Integer(seconds)).intValue();
                if (sec < 9) {
                    this.logger.fine("Setting -wait from " + sec + " to 10 seconds for the execution by the configurator...");
                    sec = 10;
                }
            }
        } else {
            sec = -1;
        }
// Remove the wait seconds.
        parameters = parameters.replaceAll("(?i)(-wait\\b)(\\s*)([^-]*)", "");
        this.logger.finer("Parameters after removing -wait: " + parameters);
        if (this.isIsPreview()) {
            // insert the dimension first just in case the path of the preview
            // image contains a "-" character. This would confuse the replacement
            // that depends on a regular expression using "-" to distinguish
            // between parameters.
            parameters = this.insertDimensionOfPreviewImage(parameters);
            parameters = this.insertPreviewImage(parameters);
        }
        // Add
        // - xplanet executable
        // - the "-num_times 1". The xplanet.exe should run once only.
        String executable = this.getOrGuessXPlanetExecutable();
        String command = executable + " " + parameters + " -num_times 1";
        this.logger.finer("Starting timer (" + sec + " seconds) for XPlanet...");
        XPlanetTimer xPlanetTimer = new XPlanetTimer(this, sec, command);
        xPlanetTimer.setFeedbackReceiver(this.instance);
        this.xPlanetStarter = new XPlanetStarter();
        this.xPlanetStarter.setTimer(xPlanetTimer);
        this.xPlanetStarter.execute();
        this.jTabbedPaneMainControlsCommand.setSelectedComponent(this.jPanelMessagesXPlanet);
        this.jMenuItemStart.setText("Restart XPlanet");
        this.jButtonStart.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/Refresh24.gif"))); // NOI18N
        this.jMenuItemStop.setEnabled(true);
        this.jButtonStop.setEnabled(true);
    }

    private String getOrGuessXPlanetExecutable() {
        this.logger.finer("Get or guess xplanet executable...");
        String executable = MainFrame.getXPLANET_EXECUTABLE();
        String osName = System.getProperty("os.name");
        this.logger.finer("os.name is: " + osName);
        if (osName == null) {
            this.logger.warning("No System Property 'os.name' found. This should never happen.");
            this.popError("No executable for xplanet given.\nAnd no System Property 'os.name' found.\nThis should never happen.");
            return null;
        }
        if (executable != null && !"".equals(executable)) {
            this.logger.finer("Found '" + executable + "' as executable.");
            // Check for blanks under Windows
            if (osName.matches("(?i).*windows.*")) {
                if (executable.contains(" ")) {
                    executable = "\"" + executable + "\"";
                    this.logger.finer("The windows executable '" + executable + "' contained blanks and where surroundet by \"");
                }
            }
        } else {
            // Suppose it is installed and in the path variable
            executable = this.guessNameOfExecutable();
        }
        return executable;
    }

    private String guessNameOfExecutable() {
        this.logger.finer("Guessing the name of the xplanet executable...");
        String osName = System.getProperty("os.name");
        this.logger.finer("os.name is: " + osName);
        // Guess for Windows
        String executable = null;
        if (osName.matches("(?i).*windows.+")) {
            executable = "xplanet.exe";
        } else if (osName.matches("(?i).*linux.*")) {
            executable = "xplanet";
        } else if (osName.matches("(?i).*mac.+")) {
            executable = "xplanet";
        } else {
            executable = "xplanet";
            this.logger.warning("No operating System found. Please check ths source code (this program).");
        }
        this.logger.finer("Did guess '" + executable + "' as executable.");
        return executable;
    }

    public void startXPlanet() {
        this.startXPlanet(false);
    }

    private void startXPlanet(boolean previewMode) {
        this.setIsPreview(previewMode);
        this.startXPlanetTimer();
        if (this.jCheckBoxMenuItemAllowInternetConnection.isSelected()) {
            this.startDownloader(null, null, false);
        }
        this.tray.setCheckBoxRun(true);
    }

    public void stopXPlanet() {
        this.logger.finer("Stop of XPlanetTimer was triggered.");
        this.cleanUpXplanetStarter();
        this.cleanUpDownloadStarter();
        this.jMenuItemStart.setText("Start XPlanet");
        this.jButtonStart.setIcon(new javax.swing.ImageIcon(getClass().getResource("/xplanetconfigurator/gui/resources/img/Play24.gif"))); // NOI18N
        this.jMenuItemStop.setEnabled(false);
        this.jButtonStop.setEnabled(false);
        this.tray.setCheckBoxRun(false);
    }

    /**
     * Feedback after download
     * Refreshes all control panels by sending them the configuration
     */
    public void receiveDownloaderFeedback() {
        Iterator it = this.treeNodes.values().iterator();
        while (it.hasNext()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) it.next();
            ControlPanel controlPanel = (ControlPanel) node.getUserObject();
            if (controlPanel.isDownloaderControlPanel()) {
                // Update the control panels for new status
                String parameters = this.downloadStarter.getTimer().getConfiguration();
                try {
                    // This sets the values of the controls (labels, text fields,...)
                    controlPanel.receiveCommandLineParameters(parameters);
                } catch (XPlanetException ex) {
                    Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        }
    }

    /**
     * Receive feedback from the XPlanetTimer after excecution of xplanet
     * and if the return code of xplanet = 0.
     */
    public void receiveXPlanetFeedback() {
        this.logger.fine("XPlanet was successfully executed. Receiving feedback from the GUI.");
        if (this.isIsPreview()) {
            this.logger.finer("In preview mode.");
            this.showPreviewPanel();
        } else {
            this.logger.finer("No in preview mode.");
        }
    }

    private void toggleExpertMode() {
        this.storeMainDividerLocation();
        // Toolbar
        boolean b = this.jCheckBoxExpertMode.isSelected();
        this.jButtonFind.setEnabled(b);
        this.jMenuItemFind.setEnabled(b);
        this.jButtonFindAgain.setEnabled(b);
        this.jMenuItemFindAgain.setEnabled(b);
        // Panels showing config and messages
        if (this.jCheckBoxExpertMode.isSelected()) {
            this.jTabbedPaneMainControlsCommand.addTab("Command Line Parameters", this.jPanelCommandLineParameters);
            this.jTabbedPaneMainControlsCommand.addTab("Config File (-config)", this.jPanelConfigFile);
            this.jTabbedPaneMainControlsCommand.addTab("Downloader", this.jPanelDownloader);
            this.jSplitPaneMainControlsCommand.remove(this.jPanelSimpleMode);
            this.jSplitPaneMainControlsCommand.setLeftComponent(this.jPanelMainTreeControls);
            this.reloadAllControllPanels();
        } else {
            this.jTabbedPaneMainControlsCommand.remove(this.jPanelCommandLineParameters);
            this.jTabbedPaneMainControlsCommand.remove(this.jPanelConfigFile);
            this.jTabbedPaneMainControlsCommand.remove(this.jPanelDownloader);
            jSplitPaneMainControlsCommand.remove(this.jPanelMainTreeControls);
            this.jSplitPaneMainControlsCommand.setLeftComponent(this.jPanelSimpleMode);
            this.jPanelSimpleMode.receiveCommandLineParameters();
        }

        this.restoreMainDividerLocation();
    }

    private void preview() {
        this.startXPlanet(true);
    }

    private void hidePreviewPanel() {
        if (this.jPanelPreview != null) {
            this.jPanelMainControlsCommand.remove(this.jPanelPreview);
            this.jPanelPreview = null;
            XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
            String previewImage = rf.getPreviewImage();
            File f = new File(previewImage);
            if (!f.delete()) {
                this.logger.fine("Failed to delete preview file.");
            }
        }
        this.myRepaint();
    }

    private void showPreviewPanel() {
        this.hidePreviewPanel();
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        String previewImage = rf.getPreviewImage();
        File f = new File(previewImage);
        if (f.exists() && f.isFile()) {
            long modified = f.lastModified();
            String timeStamp = TimeStamp.getTimestamp("yyyy-MM-dd HH:mm:ss.SSS", new Date(modified));
            Dimension d = this.getDimensionPreviewImage();
            JPanel jPanelPreviewTemp = new javax.swing.JPanel();
            jPanelPreviewTemp.setMinimumSize(d);
            jPanelPreviewTemp.setPreferredSize(d);
            jPanelPreviewTemp.setMaximumSize(d);
            jPanelPreviewTemp.setLayout(new java.awt.BorderLayout());
            JLabel jLabelPreview = new javax.swing.JLabel();
            jLabelPreview.setMinimumSize(d);
            jLabelPreview.setPreferredSize(d);
            jLabelPreview.setMaximumSize(d);
//            jLabelPreview.setIcon(new javax.swing.ImageIcon(f.getAbsolutePath() + "wrong"));
            jLabelPreview.setIcon(new javax.swing.ImageIcon(f.getAbsolutePath()));
            jLabelPreview.setToolTipText(
                    "<html>Preview last modified: " + timeStamp + "<br>Saved to: " + f.getAbsolutePath() + "<br><br>Click to hide the Image.");
            jPanelPreviewTemp.add(jLabelPreview, java.awt.BorderLayout.CENTER);
            GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
            gridBagConstraints.gridx = 1;
            gridBagConstraints.gridy = 0;
            this.jPanelMainControlsCommand.add(jPanelPreviewTemp, gridBagConstraints);

            jLabelPreview.addMouseListener(new java.awt.event.MouseAdapter() {

                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    hidePreviewPanel();
                }
            });
            this.jPanelPreview = jPanelPreviewTemp;
            this.myRepaint();
        } else {
            this.logger.fine("Preview images does not exist '" + f.getAbsolutePath() + "'.");
        }
    }

    private void myRepaint() {
        // TODO: Change the method to force the window to show the image
        Dimension dim = this.getSize();
        dim.setSize(dim.width + 1, dim.height + 1);
        this.setSize(dim);
        dim.setSize(dim.width, dim.height);
        this.setSize(dim);
    }

    /**
     * Insert (into parameters) the preview image as output.
     * @return the modified parameters
     */
    private String insertPreviewImage(String parameters) {
        // "-output", "(?i)(-output\\b)(\\s*)([^-]*)"
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        String previewImage = rf.getPreviewImage();
        // Check if exists
        // Make directory if not exist.
        String output = "-output" + " " + previewImage;
        parameters = replaceParameter(parameters, output, "(?i)(-output\\b)(\\s*)([^-]*)");
        return parameters;
    }

    private String insertDimensionOfPreviewImage(String parameters) {
        Dimension d = this.getDimensionPreviewImage();
        int previewWidth = d.width;
        int previewHeight = d.height;
        // Parameter ... -geometry 150x150 -output C:/Users/tom/data/dev/xplanet/xplanet-1.2.0/xplanet/preview/preview.jpg
        String geometry = "-geometry" + " " + Integer.toString(previewWidth) + "x" + Integer.toString(previewHeight);
        parameters = replaceParameter(parameters, geometry, "(?i)(-geometry\\b)(\\s*)([^-]*)");
        return parameters;
    }

    private Dimension getDimensionPreviewImage() {
        Dimension d = this.jPanelMainControlsCommand.getSize();
        MonitorUtil mu = new MonitorUtil();
        d = mu.getDimensionProportional(d);
        return d;
    }

    /**
     * replace a parameter of a control in the long parameter string and send it back.
     */
    private String replaceParameter(String parameters, String ownParam, String regExpr) {
        this.logger.finer("Befor replacement by " + regExpr + ": Parameters: " + parameters);
        Pattern p = Pattern.compile(regExpr);
        Matcher matcher = p.matcher(parameters);
        ownParam = ownParam + " ";
        if (matcher.find()) {
            String found = matcher.group();
            this.logger.finer("Found: " + found + ". Replacing parameters: ownParam: " + ownParam + "...");
            parameters = parameters.replaceAll(regExpr, ownParam);
        } else {
            this.logger.finer("Appending parameters: ownParam: " + ownParam + "...");
            parameters = parameters.trim() + " " + ownParam;
        }
        this.logger.finer("After replacement by " + regExpr + ": Parameters: " + parameters);
        return parameters;
    }

    private void createSimpleControlPanel() {
        if (this.jPanelSimpleMode == null) {
            this.jPanelSimpleMode = new JPanelControlParametersSimpleConfiguration(this);
            this.jPanelSimpleMode.setSection("default");
        }
    }

    /**
     * Reads the proxy configuration from file and inserts it into the
     * downloader config. Why? The proxy configuration is an exeption to other
     * configurations. The user does not want to type in the proxy all the time
     * he chooses an example from the list.
     */
    public void insertProxyConfigurationFromFile() {
        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        String configDir = rf.getRessourceDirectory("proxy");
        String file = configDir + File.separator + MainFrame.FILE_NAME_PROXY_CONFIG;
        File f = new File(file);
        if (f.exists()) {
            String proxyConfig = null;
            FileUtil util = new FileUtil();
            try {
                proxyConfig = util.getFileAsString(f);
            } catch (Exception ex) {
                this.logger.log(Level.SEVERE, null, ex);
                return;
            }
            String existingDownloaderConfig = this.getDownloaderConfig();
            // Remove existing entries to avoid double entries
            existingDownloaderConfig = existingDownloaderConfig.replaceAll("(?i)http.proxy\\w+=.*", "");
            existingDownloaderConfig = existingDownloaderConfig.replaceAll("(?i)proxy.set=.*", "");
            existingDownloaderConfig = existingDownloaderConfig + "\n" + proxyConfig;
            // Remove all empty lines
            existingDownloaderConfig = existingDownloaderConfig.replaceAll("(?m)^\\s*$^\\s*", "");
            this.setDownloaderConfiguration(existingDownloaderConfig);
        }
    }

    /**
     * Stores the proxy configuration to file. The user does not want to
     * get overwritten the proxy configuration by choosing another example
     * from the list.
     */
    public void writeProxyConfigToFile() {
        StringBuffer buf = new StringBuffer();
        // host
        String regExpr = "(?i)(http\\.proxyHost=)(.*)";
        String found = this.getElementFromDownloaderConfig(regExpr);
        buf.append(found);
        // port
        regExpr = "(?i)(http\\.proxyPort=)(.*)";
        found = this.getElementFromDownloaderConfig(regExpr);
        if (!"".equals(found) && buf.length() > 0) {
            buf.append("\n");
        }
        buf.append(found);
        // user
        regExpr = "(?i)(http\\.proxyUser=)(.*)";
        found = this.getElementFromDownloaderConfig(regExpr);
        if (!"".equals(found) && buf.length() > 0) {
            buf.append("\n");
        }
        buf.append(found);
        // pass
        regExpr = "(?i)(http\\.proxyPass=)(.*)";
        found = this.getElementFromDownloaderConfig(regExpr);
        if (!"".equals(found) && buf.length() > 0) {
            buf.append("\n");
        }
        buf.append(found);
        // set proxy
        regExpr = "(?i)(proxy\\.set\\b=)(.*)";
        found = this.getElementFromDownloaderConfig(regExpr);
        if (!"".equals(found) && buf.length() > 0) {
            buf.append("\n");
        }
        buf.append(found);

        XPlanetRessourceFinder rf = new XPlanetRessourceFinder();
        String configDir = rf.getRessourceDirectory("proxy");
        String file = configDir + File.separator + MainFrame.FILE_NAME_PROXY_CONFIG;
        FileUtil util = new FileUtil();
        try {
            util.printFile(file, buf.toString());
        } catch (Exception ex) {
            this.logger.log(Level.SEVERE, null, ex);
        }
    }

    private String getElementFromDownloaderConfig(String regExpr) {
        String parameters = this.getDownloaderConfig();
        String found = "";
        Pattern p = Pattern.compile(regExpr);
        Matcher matcher = p.matcher(parameters);
        if (matcher.find()) {
            found = matcher.group();
            this.logger.finer("Found own parameters: " + found);
        }
        return found;
    }

    private void checkXPlanetRessources() {
        CheckXPlanetFiles check = new CheckXPlanetFiles();
        check.copyRessourcesFromJarToFilesystem();
    }

    /**
     * @return the isPreview
     */
    private boolean isIsPreview() {
        return isPreview;
    }

    /**
     * @param isPreview the isPreview to set
     */
    private void setIsPreview(boolean isPreview) {
        this.isPreview = isPreview;
    }

    /*
     * The sole purpose of this class is to highlight the leaf in the jTree
     * that was selected by programm code instead of selecting it by mouse or
     * keyboard.
     */
    private class MyRenderer extends DefaultTreeCellRenderer {

        public MyRenderer() {
        }

        @Override
        public Component getTreeCellRendererComponent(
                JTree tree,
                Object value,
                boolean sel,
                boolean expanded,
                boolean leaf,
                int row,
                boolean hasFocus) {
            if (currentNode != null) {
                if (value.hashCode() == currentNode.hashCode()) {
                    sel = true;
                    logger.finer("Rendering node " + currentNode + " as selected...");
                }
            }
            super.getTreeCellRendererComponent(
                    tree, value, sel,
                    expanded, leaf, row,
                    hasFocus);
            return this;
        }
    }
}
TOP

Related Classes of xplanetconfigurator.gui.MainFrame

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.