package tim.prune.load;
import java.awt.BorderLayout;
-import java.awt.CardLayout;
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 tim.prune.App;
import tim.prune.I18nManager;
-import tim.prune.data.Altitude;
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;
/**
private App _app = null;
private JFrame _parentFrame = null;
private JDialog _dialog = null;
- private JPanel _cardPanel = null;
- private CardLayout _layout = null;
+ private WizardLayout _wizard = null;
private JButton _backButton = null, _nextButton = null;
private JButton _finishButton = null;
private JButton _moveUpButton = null, _moveDownButton = null;
private JLabel _statusLabel = null;
private DelimiterInfo[] _delimiterInfos = null;
private FileCacher _fileCacher = null;
- private JList _snippetBox = null;
+ private JList<String> _snippetBox = null;
private FileExtractTableModel _fileExtractTableModel = null;
private JTable _fieldTable;
private FieldSelectionTableModel _fieldTableModel = null;
- private JComboBox _unitsDropDown = 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 int _lastAltitudeFormat = Altitude.FORMAT_NONE;
+ private Unit _lastAltitudeUnit = null;
// constants
private static final int SNIPPET_SIZE = 6;
{
_dialog = new JDialog(_parentFrame, I18nManager.getText("dialog.openoptions.title"), true);
_dialog.setLocationRelativeTo(_parentFrame);
- _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ _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)
_delimiterRadios[_delimiterRadios.length-1].setSelected(true);
informDelimiterSelected();
_dialog.pack();
- _dialog.show();
+ _dialog.setVisible(true);
}
else
{
- JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.load.noread"),
- I18nManager.getText("error.load.dialogtitle"), JOptionPane.ERROR_MESSAGE);
+ // Didn't pass pre-check
+ _app.showErrorMessageNoLookup("error.load.dialogtitle",
+ I18nManager.getText("error.load.noread") + ": " + inFile.getName());
+ _app.informNoDataLoaded();
}
}
// 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]);
_backButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
- _layout.previous(_cardPanel);
- _backButton.setEnabled(false);
- _nextButton.setEnabled(true);
+ _wizard.showPreviousCard();
+ _nextButton.setEnabled(!_wizard.isLastCard());
+ _backButton.setEnabled(!_wizard.isFirstCard());
_finishButton.setEnabled(false);
}
});
_nextButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
- prepareSecondPanel();
- _layout.next(_cardPanel);
- _nextButton.setEnabled(false);
- _backButton.setEnabled(true);
- _finishButton.setEnabled(_fieldTableModel.getRowCount() > 1);
+ 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);
public void actionPerformed(ActionEvent e)
{
_dialog.dispose();
+ _app.informNoDataLoaded();
}
});
buttonPanel.add(cancelButton);
wholePanel.add(buttonPanel, BorderLayout.SOUTH);
- // Make the two cards, for delimiter and fields
- _cardPanel = new JPanel();
- _layout = new CardLayout();
- _cardPanel.setLayout(_layout);
+ // 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(_statusLabel);
firstCard.add(delimsPanel, BorderLayout.SOUTH);
// load snippet to show first few lines
- _snippetBox = new JList(_fileCacher.getSnippet(SNIPPET_SIZE, MAX_SNIPPET_WIDTH));
+ _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.tabledesc", tableScrollPane), BorderLayout.NORTH);
+ 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
}
}
});
- JPanel tablePanel = new JPanel();
- tablePanel.setLayout(new BorderLayout());
- tablePanel.add(_fieldTable.getTableHeader(), BorderLayout.NORTH);
- tablePanel.add(_fieldTable, BorderLayout.CENTER);
- innerPanel2.add(tablePanel, BorderLayout.CENTER);
+ 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));
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();
- altUnitsPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
- altUnitsPanel.add(new JLabel(I18nManager.getText("dialog.openoptions.altitudeunits")));
- String[] units = {I18nManager.getText("units.metres"), I18nManager.getText("units.feet")};
- _unitsDropDown = new JComboBox(units);
- altUnitsPanel.add(_unitsDropDown);
- secondCard.add(altUnitsPanel, BorderLayout.SOUTH);
- _cardPanel.add(firstCard, "card1");
- _cardPanel.add(secondCard, "card2");
-
- wholePanel.add(_cardPanel, BorderLayout.CENTER);
+ 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;
}
}
+ /**
+ * 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
_fieldTableModel.updateData(startFieldArray);
_fieldTable.setModel(_fieldTableModel);
// add dropdowns to second column
- JComboBox fieldTypesBox = new JComboBox();
- for (int i=0; i<Field.ALL_AVAILABLE_FIELDS.length; i++)
+ JComboBox<String> fieldTypesBox = new JComboBox<String>();
+ String[] fieldNames = Field.getFieldNames();
+ for (int i=0; i<fieldNames.length; i++)
{
- fieldTypesBox.addItem(Field.ALL_AVAILABLE_FIELDS[i].getName());
+ fieldTypesBox.addItem(fieldNames[i]);
}
_fieldTable.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(fieldTypesBox));
// Set altitude format to same as last time if available
- if (_lastAltitudeFormat == Altitude.FORMAT_METRES)
- _unitsDropDown.setSelectedIndex(0);
- else if (_lastAltitudeFormat == Altitude.FORMAT_FEET)
- _unitsDropDown.setSelectedIndex(1);
+ 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
// Save delimiter, field array and altitude format for later use
_lastUsedDelimiter = _currentDelimiter;
_lastSelectedFields = _fieldTableModel.getFieldArray();
- int altitudeFormat = Altitude.FORMAT_METRES;
- if (_unitsDropDown.getSelectedIndex() == 1)
- {
- altitudeFormat = Altitude.FORMAT_FEET;
- }
- _lastAltitudeFormat = altitudeFormat;
+ // 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(), altitudeFormat,
- _file.getName());
+ _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