org.n52.ifgicopter.spf.gui.PluginRegistrationDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.n52.ifgicopter.spf.gui.PluginRegistrationDialog.java

Source

/**
 * Copyright (C) 2009
 * by 52 North Initiative for Geospatial Open Source Software GmbH
 *
 * Contact: Andreas Wytzisk
 * 52 North Initiative for Geospatial Open Source Software GmbH
 * Martin-Luther-King-Weg 24
 * 48155 Muenster, Germany
 * info@52north.org
 *
 * This program is free software; you can redistribute and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 *
 * This program is distributed WITHOUT ANY WARRANTY; even without the implied
 * WARRANTY OF MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program (see gnu-gpl v2.txt). If not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA or
 * visit the Free Software Foundation web page, http://www.fsf.org.
 */

package org.n52.ifgicopter.spf.gui;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.n52.ifgicopter.spf.SPFRegistry;
import org.n52.ifgicopter.spf.common.IModule;
import org.n52.ifgicopter.spf.common.PluginRegistry;
import org.n52.ifgicopter.spf.common.IModule.ConstructorParameters;
import org.n52.ifgicopter.spf.input.IInputPlugin;

import com.nexes.wizard.Wizard;
import com.nexes.wizard.WizardPanelDescriptor;

/**
 * A Wizard style dialog for searching and configuring plugins.
 * 
 * @author matthes rieke
 * 
 */
public class PluginRegistrationDialog {

    protected static final Log log = LogFactory.getLog(PluginRegistrationDialog.class);

    protected PluginRegistry pr = new PluginRegistry();

    private static final String FIRST_DESCRIPTOR = "INTRO";
    private static final String SECOND_DESCRIPTOR = "RESULT";
    private static final String THIRD_DESCRIPTOR = "CHOICE";
    private static final String FOURTH_DESCRIPTOR = "SETUP";
    private int ret;
    private boolean canceled;
    protected ResultPanel result;
    protected PluginChoicePanel choice;
    protected ConstructorSetupPanel setup;
    protected Object searchingMutex = new Object();
    protected boolean searching;
    protected boolean searchAlreadyFinished = false;

    /**
     * @param frame
     *        the parent frame
     */
    public PluginRegistrationDialog(JFrame parent) {
        Wizard wizard = new Wizard(parent);

        WizardPanelDescriptor intro = new IntroPanel();
        wizard.registerWizardPanel(FIRST_DESCRIPTOR, intro);

        wizard.setCurrentPanel(FIRST_DESCRIPTOR);
        wizard.setTitle("Configure Plugins");

        this.result = new ResultPanel();
        wizard.registerWizardPanel(SECOND_DESCRIPTOR, this.result);

        this.choice = new PluginChoicePanel();
        wizard.registerWizardPanel(THIRD_DESCRIPTOR, this.choice);

        this.setup = new ConstructorSetupPanel();
        wizard.registerWizardPanel(FOURTH_DESCRIPTOR, this.setup);

        wizard.getDialog().setIconImage(parent.getIconImage());

        this.ret = wizard.showModalDialog();

        /*
         * this is a cancel
         */
        if (this.ret == Wizard.CANCEL_RETURN_CODE) {
            this.canceled = true;
        }

    }

    /**
     * @return all selected new plugins
     */
    public Map<String, TablePanel> getSelectedNewPlugins() {
        HashMap<String, TablePanel> map = new HashMap<String, TablePanel>();

        for (Object o : this.choice.newInputList.getSelectedValues()) {
            String s = o.toString();
            if (this.choice.tables.containsKey(s)) {
                map.put(s, this.choice.tables.get(s));
            }
        }

        for (Object o : this.choice.newOutputList.getSelectedValues()) {
            String s = o.toString();
            if (this.choice.tables.containsKey(s)) {
                map.put(s, this.choice.tables.get(s));
            }
        }

        return map;
    }

    /**
     * @return all selected old plugins
     */
    public List<String> getSelectedOldPlugins() {
        List<String> list = new ArrayList<String>();

        for (Object o : this.choice.outputList.getSelectedValues()) {
            list.add(o.toString());
        }

        for (Object o : this.choice.inputList.getSelectedValues()) {
            list.add(o.toString());
        }

        return list;
    }

    /**
     * @return the canceled
     */
    public boolean isCanceled() {
        return this.canceled;
    }

    /**
     * the first panel showing the introduction text.
     */
    private class IntroPanel extends WizardPanelDescriptor {

        private JPanel introPanel;

        public IntroPanel() {
            this.introPanel = new JPanel(new CardLayout());

            String text = "<html><body><div>This tool searches the \"plugins\" folder"
                    + " for available Input- and OutputPlugins.</div><div>A restart of the application"
                    + " is required afterwards.<br/></div><div>"
                    + "Put plugin implementations as Java jar files into the \"plugins\" folder "
                    + "in<br/>order to enable their usage.</div></body></html>";

            JLabel description = new JLabel(text);
            this.introPanel.add(description, "1");

            this.introPanel.setBorder(new EmptyBorder(2, 2, 2, 2));
            this.introPanel.setPreferredSize(new Dimension(this.introPanel.getPreferredSize().width + 100, 350));

            this.setPanelComponent(this.introPanel);
            this.setPanelDescriptorIdentifier(FIRST_DESCRIPTOR);
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#getNextPanelDescriptor()
         */
        @Override
        public Object getNextPanelDescriptor() {
            return SECOND_DESCRIPTOR;
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#aboutToHidePanel()
         */
        @Override
        public void aboutToHidePanel() {
            if (PluginRegistrationDialog.this.searchAlreadyFinished)
                return;

            synchronized (PluginRegistrationDialog.this.searchingMutex) {
                PluginRegistrationDialog.this.searching = true;
            }

            String text = "<html><body><div>Searching...</div></body></html>";

            final JLabel description = new JLabel(text);
            this.introPanel.add(description, "2");
            ((CardLayout) this.introPanel.getLayout()).show(this.introPanel, "2");

            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        /*
                         * call the actual plugin search algorithm
                         */
                        PluginRegistrationDialog.this.pr.lookupPlugins();

                        synchronized (PluginRegistrationDialog.this.searchingMutex) {
                            PluginRegistrationDialog.this.searching = false;

                            // this prevents the app to repeatingly search
                            PluginRegistrationDialog.this.searchAlreadyFinished = true;

                            description.setText("<html><body><div>Finished searching.</div></body></html>");

                            // call waiters!
                            PluginRegistrationDialog.this.searchingMutex.notifyAll();
                        }
                    } catch (IOException e) {
                        log.warn(e.getMessage(), e);
                    }
                }
            });
        }

    }

    /**
     * 
     * Panel for displaying the search results.
     * 
     * 
     */
    private class ResultPanel extends WizardPanelDescriptor {

        protected JPanel panel;
        protected JLabel info;
        protected JList inputList;
        protected JList outputList;

        public ResultPanel() {
            this.panel = new JPanel();
            this.panel.setLayout(new CardLayout());

            this.info = new JLabel("<html><body><div>Searching...</div></body></html>");
            this.panel.add(this.info, "1");

            this.setPanelComponent(this.panel);
            this.setPanelDescriptorIdentifier(SECOND_DESCRIPTOR);
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#aboutToDisplayPanel()
         */
        @Override
        public void aboutToDisplayPanel() {
            if (PluginRegistrationDialog.this.searchAlreadyFinished)
                return;

            // disable buttons as long as searching
            getWizard().setBackButtonEnabled(false);
            getWizard().setNextFinishButtonEnabled(false);

            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    synchronized (PluginRegistrationDialog.this.searchingMutex) {
                        ResultPanel.this.info.setText("Searching... ");
                        while (PluginRegistrationDialog.this.searching) {
                            try {
                                // wait.. hopefully gets notified, heh!
                                PluginRegistrationDialog.this.searchingMutex.wait();
                            } catch (InterruptedException e) {
                                log.warn(e.getMessage(), e);
                            }
                        }
                    }

                    displayResults();
                }
            });
        }

        protected void displayResults() {
            // search finished -> reactivate buttons
            getWizard().setBackButtonEnabled(true);
            getWizard().setNextFinishButtonEnabled(true);

            this.inputList = new JList(PluginRegistrationDialog.this.pr.getInputPlugins().toArray());
            this.inputList.addListSelectionListener(PluginRegistrationDialog.this.choice);
            this.outputList = new JList(PluginRegistrationDialog.this.pr.getOutputPlugins().toArray());

            JPanel listPanel = new JPanel();
            listPanel.setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.BOTH;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            gbc.weightx = 1.0;
            gbc.weighty = 0.0;
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(1, 1, 1, 1);

            // first row
            gbc.gridwidth = 2;
            JLabel fin = new JLabel(
                    "<html><body><strong>Finished! " + PluginRegistrationDialog.this.pr.getInputPlugins().size()
                            + " InputPlugins, " + PluginRegistrationDialog.this.pr.getOutputPlugins().size()
                            + " OutputPlugins found.</strong></body></html>");
            listPanel.add(fin, gbc);
            gbc.gridwidth = 1;

            // second row
            gbc.gridy++;
            gbc.weightx = 1.0;
            listPanel.add(new JLabel("InputPlugins"), gbc);
            gbc.gridx++;
            listPanel.add(new JLabel("OutputPlugins"), gbc);

            // third row
            gbc.gridy++;
            gbc.gridx = 0;
            gbc.weighty = 1.0;
            listPanel.add(new JScrollPane(this.inputList), gbc);
            gbc.gridx++;
            listPanel.add(new JScrollPane(this.outputList), gbc);

            // fourth row
            gbc.weighty = 0.0;
            gbc.gridy++;
            gbc.gridx = 0;
            gbc.gridwidth = 2;
            listPanel.add(new JLabel(
                    "<html><body><strong>Please select the plugins you want to use.</strong></body></html>"), gbc);

            String s = "2";
            this.panel.add(listPanel, s);
            ((CardLayout) this.panel.getLayout()).show(this.panel, s);
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#getBackPanelDescriptor()
         */
        @Override
        public Object getBackPanelDescriptor() {
            return FIRST_DESCRIPTOR;
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#getNextPanelDescriptor()
         */
        @Override
        public Object getNextPanelDescriptor() {
            return THIRD_DESCRIPTOR;
        }

    }

    /**
     * 
     * Panel providing all available plugins for choosing by the user.
     * 
     * 
     */
    private class PluginChoicePanel extends WizardPanelDescriptor implements ListSelectionListener {

        private JPanel panel;
        private GridBagConstraints gbc;
        protected JList inputList;
        protected JList outputList;
        protected JList newInputList;
        protected JList newOutputList;
        private boolean alreadyDrawn;
        protected Map<String, TablePanel> tables = new HashMap<String, TablePanel>();
        private boolean modelUpdated = true;

        public PluginChoicePanel() {
            this.panel = new JPanel();
            this.panel.setLayout(new GridBagLayout());

            this.gbc = new GridBagConstraints();
            this.gbc.fill = GridBagConstraints.BOTH;
            this.gbc.anchor = GridBagConstraints.NORTHWEST;
            this.gbc.weightx = 1.0;
            this.gbc.weighty = 0.0;
            this.gbc.gridx = 0;
            this.gbc.gridy = 0;
            this.gbc.insets = new Insets(1, 1, 1, 1);

            // zero row
            this.gbc.gridwidth = 2;
            JLabel fin = new JLabel("<html><body>Currently enabled Plugins</body></html>");
            this.panel.add(fin, this.gbc);
            this.gbc.gridwidth = 1;

            this.setPanelComponent(this.panel);
            this.setPanelDescriptorIdentifier(THIRD_DESCRIPTOR);
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#aboutToDisplayPanel()
         */
        @Override
        public void aboutToDisplayPanel() {
            List<String> newInputs = new ArrayList<String>();
            List<String> newOutputs = new ArrayList<String>();

            if (this.modelUpdated) {
                if (this.alreadyDrawn) {
                    ((DefaultListModel) (this.newInputList.getModel())).removeAllElements();
                    ((DefaultListModel) (this.newOutputList.getModel())).removeAllElements();
                }

                /*
                 * check constructors do it with reflections
                 */
                searchForConstructor(newInputs, PluginRegistrationDialog.this.result.inputList);
                searchForConstructor(newOutputs, PluginRegistrationDialog.this.result.outputList);

                /*
                 * re-set the items
                 */
                if (this.alreadyDrawn) {
                    DefaultListModel model = ((DefaultListModel) this.newInputList.getModel());
                    for (String string : newInputs) {
                        model.add(model.getSize(), string);
                    }
                    DefaultListModel model2 = ((DefaultListModel) this.newOutputList.getModel());
                    for (String string : newOutputs) {
                        model2.add(model2.getSize(), string);
                    }
                }

                this.modelUpdated = false;
            }

            /*
             * do not redraw the UI
             */
            if (this.alreadyDrawn)
                return;

            /*
             * currently active plugins
             */
            // first
            this.gbc.gridy++;
            this.gbc.weightx = 1.0;
            JLabel inLabel = new JLabel("InputPlugins");
            JLabel outLabel = new JLabel("OutputPlugins");

            this.panel.add(inLabel, this.gbc);
            this.gbc.gridx++;
            this.panel.add(outLabel, this.gbc);

            // second
            List<String> inputs = new ArrayList<String>();
            List<String> outputs = new ArrayList<String>();

            /*
             * retrieve currentyl registered plugins
             */
            for (String s : SPFRegistry.getInstance().getConfigProperty(SPFRegistry.INPUT_PLUGINS_PROP)
                    .split(SPFRegistry.LIST_SEPARATOR)) {
                if (s.trim().length() > 0)
                    inputs.add(s.trim());
            }
            for (String s : SPFRegistry.getInstance().getConfigProperty(SPFRegistry.OUTPUT_PLUGINS_PROP)
                    .split(SPFRegistry.LIST_SEPARATOR)) {
                if (s.trim().length() > 0)
                    outputs.add(s.trim());
            }

            int[] indices = new int[Math.max(inputs.size(), outputs.size())];
            for (int i = 0; i < indices.length; i++) {
                indices[i] = i;
            }

            this.gbc.gridy++;
            this.gbc.gridx = 0;
            this.gbc.weighty = 1.0;
            DefaultListModel inputModel = new DefaultListModel();
            for (String string : inputs) {
                inputModel.add(inputModel.getSize(), string);
            }
            this.inputList = new JList(inputModel);

            if (inputModel.getSize() > 0) {
                this.inputList.setSelectedIndices(indices);
            }
            this.panel.add(new JScrollPane(this.inputList), this.gbc);

            this.gbc.gridx++;
            DefaultListModel outputModel = new DefaultListModel();
            for (String string : outputs) {
                outputModel.add(outputModel.getSize(), string);
            }
            this.outputList = new JList(outputModel);

            if (outputModel.size() > 0) {
                this.outputList.setSelectedIndices(indices);
            }
            this.panel.add(new JScrollPane(this.outputList), this.gbc);

            /*
             * new plugins
             */
            // first row
            this.gbc.gridy++;
            this.gbc.gridx = 0;
            this.gbc.gridwidth = 2;
            this.gbc.weighty = 0.0;
            JLabel fin = new JLabel("<html><body>Found constructors for plugins:</body></html>");
            this.panel.add(fin, this.gbc);
            this.gbc.gridwidth = 1;
            this.gbc.weighty = 1.0;

            // third row
            this.gbc.gridy++;
            this.gbc.gridx = 0;
            this.gbc.weighty = 1.0;
            DefaultListModel newInputModel = new DefaultListModel();
            for (String string : newInputs) {
                newInputModel.add(newInputModel.getSize(), string);
            }
            this.newInputList = new JList(newInputModel);
            this.newInputList.addListSelectionListener(PluginRegistrationDialog.this.setup);
            this.panel.add(new JScrollPane(this.newInputList), this.gbc);

            this.gbc.gridx++;
            DefaultListModel newOutputModel = new DefaultListModel();
            for (String string : newOutputs) {
                newOutputModel.add(newOutputModel.getSize(), string);
            }
            this.newOutputList = new JList(newOutputModel);
            this.newOutputList.addListSelectionListener(PluginRegistrationDialog.this.setup);
            this.panel.add(new JScrollPane(this.newOutputList), this.gbc);

            // fourth row
            this.gbc.weighty = 0.0;
            this.gbc.gridy++;
            this.gbc.gridx = 0;
            this.gbc.gridwidth = 2;
            this.panel.add(new JLabel("<html><body><strong>Selected plugins will be used at the next"
                    + " application start.</strong></body></html>"), this.gbc);

            this.alreadyDrawn = true;
        }

        private List<String> searchForConstructor(List<String> targetList, JList sourceList) {
            for (Object o : sourceList.getSelectedValues()) {
                try {
                    Class<?> clazz = Class.forName(o.toString(), false, getClass().getClassLoader());
                    Constructor<?>[] cons = clazz.getConstructors();

                    for (Constructor<?> con : cons) {
                        if (con.getParameterTypes().length > 0) {
                            /*
                             * lets try to receive parameter names. this is done using runtime-available
                             * annotations for the plugins constructor. if no annotation is present default
                             * labels are used.
                             */
                            ConstructorParameters params = con.getAnnotation(IModule.ConstructorParameters.class);
                            Object[][] paramNames = new String[con.getParameterTypes().length][2];
                            if (params == null) {
                                for (int i = 0; i < paramNames.length; i++) {
                                    paramNames[i][0] = "Parameter " + (i + 1);
                                    paramNames[i][1] = "";
                                }
                            } else {
                                for (int i = 0; i < paramNames.length; i++) {
                                    paramNames[i][0] = params.value()[i];
                                    paramNames[i][1] = "";
                                }
                            }

                            /*
                             * create a TablePanel using the names
                             */
                            TablePanel paramTable = new TablePanel(paramNames);
                            paramTable.setInputPlugin(sourceList == PluginRegistrationDialog.this.result.inputList);
                            String pseudoSyntax = con.getName() + "(";
                            if (paramNames.length == 1) {
                                pseudoSyntax += paramNames[0][0] + ")";
                            } else {
                                for (int i = 0; i < paramNames.length - 1; i++) {
                                    pseudoSyntax += paramNames[i][0] + ", ";
                                }
                                pseudoSyntax += paramNames[paramNames.length - 1][0] + ")";
                            }

                            this.tables.put(pseudoSyntax, paramTable);
                            targetList.add(pseudoSyntax);
                        } else {
                            // create a dummy table instead. needed for internal model
                            TablePanel paramTable = new TablePanel();
                            paramTable.setInputPlugin(sourceList == PluginRegistrationDialog.this.result.inputList);
                            this.tables.put(o.toString(), paramTable);
                            targetList.add(o.toString());
                        }
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                }
            }

            return targetList;
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#getBackPanelDescriptor()
         */
        @Override
        public Object getBackPanelDescriptor() {
            return SECOND_DESCRIPTOR;
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#getNextPanelDescriptor()
         */
        @Override
        public Object getNextPanelDescriptor() {
            return FOURTH_DESCRIPTOR;
        }

        /**
         * this is called whenever the selection of the results panel changed
         */
        @Override
        public void valueChanged(ListSelectionEvent e) {
            this.modelUpdated = true;
        }
    }

    /**
     * 
     * Last Panel for providing parameter fields for every selected constructor.
     * 
     * 
     */
    private class ConstructorSetupPanel extends WizardPanelDescriptor implements ListSelectionListener {

        private JPanel panel;
        private JLabel infoLabel;
        private GridBagConstraints globalGBC;
        private boolean modelUpdated = false;
        private JScrollPane pane;
        private JPanel wrapper;

        public ConstructorSetupPanel() {
            this.wrapper = new JPanel();
            this.wrapper.setLayout(new BorderLayout());

            this.panel = new JPanel();
            this.panel.setLayout(new GridBagLayout());
            this.globalGBC = new GridBagConstraints();
            this.globalGBC.gridx = 0;
            this.globalGBC.gridy = 0;
            this.globalGBC.anchor = GridBagConstraints.NORTHWEST;
            this.globalGBC.insets = new Insets(0, 0, 0, 0);
            this.globalGBC.weighty = 0.0;

            this.infoLabel = new JLabel("Plugins will be used at the next application startup.");
            this.wrapper.add(this.infoLabel, BorderLayout.NORTH);

            this.pane = new JScrollPane(this.panel);
            this.pane.setViewportBorder(null);
            this.pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
            this.pane.getVerticalScrollBar().setBorder(BorderFactory.createEmptyBorder());
            this.pane.getHorizontalScrollBar().setBorder(BorderFactory.createEmptyBorder());
            this.wrapper.add(this.pane, BorderLayout.CENTER);

            this.setPanelComponent(this.wrapper);
            this.setPanelDescriptorIdentifier(FOURTH_DESCRIPTOR);
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#aboutToDisplayPanel()
         */
        @Override
        public void aboutToDisplayPanel() {
            if (!this.modelUpdated)
                return;

            /*
             * make it left aligned
             */
            this.globalGBC.fill = GridBagConstraints.HORIZONTAL;
            this.globalGBC.gridx = 1;
            this.globalGBC.gridy = 0;
            this.globalGBC.weightx = 1.0;
            this.panel.add(Box.createHorizontalGlue(), this.globalGBC);
            this.globalGBC.fill = GridBagConstraints.BOTH;
            this.globalGBC.weightx = 0.0;

            /*
             * reset grids
             */
            this.globalGBC.gridx = 0;
            this.globalGBC.gridy = 0;

            this.infoLabel.setText("<html><body><div><strong>"
                    + "The following plugins need parameters for instantiating them.</strong></div><div>"
                    + "All values will be treated as Strings.</div></body></html>");

            this.globalGBC.gridy++;
            this.panel.add(new JSeparator(), this.globalGBC);
            this.globalGBC.gridy++;

            boolean setupNeeded = false;
            for (Object o : PluginRegistrationDialog.this.choice.newInputList.getSelectedValues()) {
                if (createAndAddParameterPanel(o.toString()))
                    setupNeeded = true;
            }

            for (Object o : PluginRegistrationDialog.this.choice.newOutputList.getSelectedValues()) {
                if (createAndAddParameterPanel(o.toString()))
                    setupNeeded = true;
            }

            this.globalGBC.weighty = 10.0;
            this.panel.add(Box.createVerticalGlue(), this.globalGBC);
            this.globalGBC.weighty = 0.0;

            if (!setupNeeded) {
                this.infoLabel.setText("Plugins will be used at the next application startup.");
            }

            this.modelUpdated = false;
        }

        private boolean createAndAddParameterPanel(String plugin) {
            if (PluginRegistrationDialog.this.choice.tables.containsKey(plugin)
                    && !PluginRegistrationDialog.this.choice.tables.get(plugin).isDummy()) {
                JPanel panel2 = new JPanel();
                panel2.setBorder(BorderFactory.createEmptyBorder());
                panel2.setLayout(new BorderLayout());
                panel2.add(new JLabel(plugin.substring(0, plugin.indexOf("("))), BorderLayout.NORTH);
                panel2.add(PluginRegistrationDialog.this.choice.tables.get(plugin), BorderLayout.CENTER);
                panel2.add(new JSeparator(), BorderLayout.SOUTH);

                this.panel.add(panel2, this.globalGBC);
                this.globalGBC.gridy++;
                return true;
            }
            return false;
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#getBackPanelDescriptor()
         */
        @Override
        public Object getBackPanelDescriptor() {
            return THIRD_DESCRIPTOR;
        }

        /*
         * (non-Javadoc)
         * 
         * @see com.nexes.wizard.WizardPanelDescriptor#getNextPanelDescriptor()
         */
        @Override
        public Object getNextPanelDescriptor() {
            return FINISH;
        }

        @Override
        public void valueChanged(ListSelectionEvent e) {
            this.modelUpdated = true;
            this.panel.removeAll();
        }

    }

    /**
     * Helper panel creating a simple input gui for one constructor.
     */
    public class TablePanel extends JPanel {
        private List<JTextField> values;
        private boolean inputPlugin;
        private boolean dummy;

        /**
         * @return true if representation of {@link IInputPlugin}
         */
        public boolean isInputPlugin() {
            return this.inputPlugin;
        }

        protected void setInputPlugin(boolean inputPlugin) {
            this.inputPlugin = inputPlugin;
        }

        /**
         * @param paramNames
         *        2d array of parameters
         */
        public TablePanel(Object[][] paramNames) {
            this.setLayout(new GridBagLayout());
            this.setBorder(BorderFactory.createEmptyBorder());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            gbc.insets = new Insets(1, 1, 1, 1);

            this.values = new ArrayList<JTextField>();

            for (int i = 0; i < paramNames.length; i++) {
                gbc.gridx = 0;
                this.add(new JLabel(paramNames[i][0].toString()), gbc);
                this.values.add(new JTextField(paramNames[i][1].toString()));
                this.values.get(i)
                        .setPreferredSize(new Dimension(150, this.values.get(i).getPreferredSize().height));

                gbc.gridx++;
                this.add(this.values.get(i), gbc);
                gbc.gridy++;
            }
        }

        /**
         * dummy panel constructor
         */
        public TablePanel() {
            this.dummy = true;
        }

        /**
         * @return true if this is a dummy panel (holding no actual data; used for zero-parameter
         *         constructors)
         */
        public boolean isDummy() {
            return this.dummy;
        }

        /**
         * @return the values as set by the user
         */
        public List<String> getValues() {
            ArrayList<String> resultList = new ArrayList<String>();

            for (JTextField string : this.values) {
                String val = string.getText();

                if (val == null || val.equals("")) {
                    resultList.add("null");
                } else {
                    resultList.add(val.trim());
                }
            }

            return resultList;
        }

        private static final long serialVersionUID = 1L;

    }

}