/*
* RapidMiner
*
* Copyright (C) 2001-2008 by Rapid-I and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapid-i.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.gui.dialog;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import com.rapidminer.Process;
import com.rapidminer.gui.MainFrame;
import com.rapidminer.gui.dialog.boxviewer.ProcessRenderer;
import com.rapidminer.gui.properties.WizardPropertyTable;
import com.rapidminer.gui.templates.Template;
import com.rapidminer.gui.tools.ExtendedJScrollPane;
import com.rapidminer.gui.tools.SwingTools;
import com.rapidminer.tools.ParameterService;
import com.rapidminer.tools.XMLException;
/**
* The wizard dialog assists the user in creating a new process setup. Template
* processes are loaded from the etc/templates directory or from the user
* directory ".rapidminer". Instances of all processes are created and the
* parameters can be set.
*
* @author Ingo Mierswa, Simon Fischer
* @version $Id: WizardDialog.java,v 1.8 2008/05/09 19:23:21 ingomierswa Exp $
*/
public class WizardDialog extends JDialog {
private static final long serialVersionUID = 1L;
private static final String WIZARD_ICON_NAME = "wizard.jpg";
private static Icon wizardIcon;
static {
// init icon
wizardIcon = SwingTools.createImage(WIZARD_ICON_NAME);
}
private MainFrame mainFrame;
private JButton delete = new JButton("Delete");
private JButton next = new JButton("Next >");
private JButton previous = new JButton("< Previous");
private CardLayout cardLayout = new CardLayout();
private JPanel mainPanel = new JPanel(cardLayout);
private ProcessRenderer processRenderer = new ProcessRenderer();
private WizardPropertyTable propertyTable = new WizardPropertyTable();
private int currentStep = 0;
private int numberOfSteps = 0;
private transient Process[] processes;
private transient Template[] templates;
private int selectedTemplateIndex;
public WizardDialog(MainFrame mainFrame) {
super(mainFrame, "Wizard", true);
this.mainFrame = mainFrame;
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.add(next);
buttonPanel.add(previous);
previous.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
step(-1);
}
});
buttonPanel.add(next);
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
step(1);
}
});
buttonPanel.add(Box.createHorizontalStrut(11));
JButton cancel = new JButton("Cancel");
buttonPanel.add(cancel);
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cancel();
}
});
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
getContentPane().add(mainPanel, BorderLayout.CENTER);
mainPanel.setBorder(BorderFactory.createEmptyBorder(11, 11, 11, 11));
addTitle();
JPanel panel = createChooseTemplate();
addStep(panel);
addParameters();
step(0);
pack();
setSize(800, 600);
setLocationRelativeTo(mainFrame);
}
private void addTitle() {
JPanel panel = SwingTools.createTextPanel("Welcome to the RapidMiner Process Wizard", "This wizard will guide you setting up a new process definition.</p>");
JPanel content = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel image = new JLabel(wizardIcon);
image.setBorder(BorderFactory.createLoweredBevelBorder());
content.add(image);
JLabel label = new JLabel("<html>Using the wizard will involve the following steps:" + "<ul>" + "<li>Choose a template process setup</li>" + "<li>Set some of the important parameters</li>" + "<li>Create an attribute description file if necessary</li>" + "</ul>"
+ "<p>Completing these steps you can immediately start the process or " + "go on editing and make advanced settings.</p><p>Please check also the sample directory of RapidMiner containing a huge number of additional processes.</p></html>");
label.setPreferredSize(new java.awt.Dimension(300, 200));
label.setFont(label.getFont().deriveFont(java.awt.Font.PLAIN));
content.add(label);
panel.add(content, BorderLayout.CENTER);
addStep(panel);
}
private JPanel createChooseTemplate() {
File[] preDefinedTemplateFiles = ParameterService.getConfigFile("templates").listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getName().endsWith(".template");
}
});
File[] userDefinedTemplateFiles = ParameterService.getUserRapidMinerDir().listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getName().endsWith(".template");
}
});
File[] templateFiles = new File[preDefinedTemplateFiles.length + userDefinedTemplateFiles.length];
System.arraycopy(preDefinedTemplateFiles, 0, templateFiles, 0, preDefinedTemplateFiles.length);
System.arraycopy(userDefinedTemplateFiles, 0, templateFiles, preDefinedTemplateFiles.length, userDefinedTemplateFiles.length);
JPanel panel = SwingTools.createTextPanel("Select a template", "Please select one of the following template processes listed below. " + "The image on the right is a schematic figure of the process setup showing " + "operators as blue boxes and chains "
+ "and wrappers as brownish boxes containing their inner operators.");
Box radioBox = new Box(BoxLayout.Y_AXIS);
ButtonGroup group = new ButtonGroup();
templates = new Template[templateFiles.length];
processes = new Process[templateFiles.length];
for (int i = 0; i < templates.length; i++) {
try {
templates[i] = new Template(templateFiles[i]);
processes[i] = new Process(new File(templateFiles[i].getParent(), templates[i].getFilename()));
processes[i].setProcessFile(null);
} catch (InstantiationException e) {
SwingTools.showSimpleErrorMessage("Cannot load template file '" + templateFiles[i] + "'", e);
processes[i] = new Process();
templates[i] = new Template();
} catch (IOException e) {
SwingTools.showSimpleErrorMessage("Cannot load template process file '" + templateFiles[i] + "'", e);
processes[i] = new Process();
templates[i] = new Template();
} catch (XMLException e) {
SwingTools.showSimpleErrorMessage("Cannot load template process file '" + templateFiles[i] + "'", e);
processes[i] = new Process();
templates[i] = new Template();
}
JRadioButton b = new JRadioButton("<html>" + templates[i].toHTML() + "</html>");
b.setFont(b.getFont().deriveFont(java.awt.Font.PLAIN));
if (i == 0)
b.setSelected(true);
final int j = i;
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
select(j);
}
});
radioBox.add(b);
group.add(b);
}
GridBagLayout layout = new GridBagLayout();
JPanel centerPanel = new JPanel(layout);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 0.0d;
c.weighty = 0.0d;
c.gridwidth = GridBagConstraints.RELATIVE;
layout.setConstraints(radioBox, c);
centerPanel.add(radioBox);
c.weightx = 1.0d;
c.weighty = 1.0d;
c.gridwidth = GridBagConstraints.REMAINDER;
layout.setConstraints(processRenderer, c);
centerPanel.add(processRenderer);
JScrollPane centerScrollPane = new ExtendedJScrollPane(centerPanel);
panel.add(centerScrollPane, BorderLayout.CENTER);
select(0);
return panel;
}
private void addParameters() {
JPanel panel = SwingTools.createTextPanel("Make Settings", "In the following, you find a list of the most important parameters of this process definition. " + "Some of the parameters may have default values. The parameters set in bold face are mandatory. "
+ "Pointing with the mouse on one of the parameters you will get some information about the meaning " + "of the parameter.");
panel.add(new ExtendedJScrollPane(propertyTable), BorderLayout.CENTER);
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER));
panel.add(buttons, BorderLayout.SOUTH);
addStep(panel);
}
private void addStep(Component c) {
mainPanel.add(c, numberOfSteps + "");
numberOfSteps++;
}
private void select(int index) {
selectedTemplateIndex = index;
Process process = processes[index];
Template template = templates[index];
if ((process != null) && (template != null)) {
processRenderer.setOperator(process.getRootOperator());
propertyTable.setProcess(process, template.getParameters());
} else {
processRenderer.setOperator(null);
propertyTable.setProcess(null, null);
}
}
private void step(int dir) {
currentStep += dir;
if (currentStep == 1)
delete.setEnabled(true);
else
delete.setEnabled(false);
if (currentStep < 0)
currentStep = 0;
if (currentStep == 0)
previous.setEnabled(false);
else
previous.setEnabled(true);
if (currentStep >= numberOfSteps)
finish();
if (currentStep == numberOfSteps - 1) {
next.setText("Finish");
} else {
next.setText("Next >");
}
cardLayout.show(mainPanel, currentStep + "");
}
private void finish() {
mainFrame.setProcess(processes[selectedTemplateIndex], true);
mainFrame.processChanged();
dispose();
}
private void cancel() {
dispose();
}
}