Index: org/encog/workbench/dialogs/validate/InputValidationChart.java
===================================================================
--- org/encog/workbench/dialogs/validate/InputValidationChart.java	(revision 0)
+++ org/encog/workbench/dialogs/validate/InputValidationChart.java	(revision 0)
@@ -0,0 +1,76 @@
+package org.encog.workbench.dialogs.validate;
+
+import java.awt.Frame;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.encog.neural.data.NeuralDataSet;
+import org.encog.neural.networks.BasicNetwork;
+import org.encog.persist.DirectoryEntry;
+import org.encog.persist.EncogPersistedCollection;
+import org.encog.workbench.EncogWorkBench;
+import org.encog.workbench.dialogs.common.ComboBoxField;
+import org.encog.workbench.dialogs.common.EncogPropertiesDialog;
+
+public class InputValidationChart extends EncogPropertiesDialog {
+	private static final long serialVersionUID = 3377283752032159041L;
+
+	private ComboBoxField comboNetwork;
+	private ComboBoxField comboValidation;
+	
+	/**
+	 * All available networks to display in the combo box.
+	 */
+	private final List<String> networks = new ArrayList<String>();
+
+	/**
+	 * All available training sets to display in the combo box.
+	 */
+	private final List<String> trainingSets = new ArrayList<String>();
+	
+	/**
+	 * Construct the dialog box.
+	 * @param owner
+	 */
+	public InputValidationChart(final Frame owner) {
+		super(owner);
+		findData();
+		setTitle("Validation Chart");
+		setSize(400,400);
+		setLocation(200,200);
+		addProperty(this.comboNetwork = new ComboBoxField("network","Neural Network",true,this.networks));
+		addProperty(this.comboValidation = new ComboBoxField("validation set","Validation Set",true,this.trainingSets));
+		render();
+	}
+	
+	/**
+	 * Obtain the data needed to fill in the network and training set
+	 * combo boxes.
+	 */
+	private void findData() {
+		for (final DirectoryEntry obj : EncogWorkBench.getInstance()
+				.getCurrentFile().getDirectory()) {
+			if (obj.getType().equals(EncogPersistedCollection.TYPE_BASIC_NET) ) {
+				this.networks.add(obj.getName());
+			} else if (obj.getType().equals(EncogPersistedCollection.TYPE_TRAINING) ) {
+				this.trainingSets.add(obj.getName());
+			}
+		}
+	}
+	
+	/**
+	 * @return The network that the user chose.
+	 */
+	public BasicNetwork getNetwork() {
+		String networkName = (String)this.comboNetwork.getSelectedValue();
+		return (BasicNetwork)EncogWorkBench.getInstance().getCurrentFile().find(networkName);
+	}
+
+	/**
+	 * @return The training set that the user chose.
+	 */
+	public NeuralDataSet getValidationSet() {
+		String trainingName = (String)this.comboValidation.getSelectedValue();
+		return (NeuralDataSet)EncogWorkBench.getInstance().getCurrentFile().find(trainingName);
+	}
+}
Index: org/encog/workbench/dialogs/validate/ResultValidationChart.java
===================================================================
--- org/encog/workbench/dialogs/validate/ResultValidationChart.java	(revision 0)
+++ org/encog/workbench/dialogs/validate/ResultValidationChart.java	(revision 0)
@@ -0,0 +1,164 @@
+package org.encog.workbench.dialogs.validate;
+
+import java.awt.Color;
+import java.awt.Frame;
+import java.util.ArrayList;
+import java.util.Vector;
+
+import javax.swing.JDialog;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+
+import org.encog.neural.data.NeuralData;
+import org.encog.neural.data.NeuralDataPair;
+import org.encog.neural.data.NeuralDataSet;
+import org.encog.neural.networks.BasicNetwork;
+import org.encog.neural.networks.NeuralOutputHolder;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.ChartUtilities;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
+import org.jfree.chart.renderer.xy.XYItemRenderer;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+
+public class ResultValidationChart extends JDialog {
+	private static final long serialVersionUID = -2859655432840760344L;
+	private JTabbedPane tabs = new JTabbedPane();
+	private ArrayList< JFreeChart > charts = new ArrayList< JFreeChart >();
+	private ArrayList< ChartPanel > chartPanels = new ArrayList< ChartPanel >();
+	
+	public ResultValidationChart( final Frame owner ){
+		super(owner);
+		setTitle("Validation Chart");
+		this.setSize(640, 400);
+		this.add( tabs );
+	}
+	
+	public void setData( NeuralDataSet validationData, BasicNetwork network ){
+		ArrayList< XYSeries > validation = new ArrayList< XYSeries >();
+		ArrayList< XYSeries > computation = new ArrayList< XYSeries >();
+		
+		Vector<Vector<String>> tableData = new Vector<Vector<String>>();
+		Vector<String> tableHeaders = null;
+		
+		int key = 0;
+		Vector<String> tableDataRow;
+		for( NeuralDataPair dataRow : validationData ){
+			NeuralData input = dataRow.getInput();
+			NeuralData validIdeal = dataRow.getIdeal();
+			NeuralData computatedIdeal =
+				getCalculatedResult( dataRow, network );
+			int inputCount = input.size();
+			int idealCount = validIdeal.size();
+			
+			tableDataRow = new Vector<String>();
+			if( tableHeaders == null ){
+				tableHeaders = new Vector<String>();
+				for( int i=0; i<inputCount; i++ ){
+					tableHeaders.add( "Input " + i );
+				}
+				for( int i=0; i<idealCount; i++ ){
+					tableHeaders.add( "Ideal " + i );
+					tableHeaders.add( "Result " + i );
+				}
+			}
+			
+			for( int i=0; i<inputCount; i++ ){
+				tableDataRow.add( new Double( input.getData( i ) ).toString() );
+			}
+			
+			for( int i = validation.size(); i < idealCount; i++ ){
+				validation.add( new XYSeries( "Validation" ) );
+				computation.add( new XYSeries( "Computation" ) );
+				createChart();
+			}
+			
+			for( int i=0; i<idealCount; i++ ){
+				double v = validIdeal.getData( i );
+				double c = computatedIdeal.getData( i );
+				
+				validation.get(i).add( key, v );
+				computation.get(i).add( key, c );
+				
+				tableDataRow.add( new Double( v ).toString() );
+				tableDataRow.add( new Double( c ).toString() );
+			}
+			
+			tableData.add( tableDataRow );
+
+			key++;
+		}
+		
+		drawGraphs( validation, computation );
+		drawTable( tableData, tableHeaders );
+	}
+	
+	private void drawGraphs( ArrayList< XYSeries > validation,
+			ArrayList< XYSeries > computation ){
+		// Add charts
+		int size = validation.size();
+		for( int i=0; i<size; i++ ){
+			XYSeries vSeries = validation.get( i );
+			XYSeries cSeries = computation.get( i );
+			JFreeChart chart = charts.get( i );
+			ChartPanel chartPanel = chartPanels.get( i );
+			
+			XYPlot plot = chart.getXYPlot();
+			plot.setDataset(0, new XYSeriesCollection( vSeries ) );
+			final XYItemRenderer renderer1 = new StandardXYItemRenderer();
+			renderer1.setSeriesPaint(0, Color.blue);
+			plot.setRenderer(0, renderer1);
+			
+			plot.setDataset(1, new XYSeriesCollection( cSeries ) );
+			final XYItemRenderer renderer2 = new StandardXYItemRenderer();
+			renderer2.setSeriesPaint(0, Color.red);
+			plot.setRenderer(1, renderer2);
+			
+			ChartUtilities.applyCurrentTheme( chart );
+			
+			tabs.addTab( "Ideal" + ( i + 1 ), chartPanel );
+		}
+	}
+	
+	private void drawTable( Vector<Vector<String>> tableData,
+			Vector<String> tableHeaders ){
+		JTable table = new JTable( tableData, tableHeaders ){
+			private static final long serialVersionUID = 8364655578079933961L;
+			public boolean isCellEditable(int rowIndex, int vColIndex) {
+				return false;
+			}
+		};
+		
+		tabs.addTab( "Data", new JScrollPane( table ) );
+	}
+	
+	private NeuralData getCalculatedResult( NeuralDataPair data,
+			BasicNetwork network ){
+		NeuralOutputHolder out = new NeuralOutputHolder();
+		network.compute( data.getInput(), out );
+		return out.getOutput();
+	}
+
+	/**
+	 * Create the initial chart.
+	 * @return The chart.
+	 */
+	private void createChart() {
+		JFreeChart chart = ChartFactory.createXYLineChart(null, "Result",
+				"Increment", null, PlotOrientation.VERTICAL, true,
+				true, false);
+	
+		ChartPanel chartPanel = new ChartPanel(chart);
+		chartPanel.setPreferredSize(new java.awt.Dimension(600, 360));
+		chartPanel.setDomainZoomable(true);
+		chartPanel.setRangeZoomable(true);
+		
+		charts.add( chart );
+		chartPanels.add( chartPanel );
+	}
+}
Index: org/encog/workbench/frames/document/EncogMenus.java
===================================================================
--- org/encog/workbench/frames/document/EncogMenus.java	(revision 900)
+++ org/encog/workbench/frames/document/EncogMenus.java	(working copy)
@@ -36,6 +36,7 @@
 import org.encog.workbench.EncogWorkBench;
 import org.encog.workbench.dialogs.EditEncogObjectProperties;
 import org.encog.workbench.process.training.Training;
+import org.encog.workbench.process.validate.ValidationChart;
 
 public class EncogMenus {
 	public static final String FILE_NEW = "New";
@@ -60,6 +61,7 @@
 	public static final String TOOLS_EVALUATE = "Evaluate Network...";
 	public static final String TOOLS_BENCHMARK = "Benchmark Encog...";
 	public static final String TOOLS_BROWSE = "Browse Web Data...";
+	public static final String TOOLS_VALIDATION_CHART = "Validation Chart...";
 	
 	public static final String HELP_ABOUT = "About Encog Workbench...";
 	
@@ -125,6 +127,7 @@
 		this.menuTools = new JMenu("Tools");
 		owner.addItem(this.menuTools, EncogMenus.TOOLS_CODE, 'g');
 		owner.addItem(this.menuTools, EncogMenus.TOOLS_TRAIN, 't');
+		owner.addItem(this.menuTools, EncogMenus.TOOLS_VALIDATION_CHART, 'v');
 		owner.addItem(this.menuTools, EncogMenus.TOOLS_BENCHMARK, 'k');
 		owner.addItem(this.menuTools, EncogMenus.TOOLS_EVALUATE, 'e');
 		owner.addItem(this.menuTools, EncogMenus.TOOLS_BROWSE, 'b');
@@ -195,10 +198,14 @@
 		}  else if (event.getActionCommand().equals(
 				EncogMenus.TOOLS_CODE)) {
 			owner.getOperations().performGenerateCode();
-		} else if( event.getActionCommand().equals(EncogMenus.TOOLS_TRAIN) )
-		{
+		} else if( event.getActionCommand().equals(
+				EncogMenus.TOOLS_TRAIN) ) {
 			Training training = new Training();
 			training.perform(EncogWorkBench.getInstance().getMainWindow(),null);
+		}else if( event.getActionCommand().equals(
+				EncogMenus.TOOLS_VALIDATION_CHART) ) {
+			ValidationChart check = new ValidationChart();
+			check.perform(EncogWorkBench.getInstance().getMainWindow());
 		}
 	}
 }
Index: org/encog/workbench/process/validate/ValidationChart.java
===================================================================
--- org/encog/workbench/process/validate/ValidationChart.java	(revision 0)
+++ org/encog/workbench/process/validate/ValidationChart.java	(revision 0)
@@ -0,0 +1,28 @@
+package org.encog.workbench.process.validate;
+
+import java.awt.Frame;
+
+import org.encog.neural.data.NeuralDataSet;
+import org.encog.neural.networks.BasicNetwork;
+import org.encog.workbench.EncogWorkBench;
+import org.encog.workbench.dialogs.validate.InputValidationChart;
+import org.encog.workbench.dialogs.validate.ResultValidationChart;
+
+public class ValidationChart {
+	private BasicNetwork network;
+	private NeuralDataSet training;
+	
+	public void perform(Frame owner) {
+		final InputValidationChart dialog = new InputValidationChart(
+				EncogWorkBench.getInstance().getMainWindow());
+		
+		if (dialog.process()) {
+			network = dialog.getNetwork();
+			training = dialog.getValidationSet();
+			
+			ResultValidationChart chart = new ResultValidationChart( owner );
+			chart.setData( training, network );
+			chart.setVisible( true );
+		}
+	}
+}

