This is an automated email from the git hooks/post-receive script. New commit to branch feature/reecriture_editeur_de_zones in repository tutti. See https://gitlab.nuiton.org/codelutin/tutti.git commit e9d169dc3f6f56cd05e526449130f043ca74ee30 Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Mar 22 15:44:14 2016 +0100 Rethink protocol zone editor --- .../content/protocol/EditProtocolUIHandler.java | 221 +++++++++++---- .../content/protocol/EditProtocolUIModel.java | 204 +++++++++----- .../protocol/zones/AvailableStratasTreeModel.java | 114 -------- .../ui/swing/content/protocol/zones/RootNode.java | 41 --- .../swing/content/protocol/zones/StrataNode.java | 44 --- .../protocol/zones/ZoneEditorTreeModelSupport.java | 91 ------- .../swing/content/protocol/zones/ZoneEditorUI.jaxx | 2 +- .../protocol/zones/ZoneEditorUIHandler.java | 52 +--- .../content/protocol/zones/ZonesTreeModel.java | 295 --------------------- .../protocol/zones/actions/AddStratasAction.java | 83 ++---- .../protocol/zones/actions/CreateZoneAction.java | 5 +- .../protocol/zones/actions/DeleteZoneAction.java | 22 +- .../zones/actions/RemoveStratasAction.java | 51 +--- .../protocol/zones/actions/RenameZoneAction.java | 23 +- .../AvailableStratasTreeModel.java} | 24 +- .../{ => tree}/ZoneEditorTreeCellRenderer.java | 18 +- .../zones/tree/ZoneEditorTreeModelSupport.java | 199 ++++++++++++++ .../protocol/zones/tree/ZonesTreeModel.java | 84 ++++++ .../protocol/zones/tree/node/StrataNode.java | 69 +++++ .../zones/{ => tree/node}/SubStrataNode.java | 27 +- .../{ => tree/node}/ZoneEditorNodeSupport.java | 37 ++- .../content/protocol/zones/tree/node/ZoneNode.java | 73 +++++ .../EditProtocolUIModel-error-validation.xml | 2 +- .../resources/i18n/tutti-ui-swing_fr_FR.properties | 2 +- 24 files changed, 874 insertions(+), 909 deletions(-) diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIHandler.java index 793eb0b..5e825ac 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIHandler.java @@ -25,6 +25,7 @@ package fr.ifremer.tutti.ui.swing.content.protocol; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; @@ -40,9 +41,7 @@ import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicType; import fr.ifremer.tutti.persistence.entities.protocol.OperationFieldMappingRow; import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; import fr.ifremer.tutti.persistence.entities.protocol.Strata; -import fr.ifremer.tutti.persistence.entities.protocol.Stratas; import fr.ifremer.tutti.persistence.entities.protocol.SubStrata; -import fr.ifremer.tutti.persistence.entities.protocol.SubStratas; import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocols; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; @@ -51,7 +50,6 @@ import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.persistence.entities.referential.Speciess; import fr.ifremer.tutti.persistence.entities.referential.TuttiLocation; import fr.ifremer.tutti.service.DecoratorService; -import fr.ifremer.tutti.service.PersistenceService; import fr.ifremer.tutti.service.TuttiDecorator; import fr.ifremer.tutti.ui.swing.content.home.actions.CloneProtocolAction; import fr.ifremer.tutti.ui.swing.content.home.actions.EditProtocolAction; @@ -62,9 +60,13 @@ import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.Calcif import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorUI; import fr.ifremer.tutti.ui.swing.content.protocol.rtp.RtpCellEditor; import fr.ifremer.tutti.ui.swing.content.protocol.rtp.RtpCellRenderer; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.AvailableStratasTreeModel; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZonesTreeModel; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; import fr.ifremer.tutti.ui.swing.util.AbstractTuttiUIHandler; import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil; import jaxx.runtime.SwingUtil; +import jaxx.runtime.swing.JAXXWidgetUtil; import jaxx.runtime.swing.editor.bean.BeanDoubleList; import jaxx.runtime.swing.editor.bean.BeanDoubleListModel; import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox; @@ -90,9 +92,12 @@ import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.JTabbedPane; import javax.swing.JTable; +import javax.swing.JTree; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionListener; import javax.swing.event.TableModelEvent; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; @@ -122,8 +127,7 @@ import static org.nuiton.i18n.I18n.t; public class EditProtocolUIHandler extends AbstractTuttiUIHandler<EditProtocolUIModel, EditProtocolUI> implements CloseableUI { /** Logger. */ - private static final Log log = - LogFactory.getLog(EditProtocolUIHandler.class); + private static final Log log = LogFactory.getLog(EditProtocolUIHandler.class); public static String getTitle(boolean exist) { @@ -187,6 +191,8 @@ public class EditProtocolUIHandler extends AbstractTuttiUIHandler<EditProtocolUI return ui.getValidator(); } + private Multimap<TuttiLocation, TuttiLocation> programStratasAndSubstratas; + @Override public void beforeInit(EditProtocolUI ui) { super.beforeInit(ui); @@ -224,6 +230,41 @@ public class EditProtocolUIHandler extends AbstractTuttiUIHandler<EditProtocolUI listModelIsModify(model); + TuttiLocation programZone = getDataContext().getProgram().getZone(); + + programStratasAndSubstratas = HashMultimap.create(getPersistenceService().getAllFishingOperationStratasAndSubstratas(programZone.getId())); + + ImmutableMap.Builder<String, String> locationLabelCacheBuilder = ImmutableMap.builder(); + + programStratasAndSubstratas.keySet().forEach(strata -> { + + locationLabelCacheBuilder.put(strata.getId(), strata.getLabel()); + programStratasAndSubstratas.get(strata).forEach(subStrata -> locationLabelCacheBuilder.put(subStrata.getId(), subStrata.getLabel())); + + }); + + ImmutableMap<String, String> locationLabelCache = locationLabelCacheBuilder.build(); + model.setLocationLabelCache(locationLabelCache); + + // Pour lancer la validation et le recalcul des caches de zones après l + model.addPropertyChangeListener(EditProtocolUIModel.PROPERTY_MODIFYING_ZONES, evt -> { + + boolean newValue = (boolean) evt.getNewValue(); + if (!newValue) { + + if (log.isInfoEnabled()) { + log.info("Ask to release zone trees caches and revalidate protocol."); + } + + EditProtocolUIModel source = (EditProtocolUIModel) evt.getSource(); + boolean stratasAvailable = source.getAvailableStratasTreeModel().isAvailableStratas(); + source.setAvailableStratas(stratasAvailable); + + // and revalidate model, + getValidator().doValidate(); + } + }); + this.ui.setContextValue(model); } @@ -302,16 +343,11 @@ public class EditProtocolUIHandler extends AbstractTuttiUIHandler<EditProtocolUI registerValidators(validator); - Collection<Species> referents = - model.getAllReferentSpeciesByTaxonId().values(); + Collection<Species> referents = model.getAllReferentSpeciesByTaxonId().values(); - initBeanFilterableComboBox(this.ui.getSpeciesComboBox(), - Lists.newArrayList(referents), null); - initBeanFilterableComboBox(this.ui.getBenthosComboBox(), - Lists.newArrayList(referents), null); - initBeanFilterableComboBox(ui.getCaracteristicMappingComboBox(), - new ArrayList<>(model.getCaracteristics()), - null); + initBeanFilterableComboBox(this.ui.getSpeciesComboBox(), Lists.newArrayList(referents), null); + initBeanFilterableComboBox(this.ui.getBenthosComboBox(), Lists.newArrayList(referents), null); + initBeanFilterableComboBox(ui.getCaracteristicMappingComboBox(), new ArrayList<>(model.getCaracteristics()), null); List<EditProtocolCaracteristicsRowModel> caracteristicMappingRows; List<EditProtocolOperationFieldsRowModel> operationFieldMappingRows; @@ -604,8 +640,10 @@ public class EditProtocolUIHandler extends AbstractTuttiUIHandler<EditProtocolUI populateImportColumnTableEditors(); - // init available zones - initAvailableZonesModel(); + initZonesTree(); + + initAvailableStratasTree(); + // if new protocol can already cancel his creation model.setModify(model.isCreate() || model.isCleaned()); @@ -721,58 +759,109 @@ public class EditProtocolUIHandler extends AbstractTuttiUIHandler<EditProtocolUI EditProtocolSpeciesTableModel.INDIVIDUAL_OBSERVATION_ENABLED); } - protected void initAvailableZonesModel() { + protected void initZonesTree() { + + EditProtocolUIModel model = getModel(); - PersistenceService persistenceService = getPersistenceService(); + ZonesTreeModel zonesTreeModel = model.getZonesTreeModel(); - TuttiLocation programZone = getDataContext().getProgram().getZone(); + zonesTreeModel.setCreatingModel(true); + + try { + + model.getIncomingZones().forEach(zonesTreeModel::addZone); + + } finally { + zonesTreeModel.setCreatingModel(false); + } + + // expand nodes when children are added + zonesTreeModel.addTreeModelListener(new TreeModelListener() { + + @Override + public void treeNodesChanged(TreeModelEvent e) { + model.setModify(true); + } + + @Override + public void treeNodesInserted(TreeModelEvent e) { + getUI().getZoneEditor().getZonesTree().expandPath(e.getTreePath()); + } + + @Override + public void treeNodesRemoved(TreeModelEvent e) { + } + + @Override + public void treeStructureChanged(TreeModelEvent e) { + } + }); - Multimap<TuttiLocation, TuttiLocation> programStratasAndSubstratas = - HashMultimap.create(persistenceService.getAllFishingOperationStratasAndSubstratas(programZone.getId())); + initJTree(ui.getZoneEditor().getZonesTree()); - Set<TuttiLocation> usedStrataLocations = new LinkedHashSet<>(); - Set<TuttiLocation> usedSubStrataLocations = new LinkedHashSet<>(); - getModel().getZone().forEach(zone -> { + } + + protected void initAvailableStratasTree() { + + EditProtocolUIModel model = getModel(); + + Set<String> usedStrataLocations = new LinkedHashSet<>(); + Set<String> usedSubStrataLocations = new LinkedHashSet<>(); + + // Récupération des identifiants utilisés dans les zones entrantes + model.getIncomingZones().forEach(zone -> { + Collection<Strata> zoneStratas = zone.getStrata(); - Set<TuttiLocation> strataLocations = zoneStratas.stream() - .map(Strata::getLocation) - .collect(Collectors.toSet()); + Set<String> strataLocations = zoneStratas.stream() + .map(Strata::getId) + .collect(Collectors.toSet()); usedStrataLocations.addAll(strataLocations); - Set<TuttiLocation> subStrataLocations = zoneStratas.stream() - .map(Strata::getSubstrata) - .flatMap(Collection::stream) - .map(SubStrata::getLocation) - .collect(Collectors.toSet()); + Set<String> subStrataLocations = zoneStratas.stream() + .map(Strata::getSubstrata) + .flatMap(Collection::stream) + .map(SubStrata::getId) + .collect(Collectors.toSet()); usedSubStrataLocations.addAll(subStrataLocations); }); - // on transforme les données du service en modele d'ui - Collection<Strata> availableStratas = new HashSet<>(); - programStratasAndSubstratas.keySet().stream().forEach(strataLocation -> { + AvailableStratasTreeModel availableStratasTreeModel = model.getAvailableStratasTreeModel(); - Collection<TuttiLocation> subStrataLocations = new HashSet<>(programStratasAndSubstratas.get(strataLocation)); - subStrataLocations.remove(null); - List<SubStrata> subStratas = subStrataLocations.stream() - .filter(tuttiLocation -> !usedSubStrataLocations.contains(tuttiLocation)) - .map(SubStratas::newSubStrata) - .collect(Collectors.toList()); + availableStratasTreeModel.setCreatingModel(true); - if (!(subStratas.isEmpty() && usedStrataLocations.contains(strataLocation))) { + try { - // the strata is already consumed - Strata strata = Stratas.newStrata(); - strata.setLocation(strataLocation); - strata.setSubstrata(subStratas); - availableStratas.add(strata); - } + programStratasAndSubstratas.keySet().stream().forEach(strataLocation -> { - }); + String strataId = strataLocation.getId(); + + Collection<TuttiLocation> subStrataLocations = new HashSet<>(programStratasAndSubstratas.get(strataLocation)); + subStrataLocations.remove(null); + List<String> subStratas = subStrataLocations.stream() + .map(TuttiLocation::getId) + .filter(id -> !usedSubStrataLocations.contains(id)) + .collect(Collectors.toList()); + + if (!(subStratas.isEmpty() && usedStrataLocations.contains(strataLocation.getId()))) { + + StrataNode strataNode = availableStratasTreeModel.getOrCreateStrataNode(strataId); + subStratas.forEach(subStrataId -> availableStratasTreeModel.addSubsStrata(strataNode, subStrataId)); + + } + + }); + + } finally { + + availableStratasTreeModel.setCreatingModel(false); + + } + + initJTree(ui.getZoneEditor().getAvailableStratasTree()); - getModel().setAvailableStratas(availableStratas); } @Override @@ -1491,4 +1580,36 @@ public class EditProtocolUIHandler extends AbstractTuttiUIHandler<EditProtocolUI } } + protected void initJTree(JTree tree) { + tree.getModel().addTreeModelListener(new ExpandOnInsertTreeModelListener(tree)); + JAXXWidgetUtil.expandTree(tree); + } + + private static class ExpandOnInsertTreeModelListener implements TreeModelListener { + + private final JTree tree; + + private ExpandOnInsertTreeModelListener(JTree tree) { + this.tree = tree; + } + + @Override + public void treeNodesChanged(TreeModelEvent e) { + } + + @Override + public void treeNodesInserted(TreeModelEvent e) { + tree.expandPath(e.getTreePath()); + } + + @Override + public void treeNodesRemoved(TreeModelEvent e) { + } + + @Override + public void treeStructureChanged(TreeModelEvent e) { + } + + } + } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java index 86a7974..55e70e4 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java @@ -23,6 +23,7 @@ package fr.ifremer.tutti.ui.swing.content.protocol; */ import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; @@ -31,16 +32,17 @@ import fr.ifremer.tutti.persistence.entities.TuttiEntities; import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicMappingRow; import fr.ifremer.tutti.persistence.entities.protocol.OperationFieldMappingRow; import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; -import fr.ifremer.tutti.persistence.entities.protocol.Strata; import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocols; import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorRowModel; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.AvailableStratasTreeModel; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.StrataNode; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZonesTreeModel; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.AvailableStratasTreeModel; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZonesTreeModel; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.SubStrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneNode; import fr.ifremer.tutti.ui.swing.util.AbstractTuttiBeanUIModel; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.mutable.MutableInt; @@ -49,11 +51,12 @@ import org.nuiton.util.beans.BinderFactory; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; /** @@ -88,10 +91,10 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, public static final String PROPERTY_CLEANED = "cleaned"; - public static final String PROPERTY_AVAILABLE_STRATAS = "availableStratas"; - public static final String PROPERTY_CPS_ROWS = "cpsRows"; + public static final String PROPERTY_MODIFYING_ZONES = "modifyingZones"; + /** * Delegate edit object. * @@ -182,6 +185,8 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, protected static Binder<TuttiProtocol, EditProtocolUIModel> fromBeanBinder = BinderFactory.newBinder(TuttiProtocol.class, EditProtocolUIModel.class); + private boolean modifyingZones; + public EditProtocolUIModel() { super(fromBeanBinder, toBeanBinder); } @@ -191,28 +196,31 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, return TuttiProtocols.newTuttiProtocol(); } -// @Override -// public void fromEntity(TuttiProtocol entity) { -// fromBeanBinder.copyExcluding(entity, this, PROPERTY_ZONE); -// -// entity.getZone().forEach(this::addZone); -// -// List<Zone> zoneModels = entity.getZone() -// .stream() -// .map(zone -> { -// ZoneUIModel zoneUIModel = new ZoneUIModel(); -// zoneUIModel.fromEntity(zone); -// return zoneUIModel; -// }) -// .collect(Collectors.toList()); -// -// setZone(zoneModels); -// } + protected List<Zone> incomingZones = new LinkedList<>(); + + @Override + public void fromEntity(TuttiProtocol entity) { + fromBeanBinder.copyExcluding(entity, this, PROPERTY_ZONE); + + // on conserve les zones entrantes (elles seront ensuites transformées en modèle d'arbre) + incomingZones.clear(); + if (!entity.isZoneEmpty()) { + incomingZones.addAll(entity.getZone()); + } + } + + public List<Zone> getIncomingZones() { + return incomingZones; + } @Override public TuttiProtocol toEntity() { - TuttiProtocol result = super.toEntity(); -// toBeanBinder.copyExcluding(this, result, PROPERTY_ZONE); + TuttiProtocol result = TuttiProtocols.newTuttiProtocol(); + toBeanBinder.copyExcluding(this, result, PROPERTY_ZONE); + + // tree to model + Set<Zone> zones = zonesTreeModel.getZones(); + result.setZone(zones); Collection<EditProtocolCaracteristicsRowModel> protocolCaracteristicMappingRows = getCaracteristicMappingRows(); List<CaracteristicMappingRow> caracteristicMappingRows = new ArrayList<>(); @@ -979,76 +987,74 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, firePropertyChanged(TuttiProtocol.PROPERTY_OPERATION_FIELD_MAPPING, null, getOperationFieldMapping()); } - public Collection<Strata> getAvailableStratas() { - return availableStratasTreeModel.getStratas(); + public boolean isAvailableStratas() { + return getAvailableStratasTreeModel().isAvailableStratas(); } - public void setAvailableStratas(Collection<Strata> availableStratas) { - availableStratasTreeModel.setCreatingModel(true); - try { - - availableStratas.forEach(availableStratasTreeModel::addStrata); - } finally { - availableStratasTreeModel.setCreatingModel(false); - } - firePropertyChange(PROPERTY_AVAILABLE_STRATAS, Collections.emptyList(), getAvailableStratas()); + public void setAvailableStratas(boolean availableStratas) { } @Override - public List<Zone> getZone() { - return zonesTreeModel.getZones(); + public Collection<Zone> getZone() { + // Not used + return null; } @Override public void setZone(Collection<Zone> zones) { - zonesTreeModel.setCreatingModel(true); - try { - zones.forEach(zonesTreeModel::addZone); - } finally { - zonesTreeModel.setCreatingModel(false); - } + // Not used } @Override public Zone getZone(int index) { - return getZone().get(index); + // Not used + return null; } @Override public boolean isZoneEmpty() { - return getZone().isEmpty(); + + // Not used + return true; } @Override public int sizeZone() { - return getZone().size(); + // Not used + return 0; } @Override public void addZone(Zone zone) { + // Not used } @Override public void addAllZone(Collection<Zone> zones) { + // Not used } @Override public boolean removeZone(Zone zone) { + // Not used return false; } @Override public boolean removeAllZone(Collection<Zone> zones) { + // Not used return false; } @Override public boolean containsZone(Zone zone) { - return getZone().contains(zone); + // Not used + return false; } @Override public boolean containsAllZone(Collection<Zone> zones) { + // Not used return false; } @@ -1154,35 +1160,99 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, } - public void moveStrataNodeToAvailableStratasTreeModel(StrataNode strataNode) { + public void selectStrataNodes(ZoneNode selectedZoneNode, StrataNode sourceStrataNode) { - // Suppression de l'arbre des zones - zonesTreeModel.removeNodeFromParent(strataNode); + // suppression de l'arbre des disponibles + availableStratasTreeModel.removeNodeFromParent(sourceStrataNode); - Strata strata = strataNode.getUserObject(); + String sourceStrataId = sourceStrataNode.getId(); - Optional<StrataNode> optionalStrataNode = availableStratasTreeModel.getStrataNode(strata); + // récupération ou création du nœud de la strate dans la zone choisie + StrataNode targetStrataNode = zonesTreeModel.getOrCreateStrataNode(selectedZoneNode, sourceStrataId); - if (optionalStrataNode.isPresent()) { + // déplacement des nœuds de toutes les sous-strates sur la strate cible + zonesTreeModel.moveSubStratas(sourceStrataNode, targetStrataNode); - // la strate existe déjà dans l'univers des disponibles, on va juste pousser toutes les sous-strates - StrataNode newStrataNode = optionalStrataNode.get(); - Strata newStrata = newStrataNode.getUserObject(); - strata.getSubstrata().forEach(subStrata -> { + setModify(true); - // ajout dans le modèle - newStrata.addSubstrata(subStrata); + } - // ajout du nœud dans l'arbre des disponibles - availableStratasTreeModel.addSubsStrata(newStrataNode, subStrata); + public void selectedSubStraNodes(ZoneNode selectedZoneNode, SubStrataNode sourceSubStrataNode) { - }); + StrataNode sourceStrataNode = sourceSubStrataNode.getParent(); - } else { + // suppression de l'arbre des disponibles + availableStratasTreeModel.removeNodeFromParent(sourceSubStrataNode); + + if (sourceStrataNode.isLeaf()) { - // on ajouter à l'univers des disponibles toute la strate - availableStratasTreeModel.addStrata(strata); + // la strate d'origine est vide, on peut la supprimer + availableStratasTreeModel.removeNodeFromParent(sourceStrataNode); } + + // récupération ou création de la strate dans la zone choisie + StrataNode targetStrataNode = zonesTreeModel.getOrCreateStrataNode(selectedZoneNode, sourceStrataNode.getId()); + + // ajout de la sous-strate sur la strate cible + zonesTreeModel.addNode(targetStrataNode, sourceSubStrataNode); + + setModify(true); + + } + + + public void unselectStrataNode(StrataNode sourceStrataNode) { + + // Suppression de la strate de la zone + zonesTreeModel.removeNodeFromParent(sourceStrataNode); + + // récupération ou création du nœud de la strate dans la zone choisie + StrataNode targetStrataNode = availableStratasTreeModel.getOrCreateStrataNode(sourceStrataNode.getId()); + + // déplacement des nœuds de toutes les sous-strates sur la strate cible + availableStratasTreeModel.moveSubStratas(sourceStrataNode, targetStrataNode); + + setModify(true); + + } + + public void unselectSubStrataNode(SubStrataNode sourceSubStrataNode) { + + StrataNode sourceStrataNode = sourceSubStrataNode.getParent(); + + // Suppression de la sous-strate + zonesTreeModel.removeNodeFromParent(sourceSubStrataNode); + + if (sourceStrataNode.isLeaf()) { + + // plus de sous-strate, on peut supprimer la strate de la zone sélectionnée + zonesTreeModel.removeNodeFromParent(sourceStrataNode); + + } + + // récupération ou création du nœud de la strate dans la zone choisie + StrataNode targetStrataNode = availableStratasTreeModel.getOrCreateStrataNode(sourceStrataNode.getId()); + + // ajout de la sous-strate + availableStratasTreeModel.addNode(targetStrataNode, sourceSubStrataNode); + + setModify(true); + + } + + public boolean isModifyingZones() { + return modifyingZones; + } + + public void setModifyingZones(boolean modifyingZones) { + Object oldValue = isModifyingZones(); + this.modifyingZones = modifyingZones; + firePropertyChange(PROPERTY_MODIFYING_ZONES, oldValue, modifyingZones); + } + + public void setLocationLabelCache(ImmutableMap<String, String> locationLabelCache) { + this.zonesTreeModel.setLocationLabelCache(locationLabelCache); + this.availableStratasTreeModel.setLocationLabelCache(locationLabelCache); } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/AvailableStratasTreeModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/AvailableStratasTreeModel.java deleted file mode 100644 index 134e787..0000000 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/AvailableStratasTreeModel.java +++ /dev/null @@ -1,114 +0,0 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; - -/* - * #%L - * Tutti :: UI - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2012 - 2016 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import fr.ifremer.tutti.persistence.entities.protocol.Strata; -import fr.ifremer.tutti.persistence.entities.protocol.SubStrata; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Enumeration; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; - -import static org.nuiton.i18n.I18n.t; - -/** - * @author Kevin Morin (Code Lutin) - * @since 4.5 - */ -public class AvailableStratasTreeModel extends ZoneEditorTreeModelSupport { - - /** Logger. */ - private static final Log log = LogFactory.getLog(AvailableStratasTreeModel.class); - - /** - * Un cache des strates du modèle. - */ - private List<Strata> stratasCache; - - public AvailableStratasTreeModel() { - super(t("tutti.zoneEditor.availableStratas.root.label")); - } - - public StrataNode addStrata(Strata strata) { - - if (log.isInfoEnabled()) { - log.info("Add strata: " + strata); - } - StrataNode strataNode = new StrataNode(strata); - addNode(getRoot(), strataNode); - - strata.getSubstrata().forEach(subStrata -> addSubsStrata(strataNode, subStrata)); - - stratasCache = null; - return strataNode; - - } - - public boolean removeStrata(Strata strata) { - Enumeration children = getRoot().children(); - while (children.hasMoreElements()) { - StrataNode strataNode = (StrataNode) children.nextElement(); - if (strata.equals(strataNode.getUserObject())) { - if (log.isInfoEnabled()) { - log.info("Remove strata: " + strata); - } - strataNode.removeFromParent(); - stratasCache = null; - return true; - } - } - return false; - } - - public SubStrataNode addSubsStrata(StrataNode strataNode, SubStrata subStrata) { - if (log.isInfoEnabled()) { - log.info("Add subStrata: " + subStrata + " to strata node: " + strataNode); - } - SubStrataNode subStrataNode = new SubStrataNode(subStrata); - addNode(strataNode, subStrataNode); - return subStrataNode; - } - - public List<Strata> getStratas() { - if (stratasCache == null) { - stratasCache = new LinkedList<>(); - Enumeration children = getRoot().children(); - while (children.hasMoreElements()) { - StrataNode strataNode = (StrataNode) children.nextElement(); - stratasCache.add(strataNode.getUserObject()); - } - } - return stratasCache; - } - - public Optional<StrataNode> getStrataNode(Strata strata) { - int index = getStratas().indexOf(strata); - return Optional.ofNullable(index == -1 ? null : (StrataNode) getRoot().getChildAt(index)); - } - -} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/RootNode.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/RootNode.java deleted file mode 100644 index 7850593..0000000 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/RootNode.java +++ /dev/null @@ -1,41 +0,0 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; - -/* - * #%L - * Tutti :: UI - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2012 - 2016 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -/** - * @author Kevin Morin (Code Lutin) - * @since 4.5 - */ -public class RootNode extends ZoneEditorNodeSupport { - - public RootNode(String userObject) { - super(userObject, true); - } - - @Override - public String getUserObject() { - return (String) super.getUserObject(); - } -} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/StrataNode.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/StrataNode.java deleted file mode 100644 index 66d5202..0000000 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/StrataNode.java +++ /dev/null @@ -1,44 +0,0 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; - -/* - * #%L - * Tutti :: UI - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2012 - 2016 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import fr.ifremer.tutti.persistence.entities.protocol.Strata; - -/** - * @author Kevin Morin (Code Lutin) - * @since 4.5 - */ -public class StrataNode extends ZoneEditorNodeSupport { - - public StrataNode(Strata strata) { - super(strata, true); - } - - @Override - public Strata getUserObject() { - return (Strata) super.getUserObject(); - } - -} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorTreeModelSupport.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorTreeModelSupport.java deleted file mode 100644 index 9015a9d..0000000 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorTreeModelSupport.java +++ /dev/null @@ -1,91 +0,0 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; - -/* - * #%L - * Tutti :: UI - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2012 - 2016 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - - -import javax.swing.tree.DefaultTreeModel; - -/** - * @author Kevin Morin (Code Lutin) - * @since 4.5 - */ -public abstract class ZoneEditorTreeModelSupport extends DefaultTreeModel { - - /** - * Un drapeau pour bloquer les listeners lors de la création du modèle. - */ - private boolean creatingModel; - - public ZoneEditorTreeModelSupport(String rootLabel) { - super(new RootNode(rootLabel)); - } - - public void setCreatingModel(boolean creatingModel) { - this.creatingModel = creatingModel; - } - - public void addNode(ZoneEditorNodeSupport parent, ZoneEditorNodeSupport newChild) { - int index = parent.getFutureNodePosition(newChild); - insertNodeInto(newChild, parent, index); - } - - @Override - public RootNode getRoot() { - return (RootNode) super.getRoot(); - } - - @Override - protected void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) { - if (creatingModel) { - return; - } - super.fireTreeNodesChanged(source, path, childIndices, children); - } - - @Override - protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) { - if (creatingModel) { - return; - } - super.fireTreeNodesInserted(source, path, childIndices, children); - } - - @Override - protected void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) { - if (creatingModel) { - return; - } - super.fireTreeNodesRemoved(source, path, childIndices, children); - } - - @Override - protected void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) { - if (creatingModel) { - return; - } - super.fireTreeStructureChanged(source, path, childIndices, children); - } - -} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorUI.jaxx b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorUI.jaxx index 4597420..5f61c03 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorUI.jaxx +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorUI.jaxx @@ -27,7 +27,7 @@ implements='fr.ifremer.tutti.ui.swing.util.TuttiUI<EditProtocolUIModel, ZoneEditorUIHandler>'> <import> - fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneEditorTreeCellRenderer + fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneEditorTreeCellRenderer fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIModel fr.ifremer.tutti.ui.swing.util.TuttiUI fr.ifremer.tutti.ui.swing.util.TuttiUIUtil diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorUIHandler.java index 0ce2253..c2e363c 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorUIHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorUIHandler.java @@ -25,9 +25,11 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones; */ import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIModel; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.SubStrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneNode; import fr.ifremer.tutti.ui.swing.util.AbstractTuttiUIHandler; import jaxx.runtime.SwingUtil; -import jaxx.runtime.swing.JAXXWidgetUtil; import jaxx.runtime.validator.swing.SwingValidator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,8 +38,6 @@ import javax.swing.JComponent; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.SwingUtilities; -import javax.swing.event.TreeModelEvent; -import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; import java.awt.Point; @@ -105,52 +105,6 @@ public class ZoneEditorUIHandler extends AbstractTuttiUIHandler<EditProtocolUIMo zonesTree.addTreeSelectionListener(enableAddStrataListener); availableStratasTree.addTreeSelectionListener(enableAddStrataListener); - // expand nodes when children are added - getModel().getZonesTreeModel().addTreeModelListener(new TreeModelListener() { - - @Override - public void treeNodesChanged(TreeModelEvent e) { - getModel().setModify(true); - } - - @Override - public void treeNodesInserted(TreeModelEvent e) { - zonesTree.expandPath(e.getTreePath()); - } - - @Override - public void treeNodesRemoved(TreeModelEvent e) { - } - - @Override - public void treeStructureChanged(TreeModelEvent e) { - } - }); - - getModel().getAvailableStratasTreeModel().addTreeModelListener(new TreeModelListener() { - - @Override - public void treeNodesChanged(TreeModelEvent e) { - } - - @Override - public void treeNodesInserted(TreeModelEvent e) { - availableStratasTree.expandPath(e.getTreePath()); - } - - @Override - public void treeNodesRemoved(TreeModelEvent e) { - } - - @Override - public void treeStructureChanged(TreeModelEvent e) { - } - }); - - // get data - - JAXXWidgetUtil.expandTree(availableStratasTree); - JAXXWidgetUtil.expandTree(zonesTree); } @Override diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZonesTreeModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZonesTreeModel.java deleted file mode 100644 index ca40526..0000000 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZonesTreeModel.java +++ /dev/null @@ -1,295 +0,0 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; - -/* - * #%L - * Tutti :: UI - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2012 - 2016 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import fr.ifremer.tutti.persistence.entities.protocol.Strata; -import fr.ifremer.tutti.persistence.entities.protocol.SubStrata; -import fr.ifremer.tutti.persistence.entities.protocol.Zone; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Enumeration; -import java.util.LinkedList; -import java.util.List; - -import static org.nuiton.i18n.I18n.t; - -/** - * @author Kevin Morin (Code Lutin) - * @since 4.5 - */ -public class ZonesTreeModel extends ZoneEditorTreeModelSupport { - - /** Logger. */ - private static final Log log = LogFactory.getLog(ZonesTreeModel.class); - - /** - * Un cache des zones du modèle. - */ - private List<Zone> zonesCache; - - public ZonesTreeModel() { - super(t("tutti.zoneEditor.zones.root.label")); - } - - public List<Zone> getZones() { - if (zonesCache == null) { - zonesCache = new LinkedList<>(); - Enumeration children = getRoot().children(); - while (children.hasMoreElements()) { - ZoneNode zoneNode = (ZoneNode) children.nextElement(); - zonesCache.add(zoneNode.getUserObject()); - } - } - return zonesCache; - } - - public ZoneNode addZone(Zone zone) { - - if (log.isInfoEnabled()) { - log.info("Add zone: " + zone); - } - ZoneNode zoneNode = new ZoneNode(zone); - addNode(getRoot(), zoneNode); - - zone.getStrata().forEach(strata -> { - - StrataNode strataNode = addStrata(zoneNode, strata); - strata.getSubstrata().forEach(subStrata -> addSubsStrata(strataNode, subStrata)); - - }); - - zonesCache = null; - return zoneNode; - - } - - public boolean removeZone(Zone zone) { - Enumeration children = getRoot().children(); - while (children.hasMoreElements()) { - ZoneNode zoneNode = (ZoneNode) children.nextElement(); - if (zone.equals(zoneNode.getUserObject())) { - if (log.isInfoEnabled()) { - log.info("Remove zone: " + zone); - } - zoneNode.removeFromParent(); - zonesCache = null; - return true; - } - } - return false; - } - - public StrataNode addStrata(ZoneNode zoneNode, Strata strata) { - if (log.isInfoEnabled()) { - log.info("Add strata: " + strata + " to zone node: " + zoneNode); - } - StrataNode strataNode = new StrataNode(strata); - addNode(zoneNode, strataNode); - return strataNode; - } - - public SubStrataNode addSubsStrata(StrataNode strataNode, SubStrata subStrata) { - if (log.isInfoEnabled()) { - log.info("Add subStrata: " + subStrata + " to strata node: " + strataNode); - } - SubStrataNode subStrataNode = new SubStrataNode(subStrata); - addNode(strataNode, subStrataNode); - return subStrataNode; - } - - // public void removeZones(Collection<ZoneUIModel> zonesToRemove) { -// -// ZoneEditorNode root = (ZoneEditorNode) getRoot(); -// -// Enumeration rootChildren = root.children(); -// Collection<DefaultMutableTreeNode> nodesToRemove = new HashSet<>(); -// -// while (rootChildren.hasMoreElements()) { -// -// fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode zoneNode = (fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode) rootChildren.nextElement(); -// -// if (zonesToRemove.contains(zoneNode.getUserObject())) { -// nodesToRemove.add(zoneNode); -// } -// } -// -// nodesToRemove.forEach(this::removeNodeFromParent); -// } - -// public void addZones(Collection<ZoneUIModel> zonesToAdd) { -// -// ZoneEditorNode root = (ZoneEditorNode) getRoot(); -// -// zonesToAdd.forEach(zone -> { -// -// fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode zoneNode = new fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode(zone); -// addNode(zoneNode, root); -// -// Set<StrataUIModel> stratasToAdd = zone.getStrata() -// .stream() -// .map(strata -> (StrataUIModel) strata) -// .collect(Collectors.toSet()); -// -// updateStratas(zoneNode, stratasToAdd, Collections.emptySet()); -// -// }); -// -// } -// -// public void updateStratas(ZoneUIModel zone, -// Collection<StrataUIModel> stratasToAdd, -// Collection<StrataUIModel> stratasToRemove) { -// -// fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode zoneNode = findZoneNode(zone); -// updateStratas(zoneNode, stratasToAdd, stratasToRemove); -// } -// -// public void updateStratas(fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode zoneNode, -// Collection<StrataUIModel> stratasToAdd, -// Collection<StrataUIModel> stratasToRemove) { -// -// Preconditions.checkNotNull(zoneNode); -// -// for (StrataUIModel strata : stratasToRemove) { -// -// StrataNode strataNode = findStrataNode(strata, zoneNode); -// -// if (log.isInfoEnabled()) { -// log.info("remove strata " + strata.getLabel()); -// } -// -// removeNodeFromParent(strataNode); -// } -// -// for (StrataUIModel strata : stratasToAdd) { -// -// StrataNode strataNode = new StrataNode(strata); -// -// addNode(strataNode, zoneNode); -// -// Set<SubStrataUIModel> subStratasToAdd = strata.getSubstrata() -// .stream() -// .map(subStrata -> (SubStrataUIModel) subStrata) -// .collect(Collectors.toSet()); -// -// updateSubStratas(strataNode, subStratasToAdd, Collections.emptySet()); -// } -// -// } -// -// public void updateSubStratas(StrataUIModel strata, -// Collection<SubStrataUIModel> subStratasToAdd, -// Collection<SubStrataUIModel> subStratasToRemove) { -// -// StrataNode strataNode = findStrataNode(strata, strata.getZone()); -// updateSubStratas(strataNode, subStratasToAdd, subStratasToRemove); -// -// } -// -// public void updateSubStratas(StrataNode strataNode, -// Collection<SubStrataUIModel> subStratasToAdd, -// Collection<SubStrataUIModel> subStratasToRemove) { -// -// Preconditions.checkNotNull(strataNode); -// -// for (SubStrataUIModel subStrata : subStratasToRemove) { -// -// SubStrataNode subStrataNode = findSubStrataNode(subStrata, strataNode); -// -// removeNodeFromParent(subStrataNode); -// } -// -// for (SubStrataUIModel subStrata : subStratasToAdd) { -// -// SubStrataNode subStrataNode = new SubStrataNode(subStrata); -// -// addNode(subStrataNode, strataNode); -// -// } -// -// } -// -// public fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode findZoneNode(ZoneUIModel zone) { -// -// DefaultMutableTreeNode root = (DefaultMutableTreeNode) getRoot(); -// -// Enumeration rootChildren = root.children(); -// -// fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode zoneNode = null; -// -// while (zoneNode == null && rootChildren.hasMoreElements()) { -// fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode nextNode = (fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode) rootChildren.nextElement(); -// if (zone.equals(nextNode.getUserObject())) { -// zoneNode = nextNode; -// } -// } -// -// return zoneNode; -// } -// -// public StrataNode findStrataNode(StrataUIModel strata, ZoneUIModel zone) { -// -// fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.ZoneNode zoneNode = findZoneNode(zone); -// -// return findStrataNode(strata, zoneNode); -// } -// -// public StrataNode findStrataNode(StrataUIModel strata, ZoneNode zoneNode) { -// -// Enumeration zoneChildren = zoneNode.children(); -// -// StrataNode strataNode = null; -// -// while (strataNode == null && zoneChildren.hasMoreElements()) { -// StrataNode nextNode = (StrataNode) zoneChildren.nextElement(); -// if (strata.equals(nextNode.getUserObject())) { -// strataNode = nextNode; -// } -// } -// -// return strataNode; -// } -// -// public SubStrataNode findSubStrataNode(SubStrataUIModel subStrata, StrataNode strataNode) { -// -// Enumeration strataChildren = strataNode.children(); -// -// SubStrataNode subStrataNode = null; -// -// while (subStrataNode == null && strataChildren.hasMoreElements()) { -// SubStrataNode nextNode = (SubStrataNode) strataChildren.nextElement(); -// if (subStrata.equals(nextNode.getUserObject())) { -// subStrataNode = nextNode; -// } -// } -// -// return subStrataNode; -// } - -// public void zoneLabelChanged(Zone zone) { -// nodeChanged(findZoneNode(zone)); -// } -} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/AddStratasAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/AddStratasAction.java index 9431e2c..cc751a0 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/AddStratasAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/AddStratasAction.java @@ -24,24 +24,17 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones.actions; * #L% */ -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; -import fr.ifremer.tutti.persistence.entities.protocol.Strata; -import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIModel; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.AvailableStratasTreeModel; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.StrataNode; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.SubStrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.SubStrataNode; import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneEditorUI; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneNode; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZonesTreeModel; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneNode; import fr.ifremer.tutti.ui.swing.util.actions.SimpleActionSupport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.swing.JTree; import javax.swing.tree.TreePath; -import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Optional; @@ -84,71 +77,24 @@ public class AddStratasAction extends SimpleActionSupport<ZoneEditorUI> { } Set<StrataNode> strataNodesToAdd = getStrataNodesToAdd(selectedAvailableStrataPaths); - Multimap<StrataNode, SubStrataNode> subStrataNodesToAddByStrataNode = getSubStrataNodesToAdd(selectedAvailableStrataPaths, strataNodesToAdd); - Set<SubStrataNode> subStrataNodesToAdd = new LinkedHashSet<>(); - - subStrataNodesToAddByStrataNode.asMap().entrySet().forEach(entry -> { - StrataNode strataNode = entry.getKey(); - Collection<SubStrataNode> subStrataNodes = entry.getValue(); - if (strataNode.getChildCount() == subStrataNodes.size()) { - - // toute la strate est sélectionnée - strataNodesToAdd.add(strataNode); - if (log.isInfoEnabled()) { - log.info("Add full strata " + strataNode + " to add"); - } - } else { - subStrataNodesToAdd.addAll(subStrataNodes); - - } - }); + Set<SubStrataNode> subStrataNodesToAdd = getSubStrataNodesToAdd(selectedAvailableStrataPaths, strataNodesToAdd); ZoneNode selectedZoneNode = optionalSelectedZoneNode.get(); - Zone selectedZone = selectedZoneNode.getUserObject(); EditProtocolUIModel model = zoneEditorUI.getModel(); - AvailableStratasTreeModel availableStratasTreeModel = model.getAvailableStratasTreeModel(); - ZonesTreeModel zonesTreeModel = model.getZonesTreeModel(); - - strataNodesToAdd.forEach(strataNode -> { - - // suppression de l'arbre des disponibles - availableStratasTreeModel.removeNodeFromParent(strataNode); - - // ajout au modèle - selectedZone.addStrata(strataNode.getUserObject()); - - // ajout du nœud dans l'arbre - zonesTreeModel.addNode(selectedZoneNode, strataNode); - }); + model.setModifyingZones(true); - subStrataNodesToAdd.forEach(subStrataNode -> { + try { - // suppression de l'arbre des disponibles - availableStratasTreeModel.removeNodeFromParent(subStrataNode); + strataNodesToAdd.forEach(strataNode -> model.selectStrataNodes(selectedZoneNode, strataNode)); + subStrataNodesToAdd.forEach(subStrataNode -> model.selectedSubStraNodes(selectedZoneNode, subStrataNode)); - StrataNode strataNode = subStrataNode.getParent(); + } finally { - Strata strata = strataNode.getUserObject(); + model.setModifyingZones(false); - if (!selectedZone.containsStrata(strata)) { - - // ajout au modèle - selectedZone.addStrata(strata); - - // ajout du nœud dans l'arbre - strataNode = zonesTreeModel.addStrata(selectedZoneNode, strata); - - } - - // ajout au modèle - strata.addSubstrata(subStrataNode.getUserObject()); - - // ajout du nœud dans l'arbre - zonesTreeModel.addNode(strataNode, subStrataNode); - - }); + } } @@ -176,8 +122,8 @@ public class AddStratasAction extends SimpleActionSupport<ZoneEditorUI> { return result; } - protected Multimap<StrataNode, SubStrataNode> getSubStrataNodesToAdd(TreePath[] selectedStratas, Set<StrataNode> stratasNodeToAdd) { - Multimap<StrataNode, SubStrataNode> result = ArrayListMultimap.create(); + protected Set<SubStrataNode> getSubStrataNodesToAdd(TreePath[] selectedStratas, Set<StrataNode> stratasNodeToAdd) { + Set<SubStrataNode> result = new LinkedHashSet<>(); for (TreePath selectedStrata : selectedStratas) { Object node = selectedStrata.getLastPathComponent(); @@ -188,9 +134,10 @@ public class AddStratasAction extends SimpleActionSupport<ZoneEditorUI> { if (log.isInfoEnabled()) { log.info("found subStrata " + subStrataNode + " to add"); } - result.put(strataNode, subStrataNode); + result.add(subStrataNode); } } + } return result; } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/CreateZoneAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/CreateZoneAction.java index 14e55bd..d0c788d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/CreateZoneAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/CreateZoneAction.java @@ -28,7 +28,7 @@ import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.persistence.entities.protocol.Zones; import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIModel; import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneEditorUI; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneNode; import fr.ifremer.tutti.ui.swing.util.actions.SimpleActionSupport; import org.apache.commons.lang3.StringUtils; @@ -36,6 +36,8 @@ import javax.swing.JOptionPane; import javax.swing.JTree; import javax.swing.tree.TreePath; +import java.util.UUID; + import static org.nuiton.i18n.I18n.t; /** @@ -59,6 +61,7 @@ public class CreateZoneAction extends SimpleActionSupport<ZoneEditorUI> { if (StringUtils.isNotEmpty(zoneLabel)) { Zone zone = Zones.newZone(); + zone.setId(UUID.randomUUID().toString()); zone.setLabel(zoneLabel); EditProtocolUIModel model = zoneEditorUI.getModel(); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/DeleteZoneAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/DeleteZoneAction.java index 691f0aa..d4ee55e 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/DeleteZoneAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/DeleteZoneAction.java @@ -24,12 +24,13 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones.actions; * #L% */ -import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIModel; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.StrataNode; import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneEditorUI; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneNode; import fr.ifremer.tutti.ui.swing.util.actions.SimpleActionSupport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import javax.swing.JOptionPane; import javax.swing.JTree; @@ -44,6 +45,9 @@ import static org.nuiton.i18n.I18n.t; */ public class DeleteZoneAction extends SimpleActionSupport<ZoneEditorUI> { + /** Logger. */ + private static final Log log = LogFactory.getLog(DeleteZoneAction.class); + public DeleteZoneAction(ZoneEditorUI zoneEditorUI) { super(zoneEditorUI); } @@ -58,26 +62,32 @@ public class DeleteZoneAction extends SimpleActionSupport<ZoneEditorUI> { TreePath selectedPath = zonesTree.getSelectionPath(); ZoneNode zoneNode = (ZoneNode) selectedPath.getPathComponent(1); - Zone zone = zoneNode.getUserObject(); + String zoneLabel = zoneNode.getUserObject(); int confirmDeletion = JOptionPane.showConfirmDialog(zoneEditorUI, - t("tutti.zoneEditor.deleteZone.message", zone), + t("tutti.zoneEditor.deleteZone.message", zoneLabel), t("tutti.zoneEditor.deleteZone.title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (confirmDeletion == JOptionPane.YES_OPTION) { + EditProtocolUIModel model = zoneEditorUI.getModel(); Enumeration children = zoneNode.children(); while (children.hasMoreElements()) { StrataNode strateNode = (StrataNode) children.nextElement(); - model.moveStrataNodeToAvailableStratasTreeModel(strateNode); + if (log.isInfoEnabled()) { + log.info("Move back strata: " + strateNode + " to available universe."); + } + model.unselectStrataNode(strateNode); } + model.getZonesTreeModel().removeNodeFromParent(zoneNode); + } } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/RemoveStratasAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/RemoveStratasAction.java index f3b9c78..d3dbd25 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/RemoveStratasAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/RemoveStratasAction.java @@ -24,15 +24,10 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones.actions; * #L% */ -import fr.ifremer.tutti.persistence.entities.protocol.Strata; -import fr.ifremer.tutti.persistence.entities.protocol.Stratas; -import fr.ifremer.tutti.persistence.entities.protocol.SubStrata; import fr.ifremer.tutti.ui.swing.content.protocol.EditProtocolUIModel; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.AvailableStratasTreeModel; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.StrataNode; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.SubStrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.SubStrataNode; import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneEditorUI; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZonesTreeModel; import fr.ifremer.tutti.ui.swing.util.actions.SimpleActionSupport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -40,7 +35,6 @@ import org.apache.commons.logging.LogFactory; import javax.swing.JTree; import javax.swing.tree.TreePath; import java.util.HashSet; -import java.util.Optional; import java.util.Set; /** @@ -78,46 +72,19 @@ public class RemoveStratasAction extends SimpleActionSupport<ZoneEditorUI> { Set<SubStrataNode> subStratasNodeToRemove = getSubStrataNodesToRemove(selectedStratas, stratasNodeToRemove); EditProtocolUIModel model = zoneEditorUI.getModel(); - AvailableStratasTreeModel availableStratasTreeModel = model.getAvailableStratasTreeModel(); - ZonesTreeModel zonesTreeModel = model.getZonesTreeModel(); - stratasNodeToRemove.forEach(model::moveStrataNodeToAvailableStratasTreeModel); + model.setModifyingZones(true); - subStratasNodeToRemove.forEach(subStrataNode -> { + try { - // Suppression de l'arbre des zones - zonesTreeModel.removeNodeFromParent(subStrataNode); + stratasNodeToRemove.forEach(model::unselectStrataNode); + subStratasNodeToRemove.forEach(model::unselectSubStrataNode); - SubStrata subStrata = subStrataNode.getUserObject(); + } finally { - StrataNode strataNode = subStrataNode.getParent(); + model.setModifyingZones(false); - Strata strata = strataNode.getUserObject(); - - Optional<StrataNode> optionalStrataNode = availableStratasTreeModel.getStrataNode(strata); - - if (optionalStrataNode.isPresent()) { - - // la strate existe déjà dans l'univers des disponibles, on va juste pousser la sous-strate - StrataNode newStrataNode = optionalStrataNode.get(); - - // ajout dans le modèle - newStrataNode.getUserObject().addSubstrata(subStrata); - - // ajout du nœud dans l'arbre des disponibles - availableStratasTreeModel.addSubsStrata(newStrataNode, subStrata); - - } else { - - // la strate n'existe pas, on peut ajouter la strate puis la sous-strate - Strata newStrata = Stratas.newStrata(); - newStrata.setLocation(strata.getLocation()); - newStrata.addSubstrata(subStrata); - - // ajout du nœud dans l'arbre des disponibles - availableStratasTreeModel.addStrata(newStrata); - } - }); + } // select zone path zonesTree.setSelectionPath(selectedStratas[0].getParentPath()); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/RenameZoneAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/RenameZoneAction.java index 126d8da..e5a80a5 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/RenameZoneAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/actions/RenameZoneAction.java @@ -24,9 +24,8 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones.actions; * #L% */ -import fr.ifremer.tutti.persistence.entities.protocol.Zone; import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneEditorUI; -import fr.ifremer.tutti.ui.swing.content.protocol.zones.ZoneNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneNode; import fr.ifremer.tutti.ui.swing.util.actions.SimpleActionSupport; import org.apache.commons.lang3.StringUtils; @@ -55,19 +54,21 @@ public class RenameZoneAction extends SimpleActionSupport<ZoneEditorUI> { TreePath selectedPath = zonesTree.getSelectionPath(); ZoneNode zoneNode = (ZoneNode) selectedPath.getPathComponent(1); - Zone zone = zoneNode.getUserObject(); + String zoneLabel = zoneNode.getUserObject(); - String zoneLabel = (String) JOptionPane.showInputDialog(zoneEditorUI, - t("tutti.zoneEditor.renameZone.message", zone.getLabel()), - t("tutti.zoneEditor.renameZone.title", zone.getLabel()), - JOptionPane.QUESTION_MESSAGE, - null, - null, - zone.getLabel()); + String newZoneLabel = (String) JOptionPane.showInputDialog(zoneEditorUI, + t("tutti.zoneEditor.renameZone.message", zoneLabel), + t("tutti.zoneEditor.renameZone.title", zoneLabel), + JOptionPane.QUESTION_MESSAGE, + null, + null, + zoneLabel); if (StringUtils.isNotEmpty(zoneLabel)) { - zone.setLabel(zoneLabel); + zoneNode.setUserObject(newZoneLabel); zoneEditorUI.getModel().getZonesTreeModel().nodeChanged(zoneNode); + //FIXME Peut-être utiliser ça ? +// zoneEditorUI.getModel().getZonesTreeModel().nodeStructureChanged(zoneNode); } } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneNode.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/AvailableStratasTreeModel.java similarity index 57% rename from tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneNode.java rename to tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/AvailableStratasTreeModel.java index 3a2f9d0..8fc6556 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneNode.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/AvailableStratasTreeModel.java @@ -1,4 +1,4 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; +package fr.ifremer.tutti.ui.swing.content.protocol.zones.tree; /* * #%L @@ -24,25 +24,27 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones; * #L% */ -import fr.ifremer.tutti.persistence.entities.protocol.Zone; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; + +import static org.nuiton.i18n.I18n.t; /** * @author Kevin Morin (Code Lutin) + * @author Tony Chemit - chemit@codelutin.com * @since 4.5 */ -public class ZoneNode extends ZoneEditorNodeSupport { +public class AvailableStratasTreeModel extends ZoneEditorTreeModelSupport { - public ZoneNode(Zone zone) { - super(zone, true); + public AvailableStratasTreeModel() { + super(t("tutti.zoneEditor.availableStratas.root.label")); } - @Override - public Zone getUserObject() { - return (Zone) super.getUserObject(); + public StrataNode getOrCreateStrataNode(String sourceStrataId) { + return getOrCreateStrataNode(getRoot(), sourceStrataId); } - @Override - public RootNode getParent() { - return (RootNode) super.getParent(); + public boolean isAvailableStratas() { + return !getRoot().isLeaf(); } + } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorTreeCellRenderer.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZoneEditorTreeCellRenderer.java similarity index 72% rename from tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorTreeCellRenderer.java rename to tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZoneEditorTreeCellRenderer.java index 9e2a57f..157694d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorTreeCellRenderer.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZoneEditorTreeCellRenderer.java @@ -1,4 +1,4 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; +package fr.ifremer.tutti.ui.swing.content.protocol.zones.tree; /* * #%L @@ -24,8 +24,10 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones; * #L% */ +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneEditorNodeSupport; import jaxx.runtime.SwingUtil; +import javax.swing.ImageIcon; import javax.swing.JTree; import javax.swing.tree.DefaultTreeCellRenderer; import java.awt.Component; @@ -36,14 +38,22 @@ import java.awt.Component; */ public class ZoneEditorTreeCellRenderer extends DefaultTreeCellRenderer { + protected final ImageIcon location = SwingUtil.createActionIcon("location"); + + public ZoneEditorTreeCellRenderer() { + setIcon(location); + } + @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + if (value instanceof ZoneEditorNodeSupport) { + value = ((ZoneEditorNodeSupport) value).getUserObject(); + } super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); - - setIcon(SwingUtil.createActionIcon("location")); - + setIcon(location); return this; + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZoneEditorTreeModelSupport.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZoneEditorTreeModelSupport.java new file mode 100644 index 0000000..e619fbe --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZoneEditorTreeModelSupport.java @@ -0,0 +1,199 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.zones.tree; + +/* + * #%L + * Tutti :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2016 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.collect.ImmutableMap; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.SubStrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneEditorNodeSupport; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneNode; +import org.apache.commons.collections4.EnumerationUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.event.TreeModelEvent; +import javax.swing.tree.DefaultTreeModel; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +/** + * @author Kevin Morin (Code Lutin) + * @author Tony Chemit - chemit@codelutin.com + * @since 4.5 + */ +public abstract class ZoneEditorTreeModelSupport extends DefaultTreeModel { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ZoneEditorTreeModelSupport.class); + + /** + * Un drapeau pour bloquer les listeners lors de la création du modèle. + */ + private boolean creatingModel; + + /** + * Un cache de libellés de locations par leur identifiant. + */ + private ImmutableMap<String, String> locationLabelCache; + + /** + * L'ensemble des nœuds inserés pendant que le modèle est en mode création. On doit relancer alors les fire à la fin. + */ + private final Set<TreeModelEvent> nodeInserted = new LinkedHashSet<>(); + + public ZoneEditorTreeModelSupport(String rootLabel) { + super(new ZoneNode("No fucking way! I am not a zone", rootLabel)); + } + + public void setCreatingModel(boolean creatingModel) { + this.creatingModel = creatingModel; + if (creatingModel) { + nodeInserted.clear(); + } else { + try { + nodeInserted.forEach(treeModelEvent -> fireTreeNodesInserted( + treeModelEvent.getSource(), treeModelEvent.getPath(), treeModelEvent.getChildIndices(), treeModelEvent.getChildren() + )); + } finally { + nodeInserted.clear(); + } + } + } + + public void addNode(ZoneEditorNodeSupport parent, ZoneEditorNodeSupport newChild) { + int index = parent.getFutureNodePosition(newChild); + insertNodeInto(newChild, parent, index); + } + + @Override + public ZoneNode getRoot() { + return (ZoneNode) super.getRoot(); + } + + @Override + protected void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) { + if (creatingModel) { + return; + } + super.fireTreeNodesChanged(source, path, childIndices, children); + } + + @Override + protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) { + if (creatingModel) { + nodeInserted.add(new TreeModelEvent(source, path, childIndices, children)); + return; + } + super.fireTreeNodesInserted(source, path, childIndices, children); + } + + @Override + protected void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) { + if (creatingModel) { + return; + } + super.fireTreeNodesRemoved(source, path, childIndices, children); + } + + @Override + protected void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) { + if (creatingModel) { + return; + } + super.fireTreeStructureChanged(source, path, childIndices, children); + } + + protected String getLocationLabel(String locationId) { + String locationLabel = locationLabelCache.get(locationId); + Objects.requireNonNull(locationLabel, "Libellé de location non trouvé pour l'identifiant: " + locationId); + return locationLabel; + } + + public void setLocationLabelCache(ImmutableMap<String, String> locationLabelCache) { + this.locationLabelCache = locationLabelCache; + } + + public StrataNode addStrata(ZoneNode zoneNode, String strataId) { + + String strataLabel = getLocationLabel(strataId); + if (log.isInfoEnabled()) { + log.info("Add strata: " + strataLabel + " to zone node: " + zoneNode); + } + + StrataNode strataNode = new StrataNode(strataId, strataLabel); + addNode(zoneNode, strataNode); + return strataNode; + } + + public SubStrataNode addSubsStrata(StrataNode strataNode, String subStrataId) { + + String subStrataLabel = getLocationLabel(subStrataId); + if (log.isInfoEnabled()) { + log.info("Add subStrata: " + subStrataLabel + " to strata node: " + strataNode); + } + + SubStrataNode subStrataNode = new SubStrataNode(subStrataId, subStrataLabel); + addNode(strataNode, subStrataNode); + return subStrataNode; + + } + + public StrataNode getOrCreateStrataNode(ZoneNode zoneNode, String strataId) { + + StrataNode strataNode; + + Optional<StrataNode> optionalStrataNode = zoneNode.tryFindStrataNode(strataId); + + if (optionalStrataNode.isPresent()) { + + // la strate existe déjà dans la zone, on la récupère + strataNode = optionalStrataNode.get(); + + } else { + + // la strate n'existe pas, on la crée et l'ajoute à la zone + // ajout du nœud dans l'arbre + strataNode = addStrata(zoneNode, strataId); + + } + + return strataNode; + + } + + public void moveSubStratas(StrataNode sourceNode, StrataNode targetNode) { + + EnumerationUtils.toList(sourceNode.children()) + .forEach(subStrataNode -> { + removeNodeFromParent(subStrataNode); + addNode(targetNode, subStrataNode); + }); + + } + +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZonesTreeModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZonesTreeModel.java new file mode 100644 index 0000000..7778b21 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/ZonesTreeModel.java @@ -0,0 +1,84 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.zones.tree; + +/* + * #%L + * Tutti :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2016 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ifremer.tutti.persistence.entities.protocol.Zone; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.StrataNode; +import fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node.ZoneNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Enumeration; +import java.util.LinkedHashSet; +import java.util.Set; + +import static org.nuiton.i18n.I18n.t; + +/** + * @author Kevin Morin (Code Lutin) + * @author Tony Chemit - chemit@codelutin.com + * @since 4.5 + */ +public class ZonesTreeModel extends ZoneEditorTreeModelSupport { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ZonesTreeModel.class); + + public ZonesTreeModel() { + super(t("tutti.zoneEditor.zones.root.label")); + } + + public ZoneNode addZone(Zone zone) { + + if (log.isInfoEnabled()) { + log.info("Add zone: " + zone); + } + ZoneNode zoneNode = new ZoneNode(zone.getId(), zone.getLabel()); + addNode(getRoot(), zoneNode); + + zone.getStrata().forEach(strata -> { + + StrataNode strataNode = addStrata(zoneNode, strata.getId()); + strata.getSubstrata().forEach(subStrata -> addSubsStrata(strataNode, subStrata.getId())); + + }); + + return zoneNode; + + } + + public Set<Zone> getZones() { + + Set<Zone> zones = new LinkedHashSet<>(); + Enumeration zoneNodes = getRoot().children(); + while (zoneNodes.hasMoreElements()) { + Object zoneNode = zoneNodes.nextElement(); + zones.add(((ZoneNode) zoneNode).toBean()); + } + return zones; + + } + +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/StrataNode.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/StrataNode.java new file mode 100644 index 0000000..2984432 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/StrataNode.java @@ -0,0 +1,69 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node; + +/* + * #%L + * Tutti :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2016 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ifremer.tutti.persistence.entities.protocol.Strata; +import fr.ifremer.tutti.persistence.entities.protocol.Stratas; + +import java.util.Enumeration; + +/** + * Pour définir une strate contenue dans une zone. + * + * Le parent d'un tel nœud est toujours une zone. Même dans l'arbre des disponibles le nœud root sera alors une zone fictive. + * + * @author Kevin Morin (Code Lutin) + * @author Tony Chemit - chemit@codelutin.com + * @since 4.5 + */ +public class StrataNode extends ZoneEditorNodeSupport { + + public StrataNode(String id, String label) { + super(id, label, true); + } + + @Override + public ZoneNode getParent() { + return (ZoneNode) super.getParent(); + } + + @Override + public Enumeration<SubStrataNode> children() { + return super.children(); + } + + public Strata toBean() { + + Strata strata = Stratas.newStrata(); + strata.setId(getId()); + Enumeration<SubStrataNode> children = children(); + while (children.hasMoreElements()) { + SubStrataNode subStrataNode = children.nextElement(); + strata.addSubstrata(subStrataNode.toBean()); + } + return strata; + + } +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/SubStrataNode.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/SubStrataNode.java similarity index 64% rename from tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/SubStrataNode.java rename to tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/SubStrataNode.java index f113061..5f70e9c 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/SubStrataNode.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/SubStrataNode.java @@ -1,4 +1,4 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; +package fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node; /* * #%L @@ -25,24 +25,35 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones; */ import fr.ifremer.tutti.persistence.entities.protocol.SubStrata; +import fr.ifremer.tutti.persistence.entities.protocol.SubStratas; /** + * Pour définir une sous-strate contenue dans une strate. + * + * Le parent d'un tel nœud est toujours une strate. + * + * À noter que ce type de nœud est toujours une feuille. + * * @author Kevin Morin (Code Lutin) + * @author Tony Chemit - chemit@codelutin.com * @since 4.5 */ public class SubStrataNode extends ZoneEditorNodeSupport { - public SubStrataNode(SubStrata substrata) { - super(substrata, false); - } - - @Override - public SubStrata getUserObject() { - return (SubStrata) super.getUserObject(); + public SubStrataNode(String id, String label) { + super(id, label, false); } @Override public StrataNode getParent() { return (StrataNode) super.getParent(); } + + public SubStrata toBean() { + + SubStrata strata = SubStratas.newSubStrata(); + strata.setId(getId()); + return strata; + + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorNodeSupport.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/ZoneEditorNodeSupport.java similarity index 63% rename from tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorNodeSupport.java rename to tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/ZoneEditorNodeSupport.java index d9ab563..1e78f06 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/ZoneEditorNodeSupport.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/ZoneEditorNodeSupport.java @@ -1,4 +1,4 @@ -package fr.ifremer.tutti.ui.swing.content.protocol.zones; +package fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node; /* * #%L @@ -24,19 +24,35 @@ package fr.ifremer.tutti.ui.swing.content.protocol.zones; * #L% */ +import com.google.common.base.MoreObjects; + import javax.swing.tree.DefaultMutableTreeNode; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** + * Le support pour un nœud des arbres de l'éditeur de zone. + * + * Chaque nœud possède au moins un id et le {@link #getUserObject()} est son label. + * + * Les nœuds sont ordonnées par leur label. + * * @author Kevin Morin (Code Lutin) + * @author Tony Chemit - chemit@codelutin.com * @since 4.5 */ public abstract class ZoneEditorNodeSupport extends DefaultMutableTreeNode implements Comparable<ZoneEditorNodeSupport> { - public ZoneEditorNodeSupport(Object userObject, boolean allowchildren) { - super(userObject, allowchildren); + private final String id; + + public ZoneEditorNodeSupport(String id, String label, boolean allowchildren) { + super(label, allowchildren); + this.id = id; + } + + public String getId() { + return id; } public int getFutureNodePosition(ZoneEditorNodeSupport node) { @@ -55,11 +71,24 @@ public abstract class ZoneEditorNodeSupport extends DefaultMutableTreeNode imple if (o == null) { return 1; } - return toString().compareTo(o.toString()); + return getUserObject().compareTo(o.getUserObject()); } @Override public ZoneEditorNodeSupport getParent() { return (ZoneEditorNodeSupport) super.getParent(); } + + @Override + public String getUserObject() { + return (String) super.getUserObject(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", getId()) + .addValue(getUserObject()) + .toString(); + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/ZoneNode.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/ZoneNode.java new file mode 100644 index 0000000..2c933b4 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/zones/tree/node/ZoneNode.java @@ -0,0 +1,73 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.zones.tree.node; + +/* + * #%L + * Tutti :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2016 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ifremer.tutti.persistence.entities.protocol.Zone; +import fr.ifremer.tutti.persistence.entities.protocol.Zones; + +import java.util.Enumeration; +import java.util.Optional; + +/** + * Pour définir une zone ou bien un nœud racine. + * + * @author Kevin Morin (Code Lutin) + * @author Tony Chemit - chemit@codelutin.com + * @since 4.5 + */ +public class ZoneNode extends ZoneEditorNodeSupport { + + public ZoneNode(String id, String label) { + super(id, label, true); + } + + public Optional<StrataNode> tryFindStrataNode(String strataId) { + Enumeration children = children(); + while (children.hasMoreElements()) { + StrataNode strataNode = (StrataNode) children.nextElement(); + if (strataId.equals(strataNode.getId())) { + return Optional.of(strataNode); + } + } + return Optional.empty(); + } + + public Zone toBean() { + + Zone zone = Zones.newZone(); + zone.setId(getId()); + zone.setLabel(getUserObject()); + + Enumeration children = children(); + while (children.hasMoreElements()) { + Object strataNode = children.nextElement(); + zone.addStrata(((StrataNode) strataNode).toBean()); + } + + return zone; + + } + +} diff --git a/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel-error-validation.xml b/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel-error-validation.xml index 80b6b39..b261fb0 100644 --- a/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel-error-validation.xml +++ b/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel-error-validation.xml @@ -29,7 +29,7 @@ <field name="availableStratas"> <field-validator type="fieldexpression" short-circuit="true"> <param name="expression"> - <![CDATA[ !useCalcifiedPieceSampling || availableStratas.isEmpty() ]]> + <![CDATA[ !useCalcifiedPieceSampling || !availableStratas ]]> </param> <message> tutti.validator.error.zoneEditor.availableStratas.remaining diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties index 4ab3800..1043a84 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties @@ -2363,7 +2363,7 @@ tutti.validator.error.speciesFrequency.step.positiveValue=Le pas de la classe de tutti.validator.error.splitSpeciesBatch.sampleWeight.invalidValue=La somme des poids ventilés doit être strictement positive tutti.validator.error.splitSpeciesBatch.sampleWeight.sampleBatchGreaterThanBatchWeight=La somme des poids ventilés doit être inférieur ou égale à celle du poids du lot tutti.validator.error.splitSpeciesBatch.selectedCategory.required=La catégorie est obligatoire -tutti.validator.error.zoneEditor.availableStratas.remaining= +tutti.validator.error.zoneEditor.availableStratas.remaining=Il reste des strates ou des sous-strates à positionner dans les zones tutti.validator.info.cruise.noError=Campagne sans erreur tutti.validator.info.operation.noError=Trait sans erreur tutti.validator.warning.benthosFrequency.redundantTotalWeight=Le poids total est redondant (égal au poids calculé à partir des poids observés) -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.