protected void commit() {
    if (!model.isTableComplete()) {
      JOptionPane.showMessageDialog(
          this,
          "The table is incomplete.  You must provide names for all series before continuing");
      return;
    }

    searchDatabaseForMatches();

    if (model.areThereMissingEntites(true)) {
      Object[] options = {"Yes", "No", "Cancel"};
      int n =
          JOptionPane.showOptionDialog(
              this,
              "Some of the entities are not currently in the database. If you continue, "
                  + "basic records for these entities will automatically be created.\n\n"
                  + "Would you like to proceed?",
              "Confirmation",
              JOptionPane.YES_NO_CANCEL_OPTION,
              JOptionPane.QUESTION_MESSAGE,
              null,
              options,
              options[2]);

      if (n == JOptionPane.OK_OPTION) {
        model.generateMissingEntities(
            this.chkIncludeSubobjects.isSelected(), defaultEntitiesDialog);
      } else if (n == JOptionPane.CANCEL_OPTION) {
        return;
      }
    }

    // Open the series in an editor if requested
    if (chckbxOpenSeriesIn.isSelected()) {
      openEditor();
    }

    containerFrame.setVisible(false);
  }
  @Override
  public void actionPerformed(ActionEvent evt) {
    if (evt.getActionCommand().equals("SearchDB")) {
      searchDatabaseForMatches();
    } else if (evt.getActionCommand().equals("Finish")) {
      commit();
    } else if (evt.getActionCommand().equals("Cancel")) {
      containerFrame.dispose();
    } else if (evt.getActionCommand().equals("DefineByPattern")) {
      fillTableByPattern();
    } else if (evt.getActionCommand().equals("IncludeExcludeSubObjects")) {
      table.getColumnExt("SubObjectColumn").setVisible(this.chkIncludeSubobjects.isSelected());
    } else if (evt.getActionCommand().equals("SetDefaults")) {

      /*MVCArrayList<ControlledVoc> objectdic = Dictionary.getMutableDictionary("objectTypeDictionary");
      for(ControlledVoc item : objectdic)
      {
      	if(item.getNormal().equals("Site"))
      	{
      		defaultEntitiesDialog.setDefaultValues(item);
      	}
      }*/

      defaultEntitiesDialog.setVisible(true);

      if (defaultEntitiesDialog == null) {
        defaultEntitiesDialog = new DefaultEntityParametersDialog(containerFrame);
      }

    } else if (evt.getActionCommand().equals("GenerateMissing")) {
      if (model.areThereEmptyCells(this.chkIncludeSubobjects.isSelected())) {
        Alert.message(
            containerFrame,
            "Missing entries",
            "You must provide titles for all entities in the table.");
        return;
      }

      searchDatabaseForMatches();

      if (!model.areThereMissingEntites(true)) {
        Alert.message(containerFrame, "Nothing to do", "There are no entities to create!");
        return;
      }

      Object[] options = {"Yes", "No", "Cancel"};
      int n =
          JOptionPane.showOptionDialog(
              this,
              "You are about to create basic database entities for all the red crosses in the table.\n"
                  + "Are you sure you want to continue?",
              "Confirmation",
              JOptionPane.YES_NO_CANCEL_OPTION,
              JOptionPane.QUESTION_MESSAGE,
              null,
              options,
              options[2]);

      if (n == JOptionPane.OK_OPTION) {
        model.generateMissingEntities(
            this.chkIncludeSubobjects.isSelected(), this.defaultEntitiesDialog);
      }

      return;
    }
  }
  /** Populate the table using information specified in the regex pattern dialog */
  private void fillTableByPattern() {
    SeriesIdentityRegexDialog dialog =
        new SeriesIdentityRegexDialog(
            containerFrame, model.getSeriesIdentity(0), this.chkIncludeSubobjects.isSelected());

    dialog.setLocationRelativeTo(containerFrame);
    dialog.setVisible(true);

    if (dialog.cancelled) return;

    for (int i = 0; i < model.getRowCount(); i++) {
      SeriesIdentity id = model.getSeriesIdentity(i);

      // Object
      String orig =
          SeriesIdentityRegexDialog.getStringToTest(
              id, dialog.getSelectedFieldOption(TridasObject.class));
      MethodOptions method = dialog.getSelectedMethodOption(TridasObject.class);
      String pattern = dialog.getPattern(TridasObject.class);
      Integer matchNum = dialog.getMatchNum(TridasObject.class, false);
      if (!method.equals(MethodOptions.NONE))
        model.setValueAt(
            SeriesIdentityRegexDialog.getPatternMatch(orig, method, pattern, matchNum), i, 3);

      // Sub-Object
      orig =
          SeriesIdentityRegexDialog.getStringToTest(
              id, dialog.getSelectedFieldOption(TridasObject.class, true));
      method = dialog.getSelectedMethodOption(TridasObject.class, true);
      pattern = dialog.getPattern(TridasObject.class, true);
      matchNum = dialog.getMatchNum(TridasObject.class, true);
      if (!method.equals(MethodOptions.NONE))
        model.setValueAt(
            SeriesIdentityRegexDialog.getPatternMatch(orig, method, pattern, matchNum), i, 4);

      // Element
      orig =
          SeriesIdentityRegexDialog.getStringToTest(
              id, dialog.getSelectedFieldOption(TridasElement.class));
      method = dialog.getSelectedMethodOption(TridasElement.class);
      pattern = dialog.getPattern(TridasElement.class);
      matchNum = dialog.getMatchNum(TridasElement.class, true);
      if (!method.equals(MethodOptions.NONE))
        model.setValueAt(
            SeriesIdentityRegexDialog.getPatternMatch(orig, method, pattern, matchNum), i, 5);

      // Sample
      orig =
          SeriesIdentityRegexDialog.getStringToTest(
              id, dialog.getSelectedFieldOption(TridasSample.class));
      method = dialog.getSelectedMethodOption(TridasSample.class);
      pattern = dialog.getPattern(TridasSample.class);
      matchNum = dialog.getMatchNum(TridasSample.class, true);
      if (!method.equals(MethodOptions.NONE))
        model.setValueAt(
            SeriesIdentityRegexDialog.getPatternMatch(orig, method, pattern, matchNum), i, 6);

      // Radius
      orig =
          SeriesIdentityRegexDialog.getStringToTest(
              id, dialog.getSelectedFieldOption(TridasRadius.class));
      method = dialog.getSelectedMethodOption(TridasRadius.class);
      pattern = dialog.getPattern(TridasRadius.class);
      matchNum = dialog.getMatchNum(TridasRadius.class, true);
      if (!method.equals(MethodOptions.NONE))
        model.setValueAt(
            SeriesIdentityRegexDialog.getPatternMatch(orig, method, pattern, matchNum), i, 7);

      // Series
      orig =
          SeriesIdentityRegexDialog.getStringToTest(
              id, dialog.getSelectedFieldOption(TridasMeasurementSeries.class));
      method = dialog.getSelectedMethodOption(TridasMeasurementSeries.class);
      pattern = dialog.getPattern(TridasMeasurementSeries.class);
      matchNum = dialog.getMatchNum(TridasMeasurementSeries.class, true);
      if (!method.equals(MethodOptions.NONE))
        model.setValueAt(
            SeriesIdentityRegexDialog.getPatternMatch(orig, method, pattern, matchNum), i, 8);
    }
  }
 /** Open the editor with these series imported */
 private void openEditor() {
   FullEditor editor = FullEditor.getInstance();
   editor.addSamples(model.getAllSamples(this.chkIncludeSubobjects.isSelected()));
 }
 /** Search the database for entity matches based on the codes specified in the table */
 public void searchDatabaseForMatches() {
   model.searchForMatches();
 }
  /**
   * Parse the specified legacy data file for series
   *
   * @param file
   * @param fileType
   */
  private void parseFile(File file, AbstractDendroFormat format) {

    ArrayList<Sample> sampleList = new ArrayList<Sample>();

    // Create a reader based on the file type supplied
    AbstractDendroFileReader reader = TridasIO.getFileReaderFromFormat(format);
    if (reader == null) {
      Alert.error(containerFrame, "Error", "Unknown file type");
      return;
    }

    // Try and load the file
    try {
      reader.loadFile(file.getAbsolutePath());
    } catch (IOException e) {
      Alert.errorLoading(file.getAbsolutePath(), e);
      return;
    } catch (InvalidDendroFileException e) {
      Alert.error(
          containerFrame,
          "Error",
          "The selected file is not a valid "
              + format.getShortName()
              + " file.\nPlease check and try again");
      return;
    } catch (NullPointerException e) {
      Alert.error(containerFrame, "Invalid File", e.getLocalizedMessage());
    }

    TridasTridas tc = reader.getTridasContainer();
    log.debug("Project count: " + tc.getProjects().size());

    Boolean hideWarningsFlag = false;
    for (TridasProject p : tc.getProjects()) {
      for (TridasObject o : p.getObjects()) {

        for (TridasElement e : TridasUtils.getElementList(o)) {
          log.debug("Element count: " + o.getElements().size());

          for (TridasSample s : e.getSamples()) {
            for (TridasRadius r : s.getRadiuses()) {
              for (TridasMeasurementSeries ms : r.getMeasurementSeries()) {
                Sample sample =
                    EditorFactory.createSampleFromSeries(ms, e, file, format, hideWarningsFlag);
                if (sample == null) {
                  hideWarningsFlag = true;
                } else {
                  sampleList.add(sample);
                }
              }
            }
          }
        }
      }

      for (TridasDerivedSeries ds : p.getDerivedSeries()) {
        Sample sample =
            EditorFactory.createSampleFromSeries(ds, null, file, format, hideWarningsFlag);

        if (sample == null) {
          hideWarningsFlag = true;
        } else {
          sampleList.add(sample);
        }
      }
    }

    Boolean unitsSet = false;
    for (ITridasSeries ser : getSeries(sampleList)) {
      for (TridasValues tv : ser.getValues()) {
        if (tv.isSetUnit()) {
          if (tv.getUnit().isSetNormalTridas()) {
            unitsSet = true;
          }
        }
      }
    }

    if (unitsSet == false && sampleList.size() > 0 && unitsIfNotSpecified == null) {
      Object[] possibilities = {"1/1000th mm", "1/100th mm", "1/50th mm", "1/20th mm", "1/10th mm"};
      Object s =
          JOptionPane.showInputDialog(
              containerFrame,
              "One or more series has no units defined.\n" + "Please specify units below:",
              "Set Units",
              JOptionPane.PLAIN_MESSAGE,
              null,
              possibilities,
              "1/1000th mm");

      if (s.equals("1/1000th mm")) {
        unitsIfNotSpecified = NormalTridasUnit.MICROMETRES;
      } else if (s.equals("1/100th mm")) {
        unitsIfNotSpecified = NormalTridasUnit.HUNDREDTH_MM;
      } else if (s.equals("1/50th mm")) {
        unitsIfNotSpecified = NormalTridasUnit.FIFTIETH_MM;
      } else if (s.equals("1/20th mm")) {
        unitsIfNotSpecified = NormalTridasUnit.TWENTIETH_MM;
      } else if (s.equals("1/10th mm")) {
        unitsIfNotSpecified = NormalTridasUnit.TENTH_MM;
      } else {
        Alert.error(containerFrame, "Error", "Invalid measurement units specified");
        return;
      }
    }

    for (Sample sample : sampleList) {
      ITridasSeries series = sample.getSeries();

      try {
        for (int i = 0; i < series.getValues().size(); i++) {
          TridasValues tv = series.getValues().get(i);

          if (tv.isSetUnit()) {
            if (!tv.getUnit().isSetNormalTridas()) {
              tv.getUnit().setNormalTridas(unitsIfNotSpecified);
            }
          } else {
            TridasUnit unit = new TridasUnit();
            unit.setNormalTridas(unitsIfNotSpecified);
            tv.setUnit(unit);
            tv.setUnitless(null);
          }

          tv = UnitUtils.convertTridasValues(NormalTridasUnit.MICROMETRES, tv, true);

          TridasUnit unit = new TridasUnit();
          unit.setNormalTridas(NormalTridasUnit.MICROMETRES);
          tv.setUnit(unit);
          series.getValues().set(i, tv);
        }

      } catch (NumberFormatException e) {
        Alert.error("Error", "One or more data values are not numbers.");
        return;
      } catch (ConversionWarningException e) {
        Alert.error("Error", "Error converting units");
        return;
      }
    }

    for (Sample s : sampleList) {
      SeriesIdentity id = new SeriesIdentity(file, format, s);

      model.addItem(id);
    }
  }
  /** Initialize the GUI */
  private void init() {
    setLayout(new BorderLayout(0, 0));

    JPanel panelMain = new JPanel();
    add(panelMain, BorderLayout.CENTER);
    panelMain.setLayout(new MigLayout("", "[grow]", "[grow]"));

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    panelMain.add(scrollPane, "cell 0 0,grow");

    table =
        new JXTable() {
          private static final long serialVersionUID = 1L;

          public void changeSelection(
              final int row, final int column, boolean toggle, boolean extend) {
            super.changeSelection(row, column, toggle, extend);
            if (table.isCellEditable(row, column)) {
              editCellAt(row, column);
            }
          }
        };

    table.setHorizontalScrollEnabled(true);
    table.setColumnControlVisible(true);
    model = new SeriesIdentityTableModel(containerFrame);

    SeriesIdentityTableCellRenderer renderer = new SeriesIdentityTableCellRenderer();

    table.setModel(model);

    table.getColumn(3).setCellRenderer(renderer);
    table.getColumn(4).setCellRenderer(renderer);
    table.getColumn(5).setCellRenderer(renderer);
    table.getColumn(6).setCellRenderer(renderer);
    table.getColumn(7).setCellRenderer(renderer);
    table.getColumn(8).setCellRenderer(renderer);
    table.getColumnExt(4).setIdentifier("SubObjectColumn");
    table.getColumnExt("SubObjectColumn").setVisible(false);

    table
        .getColumnModel()
        .addColumnModelListener(
            new TableColumnModelListener() {

              @Override
              public void columnAdded(TableColumnModelEvent arg0) {

                chkIncludeSubobjects.setSelected(table.getColumnExt("SubObjectColumn").isVisible());
              }

              @Override
              public void columnMarginChanged(ChangeEvent arg0) {
                // TODO Auto-generated method stub

              }

              @Override
              public void columnMoved(TableColumnModelEvent arg0) {
                // TODO Auto-generated method stub

              }

              @Override
              public void columnRemoved(TableColumnModelEvent arg0) {
                chkIncludeSubobjects.setSelected(table.getColumnExt("SubObjectColumn").isVisible());
              }

              @Override
              public void columnSelectionChanged(ListSelectionEvent arg0) {
                // TODO Auto-generated method stub

              }
            });

    scrollPane.setViewportView(table);

    JPanel panelButton = new JPanel();
    add(panelButton, BorderLayout.SOUTH);
    panelButton.setLayout(new MigLayout("", "[grow][][]", "[grow][grow][][][]"));

    model.addTableModelListener(this);

    JPanel panel = new JPanel();
    panelButton.add(panel, "cell 0 1 1 2,grow");
    panel.setLayout(new MigLayout("", "[31px][162px]", "[16px][][]"));

    JLabel lblKey = new JLabel("Key:");
    panel.add(lblKey, "cell 0 0,alignx left,aligny top");

    JLabel lblPresentIn = new JLabel("= Present in database");
    lblPresentIn.setFont(new Font("Dialog", Font.PLAIN, 12));
    lblPresentIn.setIcon(Builder.getIcon("found.png", 16));
    panel.add(lblPresentIn, "flowy,cell 1 0,alignx left,aligny top");

    JLabel lblAbsentFrom = new JLabel("= Absent from database");
    lblAbsentFrom.setFont(new Font("Dialog", Font.PLAIN, 12));
    lblAbsentFrom.setIcon(Builder.getIcon("missing.png", 16));
    panel.add(lblAbsentFrom, "cell 1 1,alignx left,aligny top");

    JLabel lblNotYet = new JLabel("= Not yet searched");
    lblNotYet.setFont(new Font("Dialog", Font.PLAIN, 12));
    lblNotYet.setIcon(Builder.getIcon("wait.png", 16));
    panel.add(lblNotYet, "cell 1 2,alignx left,aligny top");

    JPanel panel_1 = new JPanel();
    panelButton.add(panel_1, "cell 1 1 2 2,alignx right,growy");
    panel_1.setLayout(new MigLayout("", "[116px,fill]", "[22px][][][]"));

    JButton btnSearchDB = new JButton("Search Database");
    btnSearchDB.setFont(new Font("Dialog", Font.BOLD, 9));
    panel_1.add(btnSearchDB, "cell 0 0,alignx left,aligny top");
    btnSearchDB.setActionCommand("SearchDB");

    JButton btnDefineByPattern = new JButton("Define names by pattern");
    btnDefineByPattern.setFont(new Font("Dialog", Font.BOLD, 9));
    panel_1.add(btnDefineByPattern, "cell 0 1,alignx left,aligny top");
    btnDefineByPattern.setActionCommand("DefineByPattern");

    JButton btnGenerateMissing = new JButton("Generate missing entities");
    btnGenerateMissing.setActionCommand("GenerateMissing");
    btnGenerateMissing.addActionListener(this);

    JButton btnSetDefaults = new JButton("Set default parameters");
    btnSetDefaults.setActionCommand("SetDefaults");
    btnSetDefaults.addActionListener(this);
    btnSetDefaults.setFont(new Font("Dialog", Font.BOLD, 9));
    panel_1.add(btnSetDefaults, "cell 0 2");

    btnGenerateMissing.setFont(new Font("Dialog", Font.BOLD, 9));
    panel_1.add(btnGenerateMissing, "flowy,cell 0 3");
    btnDefineByPattern.addActionListener(this);
    btnSearchDB.addActionListener(this);

    chkIncludeSubobjects = new JCheckBox("Include sub-objects in import");
    chkIncludeSubobjects.addActionListener(this);
    chkIncludeSubobjects.setActionCommand("IncludeExcludeSubObjects");
    panelButton.add(chkIncludeSubobjects, "cell 0 3");

    chckbxOpenSeriesIn = new JCheckBox("Open series in editor when finished");
    chckbxOpenSeriesIn.setSelected(true);
    panelButton.add(chckbxOpenSeriesIn, "cell 0 4");
  }