PageRenderTime 42ms CodeModel.GetById 9ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 0ms

/edu/uncc/parsets/gui/DataWizard.java

https://code.google.com/p/parsets/
Java | 397 lines | 301 code | 67 blank | 29 comment | 23 complexity | 379047bc9eab1e601290136485ea1b75 MD5 | raw file
  1package edu.uncc.parsets.gui;
  2
  3import java.awt.BorderLayout;
  4import java.awt.Dimension;
  5import java.awt.FileDialog;
  6import java.awt.event.ActionEvent;
  7import java.awt.event.ActionListener;
  8import java.awt.event.ItemEvent;
  9import java.awt.event.ItemListener;
 10
 11import javax.swing.BorderFactory;
 12import javax.swing.JButton;
 13import javax.swing.JComboBox;
 14import javax.swing.JComponent;
 15import javax.swing.JFrame;
 16import javax.swing.JLabel;
 17import javax.swing.JOptionPane;
 18import javax.swing.JPanel;
 19import javax.swing.JProgressBar;
 20import javax.swing.JScrollPane;
 21import javax.swing.JTable;
 22import javax.swing.JTextField;
 23import javax.swing.ListSelectionModel;
 24import javax.swing.SwingUtilities;
 25import javax.swing.event.DocumentEvent;
 26import javax.swing.event.DocumentListener;
 27import javax.swing.event.ListSelectionEvent;
 28import javax.swing.event.ListSelectionListener;
 29import javax.swing.table.AbstractTableModel;
 30
 31import net.miginfocom.swing.MigLayout;
 32import edu.uncc.parsets.data.DataType;
 33import edu.uncc.parsets.data.LocalDB;
 34import edu.uncc.parsets.data.old.CSVDataSet;
 35import edu.uncc.parsets.data.old.CSVParser;
 36import edu.uncc.parsets.data.old.CSVParserListener;
 37import edu.uncc.parsets.data.old.DataDimension;
 38import edu.uncc.parsets.gui.DBTab.CSVFileFilter;
 39import edu.uncc.parsets.util.osabstraction.AbstractOS;
 40
 41/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 42 * Copyright (c) 2009, Robert Kosara, Caroline Ziemkiewicz,
 43 *                     and others (see Authors.txt for full list)
 44 * All rights reserved.
 45 * 
 46 * Redistribution and use in source and binary forms, with or without
 47 * modification, are permitted provided that the following conditions are met:
 48 * 
 49 *    * Redistributions of source code must retain the above copyright
 50 *      notice, this list of conditions and the following disclaimer.
 51 *    * Redistributions in binary form must reproduce the above copyright
 52 *      notice, this list of conditions and the following disclaimer in the
 53 *      documentation and/or other materials provided with the distribution.
 54 *    * Neither the name of UNC Charlotte nor the names of its contributors
 55 *      may be used to endorse or promote products derived from this software
 56 *      without specific prior written permission.
 57 *      
 58 * THIS SOFTWARE IS PROVIDED BY ITS AUTHORS ''AS IS'' AND ANY
 59 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 60 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 61 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
 62 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 63 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 64 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 65 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 66 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 67 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 68\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 69
 70@SuppressWarnings("serial")
 71public class DataWizard implements CSVParserListener {
 72
 73	private JTable table;
 74
 75	CSVDataSet data;
 76
 77	DataDimension currentDimension;
 78
 79	private JTable categoriesTable;
 80
 81	private JComboBox typeCB;
 82
 83	private JLabel dimKeyLabel;
 84
 85	private JTextField dimNameTF;
 86
 87	private JButton closeBtn;
 88
 89	private JFrame wizardFrame;
 90
 91	private JTextField nameTF;
 92
 93	private JProgressBar progressBar;
 94
 95	private JLabel fileNameLabel;
 96
 97	private JTextField sourceTF;
 98
 99	private JTextField srcURLTF;
100
101	private String fileName;
102
103	private JTextField sectionTF;
104
105	private JLabel statusLabel;
106
107	private CSVParser csvParser;
108
109	class DataTableModel extends AbstractTableModel implements ListSelectionListener {
110
111		int numRows = 0;
112		
113		public int getColumnCount() {
114			if (data != null)
115				return data.getNumDimensions();
116			else
117				return 0;
118		}
119
120		public int getRowCount() {
121			if (data != null) {
122				numRows = Math.min(data.getNumRecords()-1, 100);
123				return numRows+1;
124			} else
125				return 0;
126		}
127
128		public Object getValueAt(int row, int col) {
129			if (row >= numRows)
130				return "...";
131			else {
132				DataDimension d = data.getDimension(col);
133				return d.getValues().get(row);
134			}
135		}
136
137		public String getColumnName(int i) {
138			return data.getDimension(i).getName();
139		}
140
141		public void valueChanged(ListSelectionEvent event) {
142			if (data != null)
143				if (!event.getValueIsAdjusting() && (table.getSelectedColumn() >= 0)) {
144					setActiveDimension(data.getDimension(table.getSelectedColumn()));
145				}
146		}
147	};
148
149	class CategoryTableModel extends AbstractTableModel {
150
151		public int getColumnCount() {
152			return 2;
153		}
154
155		public int getRowCount() {
156			if (currentDimension != null
157					&& currentDimension.getDataType() == DataType.categorical)
158				return currentDimension.getNumCategories();
159			else
160				return 0;
161		}
162
163		public Object getValueAt(int row, int col) {
164			if (col == 0)
165				return currentDimension.getCategoryKey(row);
166			else
167				return currentDimension.getCategoryName(row);
168		}
169
170		public String getColumnName(int i) {
171			if (i == 0)
172				return "Key";
173			else
174				return "Name";
175		}
176
177		public boolean isCellEditable(int rowIndex, int columnIndex) {
178			return columnIndex == 1;
179		}
180
181		public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
182			currentDimension.setCategoryName(rowIndex, (String) aValue);
183		}
184	};
185
186	public DataWizard() {
187		table = new JTable();
188		table.setRowSelectionAllowed(false);
189		table.setColumnSelectionAllowed(true);
190		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
191		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
192
193		JScrollPane scrollPane = new JScrollPane(table);
194		scrollPane.setOpaque(false);
195
196		wizardFrame = new JFrame("CSV Import");
197		wizardFrame.setSize(800, 800);
198		wizardFrame.add(createDataSetPanel(), BorderLayout.NORTH);
199		scrollPane.setBorder(BorderFactory.createTitledBorder("Data"));
200		wizardFrame.add(scrollPane, BorderLayout.CENTER);
201		wizardFrame.add(createDimensionPanel(), BorderLayout.EAST);
202		wizardFrame.add(createButtonPanel(), BorderLayout.SOUTH);
203
204		wizardFrame.setVisible(true);
205		
206		fileName = AbstractOS.getCurrentOS().showDialog(wizardFrame, new CSVFileFilter(), FileDialog.LOAD);
207	    if (fileName != null) {
208	    	progressBar.setIndeterminate(true);
209	    	statusLabel.setText("Analyzing CSV file ...");
210	    	csvParser = new CSVParser(fileName, this);
211	    	csvParser.analyzeCSVFile();
212	    } else {
213	    	wizardFrame.setVisible(false);
214	    	wizardFrame.dispose();
215	    }
216	}
217
218	private JComponent createButtonPanel() {
219		JPanel p = new JPanel(new MigLayout("fillx, insets 0"));
220
221		progressBar = new JProgressBar();
222		p.add(progressBar, "gapleft 5, width 250, split 2");
223
224		statusLabel = new JLabel();
225		p.add(statusLabel, "gapleft 7");
226		
227		closeBtn = new JButton("Cancel");
228		closeBtn.addActionListener(new ActionListener() {
229			public void actionPerformed(ActionEvent e) {
230				wizardFrame.setVisible(false);
231			}
232		});
233		p.add(closeBtn, "split 2, right, tag cancel");
234
235		JButton saveBtn = new JButton("Save to DB");
236		saveBtn.addActionListener(new ActionListener() {
237			public void actionPerformed(ActionEvent e) {
238				data.setName(nameTF.getText());
239				data.setSource(sourceTF.getText());
240				data.setSourceURL(srcURLTF.getText());
241				data.setSection(sectionTF.getText());
242				progressBar.setIndeterminate(true);
243				statusLabel.setText("Writing data to local database ...");
244				new Thread(new Runnable() {
245					@Override
246					public void run() {
247						csvParser.streamToDB(LocalDB.getDefaultDB());
248					}
249				}).start();
250			}
251		});
252		p.add(saveBtn, "tag ok");
253		
254		return p;
255	}
256
257	private JComponent createDataSetPanel() {
258		JPanel p = new JPanel(new MigLayout("fill, insets 0 5 0 5, wrap 6"));
259		p.setBorder(BorderFactory.createTitledBorder("Dataset"));
260		p.add(new JLabel("Name:"), "right");
261		p.add(nameTF = new JTextField(), "gap related, width 25sp, growx");
262		p.add(new JLabel("Section:"), "right, gap unrelated");
263		p.add(sectionTF = new JTextField(), "gap related, width 25sp, growx");
264		p.add(new JLabel("File:"), "right, gap unrelated");
265		p.add(fileNameLabel = new JLabel(), "gap related, width 25sp");
266		p.add(new JLabel("Source:"), "right");
267		p.add(sourceTF = new JTextField(), "gap related, width 25sp, growx");
268		p.add(new JLabel("URL:"), "right, gap unrelated");
269		p.add(srcURLTF = new JTextField(), "gap related, span 3, growx");
270		return p;
271	}
272
273	private JPanel createDimensionPanel() {
274		JPanel p = new JPanel();
275		p.setBorder(BorderFactory.createTitledBorder("Dimension"));
276		p.setLayout(new MigLayout("wrap 2, insets 0 10 0 10, fill", "[right]r[left]", "[]r[]r[]r[]r[grow,fill]r"));
277
278//		p.add(new JCheckBox("Include"), "span 2, left");
279
280		p.add(new JLabel("Key:"));
281		dimKeyLabel = new JLabel("");
282		p.add(dimKeyLabel, "gap related");
283		
284		p.add(new JLabel("Name:"));
285		dimNameTF = new JTextField(25);
286		dimNameTF.getDocument().addDocumentListener(new DocumentListener() {
287			@Override
288			public void changedUpdate(DocumentEvent e) {
289				currentDimension.setName(dimNameTF.getText());
290			}
291
292			@Override
293			public void insertUpdate(DocumentEvent e) {
294				currentDimension.setName(dimNameTF.getText());
295			}
296
297			@Override
298			public void removeUpdate(DocumentEvent e) {
299				currentDimension.setName(dimNameTF.getText());
300			}
301		});
302		p.add(dimNameTF, "gap related");
303		
304		p.add(new JLabel("Type:"));
305		DataType activeTypes[] = {DataType.categorical, DataType.numerical};
306		typeCB = new JComboBox(activeTypes);
307		typeCB.addItemListener(new ItemListener() {
308			public void itemStateChanged(ItemEvent e) {
309				currentDimension.setDataType(DataType.values()[typeCB
310						.getSelectedIndex()]);
311				categoriesTable.revalidate();
312			}
313		});
314		p.add(typeCB, "gap related");
315
316		categoriesTable = new JTable();
317		JScrollPane scrollPane = new JScrollPane(categoriesTable);
318		scrollPane.setOpaque(false);
319		scrollPane.setBorder(BorderFactory.createTitledBorder("Categories"));
320		p.add(scrollPane, "span 2");
321
322		p.setPreferredSize(new Dimension(250, 1000));
323
324		return p;
325	}
326
327	private void setActiveDimension(DataDimension d) {
328		currentDimension = d;
329		categoriesTable.setModel(new CategoryTableModel());
330		dimKeyLabel.setText(d.getKey());
331		dimNameTF.setText(d.getName());
332		typeCB.setSelectedIndex(d.getDataType().ordinal());
333	}
334
335	public void setDataSet(final CSVDataSet data) {
336		this.data = data;
337		SwingUtilities.invokeLater(new Runnable() {
338			@Override
339			public void run() {
340				statusLabel.setText("");
341				progressBar.setIndeterminate(false);
342				nameTF.setText(data.getName());
343				sectionTF.setText(data.getSection());
344				fileNameLabel.setText(data.getFileBaseName());
345				sourceTF.setText(data.getSource());
346				srcURLTF.setText(data.getSourceURL());
347				DataTableModel m = new DataTableModel();
348				table.setModel(m);
349				table.getColumnModel().getSelectionModel().addListSelectionListener(m);
350
351				progressBar.setValue(0);
352			}
353		});
354	}
355
356	@Override
357	public void setProgress(final int progress) {
358		SwingUtilities.invokeLater(new Runnable() {
359			@Override
360			public void run() {
361				if (progress >= 0) {
362					progressBar.setIndeterminate(false);
363					progressBar.setValue(progress);
364				} else
365					progressBar.setIndeterminate(true);
366			}
367		});
368	}
369
370	@Override
371	public void importDone() {
372		SwingUtilities.invokeLater(new Runnable() {
373			@Override
374			public void run() {
375				wizardFrame.setVisible(false);
376			}
377		});
378	}
379
380	@Override
381	public void errorFileNotFound(String filename) {
382		JOptionPane.showConfirmDialog(wizardFrame, "The program could not locate the file '"+filename+"'.", "File Not Found!", JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE);
383		wizardFrame.setVisible(false);
384	}
385
386	@Override
387	public void errorReadingFile(String filename) {
388		JOptionPane.showConfirmDialog(wizardFrame, "An error occured while reading the file '"+filename+"'.", "Error Reading File!", JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE);
389		wizardFrame.setVisible(false);
390	}
391
392	@Override
393	public void errorWrongNumberOfColumns(int expected, int found, int line) {
394		JOptionPane.showConfirmDialog(wizardFrame, "The parser encountered a line with the wrong number of columns ("+found+" instead of "+expected+").", "Wrong Number of Columns!", JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE);
395		wizardFrame.setVisible(false);
396	}
397}