- /**
- * Reset dialog and show it
- */
- public void begin()
- {
- // Check whether track has timestamps, exit if not
- if (!_app.getTrackInfo().getTrack().hasData(Field.TIMESTAMP))
- {
- JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("dialog.correlate.notimestamps"),
- I18nManager.getText(getNameKey()), JOptionPane.INFORMATION_MESSAGE);
- return;
- }
- // Check for any non-correlated photos, show warning continue/cancel
- if (!trackHasUncorrelatedPhotos())
- {
- Object[] buttonTexts = {I18nManager.getText("button.continue"), I18nManager.getText("button.cancel")};
- if (JOptionPane.showOptionDialog(_parentFrame, I18nManager.getText("dialog.correlate.nouncorrelatedphotos"),
- I18nManager.getText(getNameKey()), JOptionPane.YES_NO_OPTION,
- JOptionPane.WARNING_MESSAGE, null, buttonTexts, buttonTexts[1])
- == JOptionPane.NO_OPTION)
- {
- return;
- }
- }
- PhotoSelectionTableModel model = makePhotoSelectionTableModel(_app.getTrackInfo());
- _firstTabAvailable = model != null && model.getRowCount() > 0;
- CardLayout cl = (CardLayout) _cards.getLayout();
- if (_firstTabAvailable)
- {
- cl.first(_cards);
- _nextButton.setEnabled(true);
- _backButton.setEnabled(false);
- _tipLabel.setVisible(false);
- _photoSelectionTable.setModel(model);
- _previewEnabled = false;
- for (int i=0; i<model.getColumnCount(); i++) {
- _photoSelectionTable.getColumnModel().getColumn(i).setPreferredWidth(i==3?50:150);
- }
- // Calculate median time difference, select corresponding row of table
- int preselectedIndex = model.getRowCount() < 3 ? 0 : getMedianIndex(model);
- _photoSelectionTable.getSelectionModel().setSelectionInterval(preselectedIndex, preselectedIndex);
- _nextButton.requestFocus();
- }
- else
- {
- _tipLabel.setVisible(true);
- setupSecondCard(null);
- }
- _dialog.setVisible(true);
- }
-
-
- /**
- * Make contents of correlate dialog
- * @return JPanel containing gui elements
- */
- private JPanel makeDialogContents()
- {
- JPanel mainPanel = new JPanel();
- mainPanel.setLayout(new BorderLayout());
- // Card panel in the middle
- _cards = new JPanel();
- _cards.setLayout(new CardLayout());
-
- // First panel for photo selection table
- JPanel card1 = new JPanel();
- card1.setLayout(new BorderLayout(10, 10));
- card1.add(new JLabel(I18nManager.getText("dialog.correlate.photoselect.intro")), BorderLayout.NORTH);
- _photoSelectionTable = new JTable();
- JScrollPane photoScrollPane = new JScrollPane(_photoSelectionTable);
- photoScrollPane.setPreferredSize(new Dimension(400, 100));
- card1.add(photoScrollPane, BorderLayout.CENTER);
- _cards.add(card1, "card1");
-
- OptionsChangedListener optionsChangedListener = new OptionsChangedListener(this);
- // Second panel for options
- JPanel card2 = new JPanel();
- card2.setLayout(new BorderLayout());
- JPanel card2Top = new JPanel();
- card2Top.setLayout(new BoxLayout(card2Top, BoxLayout.Y_AXIS));
- _tipLabel = new JLabel(I18nManager.getText("dialog.correlate.options.tip"));
- card2Top.add(_tipLabel);
- card2Top.add(new JLabel(I18nManager.getText("dialog.correlate.options.intro")));
- // time offset section
- JPanel offsetPanel = new JPanel();
- offsetPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.correlate.options.offsetpanel")));
- offsetPanel.setLayout(new BoxLayout(offsetPanel, BoxLayout.Y_AXIS));
- JPanel offsetPanelTop = new JPanel();
- offsetPanelTop.setLayout(new FlowLayout());
- offsetPanelTop.setBorder(null);
- offsetPanelTop.add(new JLabel(I18nManager.getText("dialog.correlate.options.offset") + ": "));
- _offsetHourBox = new JTextField(3);
- _offsetHourBox.addKeyListener(optionsChangedListener);
- offsetPanelTop.add(_offsetHourBox);
- offsetPanelTop.add(new JLabel(I18nManager.getText("dialog.correlate.options.offset.hours")));
- _offsetMinBox = new JTextField(3);
- _offsetMinBox.addKeyListener(optionsChangedListener);
- offsetPanelTop.add(_offsetMinBox);
- offsetPanelTop.add(new JLabel(I18nManager.getText("dialog.correlate.options.offset.minutes")));
- _offsetSecBox = new JTextField(3);
- _offsetSecBox.addKeyListener(optionsChangedListener);
- offsetPanelTop.add(_offsetSecBox);
- offsetPanelTop.add(new JLabel(I18nManager.getText("dialog.correlate.options.offset.seconds")));
- offsetPanel.add(offsetPanelTop);
-
- // radio buttons for photo / point later
- JPanel offsetPanelBot = new JPanel();
- offsetPanelBot.setLayout(new FlowLayout());
- offsetPanelBot.setBorder(null);
- _photoLaterOption = new JRadioButton(I18nManager.getText("dialog.correlate.options.photolater"));
- _pointLaterOption = new JRadioButton(I18nManager.getText("dialog.correlate.options.pointlater"));
- _photoLaterOption.addItemListener(optionsChangedListener);
- _pointLaterOption.addItemListener(optionsChangedListener);
- ButtonGroup laterGroup = new ButtonGroup();
- laterGroup.add(_photoLaterOption);
- laterGroup.add(_pointLaterOption);
- offsetPanelBot.add(_photoLaterOption);
- offsetPanelBot.add(_pointLaterOption);
- offsetPanel.add(offsetPanelBot);
- offsetPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
- card2Top.add(offsetPanel);
-
- // time limits section
- JPanel limitsPanel = new JPanel();
- limitsPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.correlate.options.limitspanel")));
- limitsPanel.setLayout(new BoxLayout(limitsPanel, BoxLayout.Y_AXIS));
- JPanel timeLimitPanel = new JPanel();
- timeLimitPanel.setLayout(new FlowLayout());
- JRadioButton noTimeLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.notimelimit"));
- noTimeLimitRadio.addItemListener(optionsChangedListener);
- timeLimitPanel.add(noTimeLimitRadio);
- _timeLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.timelimit") + " : ");
- _timeLimitRadio.addItemListener(optionsChangedListener);
- timeLimitPanel.add(_timeLimitRadio);
- groupRadioButtons(noTimeLimitRadio, _timeLimitRadio);
- _limitMinBox = new JTextField(3);
- _limitMinBox.addKeyListener(optionsChangedListener);
- timeLimitPanel.add(_limitMinBox);
- timeLimitPanel.add(new JLabel(I18nManager.getText("dialog.correlate.options.offset.minutes")));
- _limitSecBox = new JTextField(3);
- _limitSecBox.addKeyListener(optionsChangedListener);
- timeLimitPanel.add(_limitSecBox);
- timeLimitPanel.add(new JLabel(I18nManager.getText("dialog.correlate.options.offset.seconds")));
- limitsPanel.add(timeLimitPanel);
- // distance limits
- JPanel distLimitPanel = new JPanel();
- distLimitPanel.setLayout(new FlowLayout());
- JRadioButton noDistLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.nodistancelimit"));
- noDistLimitRadio.addItemListener(optionsChangedListener);
- distLimitPanel.add(noDistLimitRadio);
- _distLimitRadio = new JRadioButton(I18nManager.getText("dialog.correlate.options.distancelimit"));
- _distLimitRadio.addItemListener(optionsChangedListener);
- distLimitPanel.add(_distLimitRadio);
- groupRadioButtons(noDistLimitRadio, _distLimitRadio);
- _limitDistBox = new JTextField(4);
- _limitDistBox.addKeyListener(optionsChangedListener);
- distLimitPanel.add(_limitDistBox);
- String[] distUnitsOptions = {I18nManager.getText("units.kilometres"), I18nManager.getText("units.metres"),
- I18nManager.getText("units.miles")};
- _distUnitsDropdown = new JComboBox(distUnitsOptions);
- _distUnitsDropdown.addItemListener(optionsChangedListener);
- distLimitPanel.add(_distUnitsDropdown);
- limitsPanel.add(distLimitPanel);
- limitsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
- card2Top.add(limitsPanel);
-
- // preview button
- JButton previewButton = new JButton(I18nManager.getText("button.preview"));
- previewButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- createPreview(true);
- }
- });
- card2Top.add(previewButton);
- card2.add(card2Top, BorderLayout.NORTH);
- // preview
- _previewTable = new JTable();
- JScrollPane previewScrollPane = new JScrollPane(_previewTable);
- previewScrollPane.setPreferredSize(new Dimension(300, 100));
- card2.add(previewScrollPane, BorderLayout.CENTER);
- _cards.add(card2, "card2");
- mainPanel.add(_cards, BorderLayout.CENTER);
-
- // Button panel at the bottom
- JPanel buttonPanel = new JPanel();
- _backButton = new JButton(I18nManager.getText("button.back"));
- _backButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- CardLayout cl = (CardLayout) _cards.getLayout();
- cl.previous(_cards);
- _backButton.setEnabled(false);
- _nextButton.setEnabled(true);
- _okButton.setEnabled(false);
- _previewEnabled = false;
- }
- });
- _backButton.setEnabled(false);
- buttonPanel.add(_backButton);
- _nextButton = new JButton(I18nManager.getText("button.next"));
- _nextButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- int rowNum = _photoSelectionTable.getSelectedRow();
- if (rowNum < 0) {rowNum = 0;}
- PhotoSelectionTableRow selectedRow = ((PhotoSelectionTableModel) _photoSelectionTable.getModel())
- .getRow(rowNum);
- setupSecondCard(selectedRow.getTimeDiff());
- }
- });
- buttonPanel.add(_nextButton);
- _okButton = new JButton(I18nManager.getText("button.ok"));
- _okButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- finishCorrelation();
- _dialog.dispose();
- }
- });
- _okButton.setEnabled(false);
- buttonPanel.add(_okButton);
- JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
- cancelButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- _dialog.dispose();
- }
- });
- buttonPanel.add(cancelButton);
- mainPanel.add(buttonPanel, BorderLayout.SOUTH);
- return mainPanel;
- }
-
-
- /**
- * Construct a table model for the photo selection table
- * @param inTrackInfo track info object
- * @return table model
- */
- private static PhotoSelectionTableModel makePhotoSelectionTableModel(TrackInfo inTrackInfo)
- {
- PhotoSelectionTableModel model = new PhotoSelectionTableModel();
- int numPhotos = inTrackInfo.getPhotoList().getNumPhotos();
- for (int i=0; i<numPhotos; i++)
- {
- Photo photo = inTrackInfo.getPhotoList().getPhoto(i);
- if (photo.getDataPoint() != null && photo.getDataPoint().hasTimestamp())
- {
- // Calculate time difference, add to table model
- long timeDiff = photo.getTimestamp().getSecondsSince(photo.getDataPoint().getTimestamp());
- model.addPhoto(photo, timeDiff);
- }
- }
- return model;
- }
-
-
- /**
- * Group the two radio buttons together with a ButtonGroup
- * @param inButton1 first radio button
- * @param inButton2 second radio button
- */
- private static void groupRadioButtons(JRadioButton inButton1, JRadioButton inButton2)
- {
- ButtonGroup buttonGroup = new ButtonGroup();
- buttonGroup.add(inButton1);
- buttonGroup.add(inButton2);
- inButton1.setSelected(true);
- }
-
-
- /**
- * Set up the second card using the given time difference and show it
- * @param inTimeDiff time difference to use for photo time offsets
- */
- private void setupSecondCard(TimeDifference inTimeDiff)
- {
- _previewEnabled = false;
- boolean hasTimeDiff = inTimeDiff != null;
- if (!hasTimeDiff)
- {
- // No time difference available, so calculate based on computer's time zone
- inTimeDiff = getTimezoneOffset();
- }
- // Use time difference to set edit boxes
- _offsetHourBox.setText("" + inTimeDiff.getNumHours());
- _offsetMinBox.setText("" + inTimeDiff.getNumMinutes());
- _offsetSecBox.setText("" + inTimeDiff.getNumSeconds());
- _photoLaterOption.setSelected(inTimeDiff.getIsPositive());
- _pointLaterOption.setSelected(!inTimeDiff.getIsPositive());
- createPreview(inTimeDiff, true);
- CardLayout cl = (CardLayout) _cards.getLayout();
- cl.next(_cards);
- _backButton.setEnabled(hasTimeDiff);
- _nextButton.setEnabled(false);
- // enable ok button if any photos have been selected
- _okButton.setEnabled(((PhotoPreviewTableModel) _previewTable.getModel()).hasPhotosSelected());
- _previewEnabled = true;