Tony CHEMIT pushed to branch develop-7.x at ultreiaio / ird-observe Commits: 7f1ce7d1 by Tony CHEMIT at 2018-07-11T15:17:05Z Improve FOB Form (expand node when selected + expand enabled first level nodes on create mode) - See #948 - - - - - 6 changed files: - client/src/main/java/fr/ird/observe/client/ui/content/data/seine/FloatingObjectUI.jaxx - client/src/main/java/fr/ird/observe/client/ui/content/data/seine/FloatingObjectUI.jcss - client/src/main/java/fr/ird/observe/client/ui/content/data/seine/FloatingObjectUIHandler.java - client/src/main/java/fr/ird/observe/client/ui/content/data/seine/FloatingObjectUIModel.java - client/src/main/java/fr/ird/observe/client/ui/content/data/seine/dcp/FloatingObjectPartsTreeNode.java - + client/src/main/java/fr/ird/observe/client/ui/content/data/seine/dcp/FloatingObjectPartsTreeTable.java Changes: ===================================== client/src/main/java/fr/ird/observe/client/ui/content/data/seine/FloatingObjectUI.jaxx ===================================== @@ -39,6 +39,7 @@ fr.ird.observe.client.ui.actions.main.global.DeleteDataGlobalUIAction fr.ird.observe.client.ui.actions.main.global.ResetDataGlobalUIAction fr.ird.observe.client.ui.actions.main.global.SaveDataGlobalUIAction + fr.ird.observe.client.ui.content.data.seine.dcp.FloatingObjectPartsTreeTable fr.ird.observe.client.ui.content.data.seine.dcp.FloatingObjectPartsTreeTableModel fr.ird.observe.client.ui.content.data.seine.dcp.FloatingObjectPartLegendTreeCellRenderer fr.ird.observe.client.ui.util.JComment @@ -175,7 +176,7 @@ <row> <cell anchor="north" weightx="1" weighty="1"> <JScrollPane id='tableScroll'> - <JXTreeTable id='table'/> + <FloatingObjectPartsTreeTable id='table' constructorParams="new FloatingObjectPartsTreeTableModel(getModel())"/> </JScrollPane> </cell> </row> ===================================== client/src/main/java/fr/ird/observe/client/ui/content/data/seine/FloatingObjectUI.jcss ===================================== @@ -140,9 +140,3 @@ BeanComboBox { focusable:false; } -#table { - treeTableModel:{new FloatingObjectPartsTreeTableModel(getModel())}; - treeCellRenderer:{new FloatingObjectPartLegendTreeCellRenderer()}; - selectionMode:{ListSelectionModel.SINGLE_SELECTION}; - rootVisible:false; -} ===================================== client/src/main/java/fr/ird/observe/client/ui/content/data/seine/FloatingObjectUIHandler.java ===================================== @@ -29,9 +29,6 @@ import fr.ird.observe.client.db.constants.DataContextType; import fr.ird.observe.client.ui.content.ContentMode; import fr.ird.observe.client.ui.content.ContentUIHandler; import fr.ird.observe.client.ui.content.ContentUIModel; -import fr.ird.observe.client.ui.content.data.seine.dcp.FloatingObjectPartsTableCellEditor; -import fr.ird.observe.client.ui.content.data.seine.dcp.FloatingObjectPartsTableCellRenderer; -import fr.ird.observe.client.ui.content.data.seine.dcp.FloatingObjectPartsTreeNode; import fr.ird.observe.client.ui.content.data.seine.dcp.FloatingObjectPartsTreeTableModel; import fr.ird.observe.client.ui.tree.navigation.NavigationTree; import fr.ird.observe.client.ui.tree.navigation.nodes.NavigationTreeNodeSupport; @@ -53,12 +50,6 @@ import fr.ird.observe.services.service.actions.consolidate.dcp.ConsolidateFloati import fr.ird.observe.spi.DtoModelHelper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.log4j.lf5.viewer.categoryexplorer.TreeModelAdapter; -import org.jdesktop.swingx.JXTable; -import org.jdesktop.swingx.JXTreeTable; -import org.jdesktop.swingx.decorator.ColorHighlighter; -import org.jdesktop.swingx.table.ColumnFactory; -import org.jdesktop.swingx.table.TableColumnExt; import org.nuiton.jaxx.runtime.spi.UIHandler; import org.nuiton.jaxx.runtime.swing.SwingUtil; import org.nuiton.jaxx.validator.swing.SwingValidatorMessage; @@ -68,8 +59,6 @@ import org.nuiton.validator.NuitonValidatorScope; import javax.swing.Icon; import javax.swing.SwingUtilities; import javax.swing.event.TableModelListener; -import javax.swing.event.TreeModelEvent; -import java.awt.Color; import java.util.HashSet; import java.util.Map; import java.util.Objects; @@ -182,17 +171,18 @@ public class FloatingObjectUIHandler extends ContentUIHandler<FloatingObjectDto, } loadReferentialReferenceSetsInModel(form); - getModel().setForm(form); + FloatingObjectUIModel model = getModel(); + model.setForm(form); FloatingObjectHelper.copyFloatingObjectDto(form.getObject(), bean); - getModel().reset(); + model.reset(); - openTable(partsSet, getUi().getTable(), bean.isPersisted()); + getUi().getTable().openTable(model, partsSet, bean.isPersisted()); setContentMode(mode); // do this after setting mode (since only update mode use this...) - getModel().setReference(floatingObjectReference.orElse(null)); + model.setReference(floatingObjectReference.orElse(null)); if (mode != ContentMode.READ) { getUi().startEdit(null); @@ -203,33 +193,9 @@ public class FloatingObjectUIHandler extends ContentUIHandler<FloatingObjectDto, @Override protected void openedUI() { - SwingUtilities.invokeLater(this::forceGrabFocusOnForm); } - private void openTable(Set<FloatingObjectPartReference> partsSet, JXTreeTable table, boolean persisted) { - - FloatingObjectUIModel model = getModel(); - for (FloatingObjectPartReference p : partsSet) { - String objectMaterialId = p.getObjectMaterialId(); - String whenArriving = p.getWhenArriving(); - String whenLeaving = p.getWhenLeaving(); - if (whenArriving != null && !Objects.equals("false", whenArriving)) { - model.setWhenArriving(objectMaterialId, whenArriving); - } - if (whenLeaving != null && !Objects.equals("false", whenLeaving)) { - model.setWhenLeaving(objectMaterialId, whenLeaving); - } - } - - FloatingObjectPartsTreeTableModel treeTableModel = (FloatingObjectPartsTreeTableModel) table.getTreeTableModel(); - treeTableModel.reset(); - - if (persisted) { - table.expandAll(); - } - } - @Override public void startEditUI(String... binding) { ContentUIModel<FloatingObjectDto> contentUIModel = getModel(); @@ -334,7 +300,7 @@ public class FloatingObjectUIHandler extends ContentUIHandler<FloatingObjectDto, FloatingObjectUIModel model = getModel(); model.setReferentialMap(allMap); - initTable(detailedForm, ui.getTable()); + ui.getTable().initTable(model, () -> getUi().getPreferredSize().width - 200, detailedForm); model.addPropertyChangeListener(FloatingObjectUIModel.PROPERTY_REFERENCE, e -> { if (!model.isUpdatingMode()) { @@ -386,60 +352,10 @@ public class FloatingObjectUIHandler extends ContentUIHandler<FloatingObjectDto, getModel().setArriving(operation.isWhenArriving()); getModel().setLeaving(operation.isWhenLeaving()); } - FloatingObjectPartsTreeTableModel treeModel = (FloatingObjectPartsTreeTableModel) getUi().getTable().getTreeTableModel(); + FloatingObjectPartsTreeTableModel treeModel = getUi().getTable().getTreeTableModel(); treeModel.reset(); } - private void initTable(ObjectMaterialHierarchyDto materials, JXTreeTable table) { - - FloatingObjectPartsTreeTableModel treeModel = (FloatingObjectPartsTreeTableModel) table.getTreeTableModel(); - treeModel.rebuildRootNode(materials); - - table.setColumnFactory(new ColumnFactory() { - - @Override - public void configureColumnWidths(JXTable table, TableColumnExt columnExt) { - if (table.getColumn(0).equals(columnExt)) { - columnExt.setPreferredWidth(getUi().getPreferredSize().width - 200); - columnExt.setMinWidth(columnExt.getPreferredWidth()); - return; - } - super.configureColumnWidths(table, columnExt); - columnExt.setMinWidth(columnExt.getPreferredWidth()); - } - }); - treeModel.addTreeModelListener(new TreeModelAdapter() { - @Override - public void treeNodesChanged(TreeModelEvent e) { - if (treeModel.isAdjusting()) { - return; - } - getModel().setModified(true); - getModel().setPartsModified(); - } - - }); - - table.setDefaultRenderer(Object.class, new FloatingObjectPartsTableCellRenderer(table)); - table.setDefaultEditor(Object.class, new FloatingObjectPartsTableCellEditor(table)); - table.addHighlighter(new ColorHighlighter((renderer, adapter) -> { - JXTreeTable component = (JXTreeTable) adapter.getComponent(); - int row = adapter.convertRowIndexToModel(adapter.row); - FloatingObjectPartsTreeNode node = (FloatingObjectPartsTreeNode) component.getPathForRow(row).getLastPathComponent(); - boolean valid1 = node.isValid(1); - boolean valid2 = node.isValid(2); - switch (adapter.convertRowIndexToModel(adapter.column)) { - case 0: - return false; - case 1: - return !valid1; - case 2: - return !valid2; - } - return true; - }, ObserveSwingApplicationContext.get().getConfig().getFloatingObjectMaterialErrorColor(), Color.WHITE)); - } - protected void computeTabValidState(SwingValidatorMessageTableModel errorTableModel) { Set<String> errorProperties = new HashSet<>(); ===================================== client/src/main/java/fr/ird/observe/client/ui/content/data/seine/FloatingObjectUIModel.java ===================================== @@ -127,7 +127,7 @@ public class FloatingObjectUIModel extends ContentUIModel<FloatingObjectDto> { return result.build(); } - void setPartsModified() { + public void setPartsModified() { firePropertyChange(PROPERTY_PARTS_MODIFIED, true); } ===================================== client/src/main/java/fr/ird/observe/client/ui/content/data/seine/dcp/FloatingObjectPartsTreeNode.java ===================================== @@ -23,9 +23,11 @@ package fr.ird.observe.client.ui.content.data.seine.dcp; */ import com.google.common.collect.ImmutableSet; +import fr.ird.observe.client.ObserveSwingApplicationContext; import fr.ird.observe.client.ui.content.data.seine.FloatingObjectUIModel; import fr.ird.observe.dto.data.seine.ObjectMaterialHierarchyDto; import fr.ird.observe.dto.referential.FormulaHelper; +import fr.ird.observe.dto.referential.ReferentialLocale; import fr.ird.observe.dto.referential.seine.ObjectMaterialTypeReference; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -203,14 +205,17 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im } void computeMandatoryValidState(boolean whenArriving, boolean whenLeaving) { + FloatingObjectPartsTreeNodeContext userObject = getUserObject(); if (whenArriving) { - getUserObject().validWhenArriving = getParent().getUserObject().validWhenArriving; + userObject.validWhenArriving = getParent().getUserObject().validWhenArriving; } if (whenLeaving) { - getUserObject().validWhenLeaving = getParent().getUserObject().validWhenLeaving; + userObject.validWhenLeaving = getParent().getUserObject().validWhenLeaving; } - log.info("Validate node " + this); + if (userObject.getValueAt(1) != null || userObject.getValueAt(2) != null) { + log.info("Validate node " + this); + } } void computeFormulaValidState(boolean whenArriving, boolean whenLeaving) { @@ -304,6 +309,7 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im private final boolean mandatory; // Is the node is exclusive (means only one value possible for him and his brothers) ? private final boolean exclusive; + private final ReferentialLocale referentialLocale; // Is the node valid for whenArriving column ? private boolean validWhenArriving = true; // Is the node valid for whenLeaving column ? @@ -322,6 +328,7 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im this.mandatory = false; this.exclusive = false; this.needOneSelection = false; + this.referentialLocale=ObserveSwingApplicationContext.get().getDecoratorService().getReferentialLocale(); } FloatingObjectPartsTreeNodeContext(ObjectMaterialHierarchyDto dto, FloatingObjectPartsTreeNodeContext parent) { @@ -340,7 +347,8 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im this.mandatory = parent.mandatory || parent.needOneSelection; // exclusive if his parent requires it this.exclusive = parent.dto != null && !parent.dto.isChildrenMultiSelectable(); - log.info(String.format("New node: %s - mandatory %s - needOneSelection %s - exclusive %s", dto.getLabel2(), mandatory, needOneSelection, exclusive)); + this.referentialLocale=ObserveSwingApplicationContext.get().getDecoratorService().getReferentialLocale(); + log.info(String.format("New node: %s - mandatory %s - needOneSelection %s - exclusive %s", dto.getLabel(referentialLocale), mandatory, needOneSelection, exclusive)); } Object getValueAt(int column) { @@ -356,6 +364,7 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im } void setValueAt(Object aValue, int column) { + text = null; switch (column) { case 1: // when arriving uiModel.setWhenArriving(dto.getId(), aValue == null ? null : String.valueOf(aValue)); @@ -393,7 +402,7 @@ public class FloatingObjectPartsTreeNode extends AbstractMutableTreeTableNode im public String getText() { if (text == null && dto != null) { - text = String.format("%s [value: %s-%s] [valid: %s-%s]", dto.getLabel2(), getValueAt(1), getValueAt(2), isValid(1), isValid(2)); + text = String.format("%s [value: %s-%s] [valid: %s-%s]", dto.getLabel(referentialLocale), getValueAt(1), getValueAt(2), isValid(1), isValid(2)); } return text; } ===================================== client/src/main/java/fr/ird/observe/client/ui/content/data/seine/dcp/FloatingObjectPartsTreeTable.java ===================================== @@ -0,0 +1,156 @@ +package fr.ird.observe.client.ui.content.data.seine.dcp; + +/*- + * #%L + * ObServe :: Client + * %% + * Copyright (C) 2008 - 2018 IRD, Code Lutin, Ultreia.io + * %% + * 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.ird.observe.client.ObserveSwingApplicationContext; +import fr.ird.observe.client.ui.content.data.seine.FloatingObjectUIModel; +import fr.ird.observe.dto.data.seine.FloatingObjectPartReference; +import fr.ird.observe.dto.data.seine.ObjectMaterialHierarchyDto; +import org.apache.log4j.lf5.viewer.categoryexplorer.TreeModelAdapter; +import org.jdesktop.swingx.JXTable; +import org.jdesktop.swingx.JXTreeTable; +import org.jdesktop.swingx.decorator.ColorHighlighter; +import org.jdesktop.swingx.table.ColumnFactory; +import org.jdesktop.swingx.table.TableColumnExt; +import org.jdesktop.swingx.treetable.MutableTreeTableNode; + +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.event.TreeModelEvent; +import javax.swing.tree.TreePath; +import java.awt.Color; +import java.util.Enumeration; +import java.util.Objects; +import java.util.Set; +import java.util.function.Supplier; + +/** + * Created by tchemit on 11/07/2018. + * + * @author Tony Chemit - dev@tchemit.fr + */ +public class FloatingObjectPartsTreeTable extends JXTreeTable { + + public FloatingObjectPartsTreeTable(FloatingObjectPartsTreeTableModel treeModel) { + super(treeModel); + setTreeCellRenderer(new FloatingObjectPartLegendTreeCellRenderer()); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + setRootVisible(false); + } + + @Override + public FloatingObjectPartsTreeTableModel getTreeTableModel() { + return (FloatingObjectPartsTreeTableModel) super.getTreeTableModel(); + } + + public void openTable(FloatingObjectUIModel model, Set<FloatingObjectPartReference> partsSet, boolean persisted) { + + for (FloatingObjectPartReference p : partsSet) { + String objectMaterialId = p.getObjectMaterialId(); + String whenArriving = p.getWhenArriving(); + String whenLeaving = p.getWhenLeaving(); + if (whenArriving != null && !Objects.equals("false", whenArriving)) { + model.setWhenArriving(objectMaterialId, whenArriving); + } + if (whenLeaving != null && !Objects.equals("false", whenLeaving)) { + model.setWhenLeaving(objectMaterialId, whenLeaving); + } + } + + FloatingObjectPartsTreeTableModel treeTableModel = getTreeTableModel(); + treeTableModel.reset(); + + if (persisted) { + expandAll(); + } else { + // expand first level nodes (except if they are disabled) + FloatingObjectPartsTreeNode root = treeTableModel.getRoot(); + Enumeration<? extends MutableTreeTableNode> children = root.children(); + while (children.hasMoreElements()) { + FloatingObjectPartsTreeNode mutableTreeTableNode = (FloatingObjectPartsTreeNode) children.nextElement(); + if (mutableTreeTableNode.isEnabled()) { + SwingUtilities.invokeLater(() -> expandPath(new TreePath(new Object[]{root, mutableTreeTableNode}))); + } + } + } + // auto expand nodes when selected + addTreeSelectionListener(e -> { + int selectedRow = getSelectedRow(); + if (selectedRow != -1) { + if (!isExpanded(selectedRow)) { + SwingUtilities.invokeLater(() -> expandRow(selectedRow)); + } + } + }); + } + + public void initTable(FloatingObjectUIModel model, Supplier<Integer> width, ObjectMaterialHierarchyDto materials) { + + FloatingObjectPartsTreeTableModel treeModel = getTreeTableModel(); + treeModel.rebuildRootNode(materials); + + setColumnFactory(new ColumnFactory() { + + @Override + public void configureColumnWidths(JXTable table, TableColumnExt columnExt) { + if (table.getColumn(0).equals(columnExt)) { + columnExt.setPreferredWidth(width.get()); + columnExt.setMinWidth(columnExt.getPreferredWidth()); + return; + } + super.configureColumnWidths(table, columnExt); + columnExt.setMinWidth(columnExt.getPreferredWidth()); + } + }); + treeModel.addTreeModelListener(new TreeModelAdapter() { + @Override + public void treeNodesChanged(TreeModelEvent e) { + if (treeModel.isAdjusting()) { + return; + } + model.setModified(true); + model.setPartsModified(); + } + + }); + + setDefaultRenderer(Object.class, new FloatingObjectPartsTableCellRenderer(this)); + setDefaultEditor(Object.class, new FloatingObjectPartsTableCellEditor(this)); + addHighlighter(new ColorHighlighter((renderer, adapter) -> { + JXTreeTable component = (JXTreeTable) adapter.getComponent(); + int row = adapter.convertRowIndexToModel(adapter.row); + FloatingObjectPartsTreeNode node = (FloatingObjectPartsTreeNode) component.getPathForRow(row).getLastPathComponent(); + boolean valid1 = node.isValid(1); + boolean valid2 = node.isValid(2); + switch (adapter.convertRowIndexToModel(adapter.column)) { + case 0: + return false; + case 1: + return !valid1; + case 2: + return !valid2; + } + return true; + }, ObserveSwingApplicationContext.get().getConfig().getFloatingObjectMaterialErrorColor(), Color.WHITE)); + } +} View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/commit/7f1ce7d15063b77511c57902d2b2... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/commit/7f1ce7d15063b77511c57902d2b2... You're receiving this email because of your account on gitlab.com.