+ data[dataIndex][TYPE_COLUMN] = type;
+ data[dataIndex][COLOUR_COLUMN] = fr.getFeatureStyle(type);
+ FeatureMatcherSetI featureFilter = fr.getFeatureFilter(type);
+ data[dataIndex][FILTER_COLUMN] = featureFilter == null
+ ? new FeatureMatcherSet()
+ : featureFilter;
+ data[dataIndex][SHOW_COLUMN] = new Boolean(
+ af.getViewport().getFeaturesDisplayed().isVisible(type));
+ dataIndex++;
+ displayableTypes.remove(type);
+ }
+ }
+
+ /*
+ * process any extra features belonging only to
+ * a group which was just selected
+ */
+ while (!displayableTypes.isEmpty())
+ {
+ String type = displayableTypes.iterator().next();
+ data[dataIndex][TYPE_COLUMN] = type;
+
+ data[dataIndex][COLOUR_COLUMN] = fr.getFeatureStyle(type);
+ if (data[dataIndex][COLOUR_COLUMN] == null)
+ {
+ // "Colour has been updated in another view!!"
+ fr.clearRenderOrder();
+ return;
+ }
+ FeatureMatcherSetI featureFilter = fr.getFeatureFilter(type);
+ data[dataIndex][FILTER_COLUMN] = featureFilter == null
+ ? new FeatureMatcherSet()
+ : featureFilter;
+ data[dataIndex][SHOW_COLUMN] = new Boolean(true);
+ dataIndex++;
+ displayableTypes.remove(type);
+ }
+
+ if (originalData == null)
+ {
+ originalData = new Object[data.length][COLUMN_COUNT];
+ for (int i = 0; i < data.length; i++)
+ {
+ System.arraycopy(data[i], 0, originalData[i], 0, COLUMN_COUNT);
+ }
+ }
+ else
+ {
+ updateOriginalData(data);
+ }
+
+ /*
+ * recreate the table model
+ */
+ FeatureTableModel dataModel = new FeatureTableModel(data);
+ table.setModel(dataModel);
+
+ /*
+ * we want to be able to filter out rows for sub-types, but not to sort
+ * rows, so have to add a RowFilter to a disabled TableRowSorter (!)
+ */
+ final TableRowSorter<FeatureTableModel> sorter = new TableRowSorter<>(
+ dataModel);
+ for (int i = 0; i < table.getColumnCount(); i++)
+ {
+ sorter.setSortable(i, false);
+ }
+
+ /*
+ * filter rows to only top-level Ontology types if requested
+ */
+ sorter.setRowFilter(new RowFilter<FeatureTableModel, Integer>()
+ {
+ @Override
+ public boolean include(
+ Entry<? extends FeatureTableModel, ? extends Integer> entry)
+ {
+ if (!summaryView.isSelected())
+ {
+ return true;
+ }
+ int row = entry.getIdentifier(); // this is model, not view, row number
+ String featureType = (String) entry.getModel().getData()[row][TYPE_COLUMN];
+ return parents.contains(featureType);
+ }
+ });
+ table.setRowSorter(sorter);
+
+ table.getColumnModel().getColumn(0).setPreferredWidth(200);
+
+ groupPanel.setLayout(
+ new GridLayout(fr.getFeatureGroupsSize() / 4 + 1, 4));
+ pruneGroups(foundGroups);
+ groupPanel.validate();
+
+ updateFeatureRenderer(data, groupChanged != null);
+ resettingTable = false;
+ }
+
+ /**
+ * Updates 'originalData' (used for restore on Cancel) if we detect that changes
+ * have been made outwith this dialog
+ * <ul>
+ * <li>a new feature type added (and made visible)</li>
+ * <li>a feature colour changed (in the Amend Features dialog)</li>
+ * </ul>
+ *
+ * @param foundData
+ */
+ protected void updateOriginalData(Object[][] foundData)
+ {
+ // todo LinkedHashMap instead of Object[][] would be nice
+
+ Object[][] currentData = ((FeatureTableModel) table.getModel())
+ .getData();
+ for (Object[] row : foundData)
+ {
+ String type = (String) row[TYPE_COLUMN];
+ boolean found = false;
+ for (Object[] current : currentData)
+ {
+ if (type.equals(current[TYPE_COLUMN]))
+ {
+ found = true;
+ /*
+ * currently dependent on object equality here;
+ * really need an equals method on FeatureColour
+ */
+ if (!row[COLOUR_COLUMN].equals(current[COLOUR_COLUMN]))
+ {
+ /*
+ * feature colour has changed externally - update originalData
+ */
+ for (Object[] original : originalData)
+ {
+ if (type.equals(original[TYPE_COLUMN]))
+ {
+ original[COLOUR_COLUMN] = row[COLOUR_COLUMN];
+ break;
+ }
+ }
+ }
+ break;
+ }