package tim.prune.load;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellEditor;
import java.io.File;
import tim.prune.App;
import tim.prune.I18nManager;
import tim.prune.data.Field;
import tim.prune.data.PointCreateOptions;
import tim.prune.data.SourceInfo;
import tim.prune.data.Unit;
import tim.prune.data.UnitSetLibrary;
import tim.prune.gui.GuiGridLayout;
import tim.prune.gui.WizardLayout;
/**
* Class to handle loading of text files including GUI options,
* and passing loaded data back to App object
*/
public class TextFileLoader
{
private File _file = null;
private App _app = null;
private JFrame _parentFrame = null;
private JDialog _dialog = null;
private WizardLayout _wizard = null;
private JButton _backButton = null, _nextButton = null;
private JButton _finishButton = null;
private JButton _moveUpButton = null, _moveDownButton = null;
private JRadioButton[] _delimiterRadios = null;
private JTextField _otherDelimiterText = null;
private JLabel _statusLabel = null;
private DelimiterInfo[] _delimiterInfos = null;
private FileCacher _fileCacher = null;
private JList<String> _snippetBox = null;
private FileExtractTableModel _fileExtractTableModel = null;
private JTable _fieldTable;
private FieldSelectionTableModel _fieldTableModel = null;
private JComboBox<String> _altitudeUnitsDropdown = null;
private JComboBox<String> _hSpeedUnitsDropdown = null;
private JComboBox<String> _vSpeedUnitsDropdown = null;
private JRadioButton _vSpeedUpwardsRadio = null;
private ComponentHider _componentHider = null;
private int _selectedField = -1;
private char _currentDelimiter = ',';
// previously selected values
private char _lastUsedDelimiter = ',';
private Field[] _lastSelectedFields = null;
private Unit _lastAltitudeUnit = null;
// constants
private static final int SNIPPET_SIZE = 6;
private static final int MAX_SNIPPET_WIDTH = 80;
private static final char[] DELIMITERS = {',', '\t', ';', ' '};
/**
* Inner class to listen for delimiter change operations
*/
private class DelimListener implements ActionListener, DocumentListener
{
public void actionPerformed(ActionEvent e)
{
informDelimiterSelected();
}
public void changedUpdate(DocumentEvent e)
{
informDelimiterSelected();
}
public void insertUpdate(DocumentEvent e)
{
informDelimiterSelected();
}
public void removeUpdate(DocumentEvent e)
{
informDelimiterSelected();
}
}
/**
* Constructor
* @param inApp Application object to inform of track load
* @param inParentFrame parent frame to reference for dialogs
*/
public TextFileLoader(App inApp, JFrame inParentFrame)
{
_app = inApp;
_parentFrame = inParentFrame;
}
/**
* Open the selected file and show the GUI dialog to select load options
* @param inFile file to open
*/
public void openFile(File inFile)
{
_file = inFile;
if (preCheckFile(_file))
{
_dialog = new JDialog(_parentFrame, I18nManager.getText("dialog.openoptions.title"), true);
_dialog.setLocationRelativeTo(_parentFrame);
_dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
// add closing listener
_dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
_dialog.dispose();
_app.informNoDataLoaded();
}
});
_dialog.getContentPane().add(makeDialogComponents());
// select best separator according to row counts (more is better)
int bestDelim = getBestOption(_delimiterInfos[0].getNumWinningRecords(),
_delimiterInfos[1].getNumWinningRecords(), _delimiterInfos[2].getNumWinningRecords(),
_delimiterInfos[3].getNumWinningRecords());
if (bestDelim >= 0)
_delimiterRadios[bestDelim].setSelected(true);
else
_delimiterRadios[_delimiterRadios.length-1].setSelected(true);
informDelimiterSelected();
_dialog.pack();
_dialog.setVisible(true);
}
else
{
// Didn't pass pre-check
_app.showErrorMessageNoLookup("error.load.dialogtitle",
I18nManager.getText("error.load.noread") + ": " + inFile.getName());
_app.informNoDataLoaded();
}
}
/**
* Check the given file for readability and funny characters,
* and count the fields for the various separators
* @param inFile file to check
*/
private boolean preCheckFile(File inFile)
{
// Check file exists and is readable
if (inFile == null || !inFile.exists() || !inFile.canRead())
{
return false;
}
// Use a FileCacher to read the file into an array
_fileCacher = new FileCacher(inFile);
// Check each line of the file
String[] fileContents = _fileCacher.getContents();
if (fileContents == null) {
return false; // nothing cached, might be binary
}
boolean fileOK = true;
_delimiterInfos = new DelimiterInfo[5];
for (int i=0; i<4; i++) _delimiterInfos[i] = new DelimiterInfo(DELIMITERS[i]);
String currLine = null;
String[] splitFields = null;
int commaFields = 0, semicolonFields = 0, tabFields = 0, spaceFields = 0;
for (int lineNum=0; lineNum<fileContents.length && fileOK; lineNum++)
{
currLine = fileContents[lineNum];
// check for invalid characters
if (currLine.indexOf('\0') >= 0) {fileOK = false;}
// check for commas
splitFields = currLine.split(",");
commaFields = splitFields.length;
if (commaFields > 1) _delimiterInfos[0].incrementNumRecords();
_delimiterInfos[0].updateMaxFields(commaFields);
// check for tabs
splitFields = currLine.split("\t");
tabFields = splitFields.length;
if (tabFields > 1) _delimiterInfos[1].incrementNumRecords();
_delimiterInfos[1].updateMaxFields(tabFields);
// check for semicolons
splitFields = currLine.split(";");
semicolonFields = splitFields.length;
if (semicolonFields > 1) _delimiterInfos[2].incrementNumRecords();
_delimiterInfos[2].updateMaxFields(semicolonFields);
// check for spaces
splitFields = currLine.split(" ");
spaceFields = splitFields.length;
if (spaceFields > 1) _delimiterInfos[3].incrementNumRecords();
_delimiterInfos[3].updateMaxFields(spaceFields);
// increment counters
int bestScorer = getBestOption(commaFields, tabFields, semicolonFields, spaceFields);
if (bestScorer >= 0)
_delimiterInfos[bestScorer].incrementNumWinningRecords();
}
return fileOK;
}
/**
* Get the index of the best one in the list
* @return the index of the maximum of the four given values
*/
private static int getBestOption(int inOpt0, int inOpt1, int inOpt2, int inOpt3)
{
int bestIndex = -1;
int maxScore = 1;
if (inOpt0 > maxScore) {bestIndex = 0; maxScore = inOpt0;}
if (inOpt1 > maxScore) {bestIndex = 1; maxScore = inOpt1;}
if (inOpt2 > maxScore) {bestIndex = 2; maxScore = inOpt2;}
if (inOpt3 > maxScore) {bestIndex = 3; maxScore = inOpt3;}
return bestIndex;
}
/**
* Make the components for the open options dialog
* @return Component for all options
*/
private Component makeDialogComponents()
{
JPanel wholePanel = new JPanel();
wholePanel.setLayout(new BorderLayout());
// add buttons to south
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
_backButton = new JButton(I18nManager.getText("button.back"));
_backButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
_wizard.showPreviousCard();
_nextButton.setEnabled(!_wizard.isLastCard());
_backButton.setEnabled(!_wizard.isFirstCard());
_finishButton.setEnabled(false);
}
});
_backButton.setEnabled(false);
buttonPanel.add(_backButton);
_nextButton = new JButton(I18nManager.getText("button.next"));
_nextButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
prepareNextPanel(); // Maybe it needs to be initialized based on previous panels
_wizard.showNextCard();
_nextButton.setEnabled(!_wizard.isLastCard() && isCurrentCardValid());
_backButton.setEnabled(!_wizard.isFirstCard());
_finishButton.setEnabled(_wizard.isLastCard() && isCurrentCardValid());
}
});
buttonPanel.add(_nextButton);
_finishButton = new JButton(I18nManager.getText("button.finish"));
_finishButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
finished();
}
});
_finishButton.setEnabled(false);
buttonPanel.add(_finishButton);
JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
_dialog.dispose();
_app.informNoDataLoaded();
}
});
buttonPanel.add(cancelButton);
wholePanel.add(buttonPanel, BorderLayout.SOUTH);
// Make the card panel in the centre
JPanel cardPanel = new JPanel();
_wizard = new WizardLayout(cardPanel);
JPanel firstCard = new JPanel();
firstCard.setLayout(new BorderLayout());
firstCard.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
JPanel delimsPanel = new JPanel();
delimsPanel.setLayout(new GridLayout(0, 2));
delimsPanel.add(new JLabel(I18nManager.getText("dialog.delimiter.label")));
delimsPanel.add(new JLabel("")); // blank label to go to next grid row
// radio buttons
_delimiterRadios = new JRadioButton[5];
_delimiterRadios[0] = new JRadioButton(I18nManager.getText("dialog.delimiter.comma"));
delimsPanel.add(_delimiterRadios[0]);
_delimiterRadios[1] = new JRadioButton(I18nManager.getText("dialog.delimiter.tab"));
delimsPanel.add(_delimiterRadios[1]);
_delimiterRadios[2] = new JRadioButton(I18nManager.getText("dialog.delimiter.semicolon"));
delimsPanel.add(_delimiterRadios[2]);
_delimiterRadios[3] = new JRadioButton(I18nManager.getText("dialog.delimiter.space"));
delimsPanel.add(_delimiterRadios[3]);
JPanel otherPanel = new JPanel();
otherPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
_delimiterRadios[4] = new JRadioButton(I18nManager.getText("dialog.delimiter.other"));
otherPanel.add(_delimiterRadios[4]);
_otherDelimiterText = new JTextField(new OneCharDocument(), null, 2);
otherPanel.add(_otherDelimiterText);
// Group radio buttons
ButtonGroup delimGroup = new ButtonGroup();
DelimListener delimListener = new DelimListener();
for (int i=0; i<_delimiterRadios.length; i++)
{
delimGroup.add(_delimiterRadios[i]);
_delimiterRadios[i].addActionListener(delimListener);
}
_otherDelimiterText.getDocument().addDocumentListener(delimListener);
delimsPanel.add(new JLabel(""));
delimsPanel.add(otherPanel);
_statusLabel = new JLabel("");
delimsPanel.add(_statusLabel);
firstCard.add(delimsPanel, BorderLayout.SOUTH);
// load snippet to show first few lines
_snippetBox = new JList<String>(_fileCacher.getSnippet(SNIPPET_SIZE, MAX_SNIPPET_WIDTH));
_snippetBox.setEnabled(false);
firstCard.add(makeLabelledPanel("dialog.openoptions.filesnippet", _snippetBox), BorderLayout.CENTER);
// Second screen, for field order selection
JPanel secondCard = new JPanel();
secondCard.setLayout(new BorderLayout());
secondCard.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
// table for file contents
_fileExtractTableModel = new FileExtractTableModel();
JTable extractTable = new JTable(_fileExtractTableModel);
JScrollPane tableScrollPane = new JScrollPane(extractTable);
extractTable.setPreferredScrollableViewportSize(new Dimension(350, 80));
extractTable.getTableHeader().setReorderingAllowed(false);
secondCard.add(makeLabelledPanel("dialog.openoptions.filesnippet", tableScrollPane), BorderLayout.NORTH);
JPanel innerPanel2 = new JPanel();
innerPanel2.setLayout(new BorderLayout());
innerPanel2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
_fieldTable = new JTable(new FieldSelectionTableModel());
_fieldTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// add listener for selected table row
_fieldTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
if (lsm.isSelectionEmpty()) {
//no rows are selected
selectField(-1);
} else {
selectField(lsm.getMinSelectionIndex());
}
}
});
JScrollPane lowerTablePane = new JScrollPane(_fieldTable);
lowerTablePane.setPreferredSize(new Dimension(300, 100));
innerPanel2.add(lowerTablePane, BorderLayout.CENTER);
JPanel innerPanel3 = new JPanel();
innerPanel3.setLayout(new BoxLayout(innerPanel3, BoxLayout.Y_AXIS));
_moveUpButton = new JButton(I18nManager.getText("button.moveup"));
_moveUpButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
int currRow = _fieldTable.getSelectedRow();
closeTableComboBox(currRow);
_fieldTableModel.moveUp(currRow);
_fieldTable.setRowSelectionInterval(currRow-1, currRow-1);
}
});
innerPanel3.add(_moveUpButton);
_moveDownButton = new JButton(I18nManager.getText("button.movedown"));
_moveDownButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
int currRow = _fieldTable.getSelectedRow();
closeTableComboBox(currRow);
_fieldTableModel.moveDown(currRow);
_fieldTable.setRowSelectionInterval(currRow+1, currRow+1);
}
});
innerPanel3.add(_moveDownButton);
innerPanel3.add(Box.createVerticalStrut(60));
JButton guessButton = new JButton(I18nManager.getText("button.guessfields"));
guessButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
_lastSelectedFields = null;
prepareSecondPanel();
}
});
innerPanel3.add(guessButton);
innerPanel2.add(innerPanel3, BorderLayout.EAST);
secondCard.add(innerPanel2, BorderLayout.CENTER);
// Third card, for units selection of altitude and speeds
JPanel thirdCard = new JPanel();
thirdCard.setLayout(new BorderLayout(10, 10));
JPanel holderPanel = new JPanel();
holderPanel.setLayout(new BoxLayout(holderPanel, BoxLayout.Y_AXIS));
// Altitude
JPanel altUnitsPanel = new JPanel();
GuiGridLayout altGrid = new GuiGridLayout(altUnitsPanel);
altUnitsPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("fieldname.altitude")));
JLabel altLabel = new JLabel(I18nManager.getText("dialog.openoptions.altitudeunits") + ": ");
altGrid.add(altLabel);
String[] altUnits = {I18nManager.getText("units.metres"), I18nManager.getText("units.feet")};
_altitudeUnitsDropdown = new JComboBox<String>(altUnits);
altGrid.add(_altitudeUnitsDropdown);
holderPanel.add(altUnitsPanel);
// Horizontal speed
JPanel speedPanel = new JPanel();
GuiGridLayout speedGrid = new GuiGridLayout(speedPanel);
speedPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("fieldname.speed")));
JLabel speedLabel = new JLabel(I18nManager.getText("dialog.openoptions.speedunits") + ": ");
speedGrid.add(speedLabel);
_hSpeedUnitsDropdown = new JComboBox<String>();
for (Unit spUnit : UnitSetLibrary.ALL_SPEED_UNITS) {
_hSpeedUnitsDropdown.addItem(I18nManager.getText(spUnit.getNameKey()));
}
speedGrid.add(_hSpeedUnitsDropdown);
holderPanel.add(speedPanel);
// Vertical speed
JPanel vSpeedPanel = new JPanel();
GuiGridLayout vSpeedGrid = new GuiGridLayout(vSpeedPanel);
vSpeedPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("fieldname.verticalspeed")));
JLabel vSpeedLabel = new JLabel(I18nManager.getText("dialog.openoptions.vertspeedunits") + ": ");
vSpeedGrid.add(vSpeedLabel);
_vSpeedUnitsDropdown = new JComboBox<String>();
for (Unit spUnit : UnitSetLibrary.ALL_SPEED_UNITS) {
_vSpeedUnitsDropdown.addItem(I18nManager.getText(spUnit.getNameKey()));
}
vSpeedGrid.add(_vSpeedUnitsDropdown);
_vSpeedUpwardsRadio = new JRadioButton(I18nManager.getText("dialog.openoptions.vspeed.positiveup"));
JRadioButton vSpeedDownwardsRadio = new JRadioButton(I18nManager.getText("dialog.openoptions.vspeed.positivedown"));
ButtonGroup vSpeedDirGroup = new ButtonGroup();
vSpeedDirGroup.add(_vSpeedUpwardsRadio); vSpeedDirGroup.add(vSpeedDownwardsRadio);
vSpeedGrid.add(_vSpeedUpwardsRadio); vSpeedGrid.add(vSpeedDownwardsRadio);
_vSpeedUpwardsRadio.setSelected(true);
holderPanel.add(vSpeedPanel);
thirdCard.add(holderPanel, BorderLayout.NORTH);
// Make a hider to show and hide the components according to the selected fields
_componentHider = new ComponentHider();
_componentHider.addComponent(altLabel, Field.ALTITUDE);
_componentHider.addComponent(_altitudeUnitsDropdown, Field.ALTITUDE);
_componentHider.addComponent(speedLabel, Field.SPEED);
_componentHider.addComponent(_hSpeedUnitsDropdown, Field.SPEED);
_componentHider.addComponent(vSpeedLabel, Field.VERTICAL_SPEED);
_componentHider.addComponent(_vSpeedUnitsDropdown, Field.VERTICAL_SPEED);
_componentHider.addComponent(_vSpeedUpwardsRadio, Field.VERTICAL_SPEED);
_componentHider.addComponent(vSpeedDownwardsRadio, Field.VERTICAL_SPEED);
// Add cards to the wizard
_wizard.addCard(firstCard);
_wizard.addCard(secondCard);
_wizard.addCard(thirdCard);
wholePanel.add(cardPanel, BorderLayout.CENTER);
return wholePanel;
}
/**
* Close the combo box on the selected row of the field table
* @param inRow currently selected row number
*/
private void closeTableComboBox(int inRow)
{
TableCellEditor editor = _fieldTable.getCellEditor(inRow, 1);
if (editor != null)
{
editor.stopCellEditing();
}
}
/**
* change the status based on selection of a delimiter
*/
protected void informDelimiterSelected()
{
int fields = 0;
// Loop through radios to see which one is selected
for (int i=0; i<(_delimiterRadios.length-1); i++)
{
if (_delimiterRadios[i].isSelected())
{
// Set label text to describe records and fields
int numRecords = _delimiterInfos[i].getNumRecords();
if (numRecords == 0)
{
_statusLabel.setText(I18nManager.getText("dialog.openoptions.deliminfo.norecords"));
}
else
{
fields = _delimiterInfos[i].getMaxFields();
_statusLabel.setText("" + numRecords + " " + I18nManager.getText("dialog.openoptions.deliminfo.records")
+ " " + fields + " " + I18nManager.getText("dialog.openoptions.deliminfo.fields"));
}
}
}
// Don't show label if "other" delimiter is chosen (as records, fields are unknown)
if (_delimiterRadios[_delimiterRadios.length-1].isSelected())
{
_statusLabel.setText("");
}
// enable/disable next button
_nextButton.setEnabled((_delimiterRadios[4].isSelected() == false && fields > 1)
|| _otherDelimiterText.getText().length() == 1);
}
/**
* Get the delimiter info from the first step
* @return delimiter information object for the selected delimiter
*/
public DelimiterInfo getSelectedDelimiterInfo()
{
for (int i=0; i<4; i++)
if (_delimiterRadios[i].isSelected()) return _delimiterInfos[i];
// must be "other" - build info if necessary
if (_delimiterInfos[4] == null)
_delimiterInfos[4] = new DelimiterInfo(_otherDelimiterText.getText().charAt(0));
return _delimiterInfos[4];
}
/**
* Prepare the next panel to be shown, if necessary
*/
private void prepareNextPanel()
{
int currPanel = _wizard.getCurrentCardIndex();
if (currPanel == 0) {
prepareSecondPanel();
}
else if (currPanel == 1)
{
Field[] selectedFields = _fieldTableModel.getFieldArray();
// Enable / disable controls based on whether altitude / speed / vspeed fields were chosen on second panel
_componentHider.enableComponents(Field.ALTITUDE, doesFieldArrayContain(selectedFields, Field.ALTITUDE));
_componentHider.enableComponents(Field.SPEED, doesFieldArrayContain(selectedFields, Field.SPEED));
_componentHider.enableComponents(Field.VERTICAL_SPEED, doesFieldArrayContain(selectedFields, Field.VERTICAL_SPEED));
// TODO: Also check ranges of altitudes, speeds, vert speeds to show them in the third panel
}
}
/**
* Use the delimiter selected to determine the fields in the file
* and prepare the second panel accordingly
*/
private void prepareSecondPanel()
{
DelimiterInfo info = getSelectedDelimiterInfo();
FileSplitter splitter = new FileSplitter(_fileCacher);
// Check info makes sense - num fields > 0, num records > 0
// set "Finished" button to disabled if not ok
// Add data to GUI elements
String[][] tableData = splitter.splitFieldData(info.getDelimiter());
// possible to ignore blank columns here
_currentDelimiter = info.getDelimiter();
_fileExtractTableModel.updateData(tableData);
_fieldTableModel = new FieldSelectionTableModel();
// Check number of fields and use last ones if count matches
Field[] startFieldArray = null;
if (_lastSelectedFields != null && splitter.getNumColumns() == _lastSelectedFields.length)
{
startFieldArray = _lastSelectedFields;
}
else
{
// Take first full row of file and use it to guess fields
startFieldArray = FieldGuesser.guessFields(splitter.getFirstFullRow());
}
_fieldTableModel.updateData(startFieldArray);
_fieldTable.setModel(_fieldTableModel);
// add dropdowns to second column
JComboBox<String> fieldTypesBox = new JComboBox<String>();
String[] fieldNames = Field.getFieldNames();
for (int i=0; i<fieldNames.length; i++)
{
fieldTypesBox.addItem(fieldNames[i]);
}
_fieldTable.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(fieldTypesBox));
// Set altitude format to same as last time if available
if (_lastAltitudeUnit == UnitSetLibrary.UNITS_METRES)
_altitudeUnitsDropdown.setSelectedIndex(0);
else if (_lastAltitudeUnit == UnitSetLibrary.UNITS_FEET)
_altitudeUnitsDropdown.setSelectedIndex(1);
// no selection on field list
selectField(-1);
}
/**
* See if the given array of selected fields contains the specified one
* @param inFields array of fields selected by user in the second panel
* @param inCheck field to check
* @return true if the field is present in the array
*/
private boolean doesFieldArrayContain(Field[] inFields, Field inCheck)
{
if (inFields != null) {
for (int i=0; i<inFields.length; i++) {
if (inFields[i] == inCheck) { // == check ok here because it only checks for built-in fields
return true;
}
}
}
return false;
}
/**
* All options have been selected, so load file
*/
private void finished()
{
// Save delimiter, field array and altitude format for later use
_lastUsedDelimiter = _currentDelimiter;
_lastSelectedFields = _fieldTableModel.getFieldArray();
// TODO: Remember all the units selections for next load?
// Get the selected units for altitudes and speeds
SourceInfo sourceInfo = new SourceInfo(_file, SourceInfo.FILE_TYPE.TEXT);
PointCreateOptions options = new PointCreateOptions();
options.setAltitudeUnits(_altitudeUnitsDropdown.getSelectedIndex() == 0 ? UnitSetLibrary.UNITS_METRES : UnitSetLibrary.UNITS_FEET);
Unit hSpeedUnit = UnitSetLibrary.ALL_SPEED_UNITS[_hSpeedUnitsDropdown.getSelectedIndex()];
options.setSpeedUnits(hSpeedUnit);
Unit vSpeedUnit = UnitSetLibrary.ALL_SPEED_UNITS[_vSpeedUnitsDropdown.getSelectedIndex()];
options.setVerticalSpeedUnits(vSpeedUnit, _vSpeedUpwardsRadio.isSelected());
// give data to App
_app.informDataLoaded(_fieldTableModel.getFieldArray(),
_fileExtractTableModel.getData(), options, sourceInfo, null);
// clear up file cacher
_fileCacher.clear();
// dispose of dialog
_dialog.dispose();
}
/**
* @return true if the inputs on the current tab are valid, user is allowed to proceed
*/
private boolean isCurrentCardValid()
{
int cardIndex = _wizard.getCurrentCardIndex();
if (cardIndex == 1)
{
// validate second panel
return _fieldTableModel.getRowCount() > 1;
}
// all other panels are always valid
return true;
}
/**
* Make a panel with a label and a component
* @param inLabelKey label key to use
* @param inComponent component for main area of panel
* @return labelled Panel
*/
private static JPanel makeLabelledPanel(String inLabelKey, JComponent inComponent)
{
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JLabel(I18nManager.getText(inLabelKey)), BorderLayout.NORTH);
panel.add(inComponent, BorderLayout.CENTER);
return panel;
}
/**
* An entry in the field list has been selected
* @param inFieldNum index of field, starting with 0
*/
private void selectField(int inFieldNum)
{
if (inFieldNum == -1 || inFieldNum != _selectedField)
{
_selectedField = inFieldNum;
_moveUpButton.setEnabled(inFieldNum > 0);
_moveDownButton.setEnabled(inFieldNum >= 0
&& inFieldNum < (_fieldTableModel.getRowCount()-1));
}
}
/**
* @return the last delimiter character used for a load
*/
public char getLastUsedDelimiter()
{
return _lastUsedDelimiter;
}
}