Project

General

Profile

Revision 43d417f5

ID43d417f52847766153f286f77659eea96a1ecac9
Parent 34d19b7b
Child 368703af

Added by Patrick Plitzner almost 4 years ago

ref #7095 Show taxon node hierarchy in matrix (experimental)

View differences:

eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CharacterMatrix.java
16 16
import java.util.Arrays;
17 17
import java.util.Collection;
18 18
import java.util.Collections;
19
import java.util.Comparator;
19 20
import java.util.HashMap;
20 21
import java.util.HashSet;
21 22
import java.util.List;
......
56 57
import org.eclipse.nebula.widgets.nattable.export.command.ExportCommandHandler;
57 58
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
58 59
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
60
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeData;
61
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeRowModel;
59 62
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
60 63
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
61 64
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
......
89 92
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
90 93
import org.eclipse.nebula.widgets.nattable.summaryrow.FixedSummaryRowLayer;
91 94
import org.eclipse.nebula.widgets.nattable.summaryrow.SummaryRowLayer;
95
import org.eclipse.nebula.widgets.nattable.tree.ITreeRowModel;
96
import org.eclipse.nebula.widgets.nattable.tree.TreeLayer;
92 97
import org.eclipse.nebula.widgets.nattable.ui.menu.AbstractHeaderMenuConfiguration;
98
import org.eclipse.nebula.widgets.nattable.ui.menu.DebugMenuConfiguration;
93 99
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
94 100
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
95 101
import org.eclipse.swt.SWT;
......
104 110
import ca.odell.glazedlists.EventList;
105 111
import ca.odell.glazedlists.GlazedLists;
106 112
import ca.odell.glazedlists.SortedList;
113
import ca.odell.glazedlists.TreeList;
107 114
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
108 115
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
109 116
import eu.etaxonomy.cdm.api.service.IWorkingSetService;
117
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
110 118
import eu.etaxonomy.cdm.model.common.TermVocabulary;
111 119
import eu.etaxonomy.cdm.model.description.DescriptionBase;
112 120
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
......
117 125
import eu.etaxonomy.cdm.model.description.State;
118 126
import eu.etaxonomy.cdm.model.description.WorkingSet;
119 127
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
128
import eu.etaxonomy.cdm.model.taxon.Taxon;
129
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
120 130
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
121 131
import eu.etaxonomy.taxeditor.editor.workingSet.matrix.categorical.CategoricalDataCellEditor;
122 132
import eu.etaxonomy.taxeditor.editor.workingSet.matrix.categorical.CategoricalDataDisplayConverter;
......
183 193

  
184 194
    private Properties natTableState;
185 195

  
186
    private EventList<RowWrapper> descriptions;
196
    private EventList<Object> descriptions;
187 197

  
188 198
    private Collection<SpecimenOrObservationBase> specimenCache = null;
189 199

  
......
217 227
        Collections.sort(features);
218 228

  
219 229
        descriptions = GlazedLists.eventList(getDescriptions(workingSet));
220
        SortedList<RowWrapper> sortedList = new SortedList<>(descriptions, null);
230
        // use the SortedList constructor with 'null' for the Comparator
231
        // because the Comparator will be set by configuration
232
        SortedList<Object> sortedList = new SortedList<>(descriptions, null);
233
        // wrap the SortedList with the TreeList
234
        TreeList treeList = new TreeList(sortedList, new DescriptionTreeFormat(), TreeList.NODES_START_EXPANDED);
221 235

  
222 236
        ConfigRegistry configRegistry = new ConfigRegistry();
223 237

  
......
225 239
         * data provider
226 240
         */
227 241
        SpecimenColumnPropertyAccessor columnPropertyAccessor = new SpecimenColumnPropertyAccessor(this);
228
        IDataProvider bodyDataProvider = new ListDataProvider<RowWrapper>(sortedList, columnPropertyAccessor);
242
        IDataProvider bodyDataProvider = new ListDataProvider<Object>(treeList, columnPropertyAccessor);
229 243

  
230 244
        /**
231 245
         * BODY layer
......
278 292
            initLabels(bodyColumnLabelAccumulator, i, feature);
279 293
        }
280 294

  
281
        GlazedListsEventLayer<RowWrapper> eventLayer = new GlazedListsEventLayer<>(bodyDataLayer, sortedList);
295
        // layer for event handling of GlazedLists and PropertyChanges
296
        GlazedListsEventLayer eventLayer = new GlazedListsEventLayer<>(bodyDataLayer, treeList);
297
        GlazedListTreeData treeData = new GlazedListTreeData<>(treeList);
298
        ITreeRowModel treeRowModel = new GlazedListTreeRowModel<>(treeData);
282 299

  
283 300
        RowReorderLayer rowReorderLayer = new RowReorderLayer(eventLayer);
284 301
        ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(rowReorderLayer);
285 302
        ColumnHideShowLayer columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer);
286 303
        RowHideShowLayer rowHideShowLayer = new RowHideShowLayer(columnHideShowLayer);
287 304
        SelectionLayer selectionLayer = new SelectionLayer(rowHideShowLayer);
288
        ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
305
        TreeLayer treeLayer = new TreeLayer(selectionLayer, treeRowModel);
306
        ViewportLayer viewportLayer = new ViewportLayer(treeLayer);
307

  
289 308

  
290 309

  
291 310
        // create a standalone FixedSummaryRowLayer
......
889 908
        return propertyMap;
890 909
    }
891 910

  
911
    /*
912
    * Using a String directly as the tree item has the possible disadvantage of
913
    * haven non-unique items in the tree within subtrees.
914
    */
915
    private class DescriptionTreeFormat implements TreeList.Format<RowWrapper> {
916

  
917
        private Map parentMapping = new HashMap<>();
918

  
919
        /**
920
         * Populate path with a list describing the path from a root node to
921
         * this element. Upon returning, the list must have size >= 1, where the
922
         * provided element identical to the list's last element. This
923
         * implementation will use the first object found for a last name as
924
         * root node by storing it within a map. If there is already an object
925
         * stored for the lastname of the given element, it will be used as root
926
         * for the path.
927
         */
928
        @Override
929
        public void getPath(List path, RowWrapper element) {
930
            //TODO: check for multiple taxon nodes in multiple classifications
931
            Taxon taxon = (Taxon) element.getAssociatedTaxa().iterator().next();
932
            Set<TaxonNode> taxonNodes = taxon.getTaxonNodes();
933
            if(taxonNodes!=null){
934
                TaxonNode node = taxonNodes.iterator().next();
935
                TaxonNode parent = HibernateProxyHelper.deproxy(node.getParent(), TaxonNode.class);
936
                while(parent!=null){
937
                    path.add(parent);
938
                    parent = HibernateProxyHelper.deproxy(parent.getParent(), TaxonNode.class);
939
                }
940
            }
941
            path.add(element);
942
        }
943

  
944
        /**
945
         * Simply always return true.
946
         *
947
         * @return true if this element can have child elements, or
948
         *         false if it is always a leaf node.
949
         */
950
        @Override
951
        public boolean allowsChildren(RowWrapper element) {
952
            return true;
953
        }
954

  
955
        /**
956
         * Returns the comparator used to order path elements of the specified
957
         * depth. If enforcing order at this level is not intended, this method
958
         * should return null. We do a simple sorting of the last
959
         * names of the persons to show so the tree nodes are sorted in
960
         * alphabetical order.
961
         */
962
        @Override
963
        public Comparator<RowWrapper> getComparator(int depth) {
964
            return new Comparator<RowWrapper>() {
965

  
966
                @Override
967
                public int compare(RowWrapper o1, RowWrapper o2) {
968
                    return o1.getSpecimenDescription().getId()-(o2.getSpecimenDescription().getId());
969
                }
970

  
971
            };
972
        }
973
    }
974

  
975

  
892 976
}
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/SpecimenColumnPropertyAccessor.java
26 26
 * @since Nov 26, 2017
27 27
 *
28 28
 */
29
public class SpecimenColumnPropertyAccessor implements IColumnPropertyAccessor<RowWrapper>{
29
public class SpecimenColumnPropertyAccessor implements IColumnPropertyAccessor<Object>{
30 30

  
31 31
    private CharacterMatrix matrix;
32 32

  
......
39 39
     * {@inheritDoc}
40 40
     */
41 41
    @Override
42
    public Object getDataValue(RowWrapper rowObject, int columnIndex) {
43
        switch (columnIndex) {
44
        case 0:
45
            return rowObject.getAssociatedTaxa();
46
        case 1:
47
            return rowObject.getFieldUnit();
48
        case 2:
49
            return rowObject.getIdentifier();
50
        case 3:
51
            return rowObject.getCountry();
52

  
53
        default:
54
            break;
55
        }
56
        Feature feature = matrix.getIndexToFeatureMap().get(columnIndex);
57
        Set<DescriptionElementBase> elements = rowObject.getSpecimenDescription().getElements();
58
        for (DescriptionElementBase descriptionElementBase : elements) {
59
            if(descriptionElementBase.getFeature().equals(feature)){
60
                return descriptionElementBase;
42
    public Object getDataValue(Object rowObject, int columnIndex) {
43
        if(rowObject instanceof RowWrapper){
44
            RowWrapper rowWrapper = (RowWrapper)rowObject;
45
            switch (columnIndex) {
46
            case 0:
47
                return rowWrapper.getAssociatedTaxa();
48
            case 1:
49
                return rowWrapper.getFieldUnit();
50
            case 2:
51
                return rowWrapper.getIdentifier();
52
            case 3:
53
                return rowWrapper.getCountry();
54

  
55
            default:
56
                break;
57
            }
58
            Feature feature = matrix.getIndexToFeatureMap().get(columnIndex);
59
            Set<DescriptionElementBase> elements = rowWrapper.getSpecimenDescription().getElements();
60
            for (DescriptionElementBase descriptionElementBase : elements) {
61
                if(descriptionElementBase.getFeature().equals(feature)){
62
                    return descriptionElementBase;
63
                }
61 64
            }
65
        } else if (columnIndex == 0) {
66
            return rowObject;
62 67
        }
63 68
        return null;
64 69
    }
......
67 72
     * {@inheritDoc}
68 73
     */
69 74
    @Override
70
    public void setDataValue(RowWrapper rowObject, int columnIndex, Object newValue) {
71
        Feature feature = matrix.getIndexToFeatureMap().get(columnIndex);
72
        Set<DescriptionElementBase> elements = rowObject.getSpecimenDescription().getElements();
73
        for (DescriptionElementBase descriptionElementBase : elements) {
74
            if(descriptionElementBase.getFeature().equals(feature)){
75
                setDescriptionElement(descriptionElementBase, feature, newValue);
75
    public void setDataValue(Object rowObject, int columnIndex, Object newValue) {
76
        if(rowObject instanceof RowWrapper){
77
            RowWrapper rowWrapper = (RowWrapper)rowObject;
78
            Feature feature = matrix.getIndexToFeatureMap().get(columnIndex);
79
            Set<DescriptionElementBase> elements = rowWrapper.getSpecimenDescription().getElements();
80
            for (DescriptionElementBase descriptionElementBase : elements) {
81
                if(descriptionElementBase.getFeature().equals(feature)){
82
                    setDescriptionElement(descriptionElementBase, feature, newValue);
83
                }
76 84
            }
77 85
        }
78 86
    }

Also available in: Unified diff

Add picture from clipboard (Maximum size: 40 MB)