This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository tutti. See http://git.codelutin.com/tutti.git commit 5b82225d59a0587e39b47270751e20e67a9bf703 Author: Tony CHEMIT <chemit@codelutin.com> Date: Thu Jan 1 14:58:35 2015 +0100 remise a plat de l'ecran SpeciesFrequency --- pom.xml | 2 +- .../frequency/BenthosFrequencyTableModel.java | 6 +- .../frequency/SpeciesFrequencyCellComponent.java | 10 +- .../SpeciesFrequencyLogCellComponent.java | 84 ++- .../frequency/SpeciesFrequencyLogRowModel.java | 5 +- .../frequency/SpeciesFrequencyLogsTableModel.java | 7 - .../frequency/SpeciesFrequencyTableModel.java | 274 ++++++--- .../species/frequency/SpeciesFrequencyUI.css | 42 +- .../species/frequency/SpeciesFrequencyUI.jaxx | 78 ++- .../frequency/SpeciesFrequencyUIHandler.java | 651 ++++----------------- .../species/frequency/SpeciesFrequencyUIModel.java | 224 ++++--- .../frequency/SpeciesFrequencyUIModelCache.java | 134 +++++ .../actions/AddLengthStepCaracteristicAction.java | 75 +++ .../frequency/actions/ApplyRafaleAction.java | 106 ++++ .../species/frequency/actions/CancelAction.java | 49 ++ .../frequency/actions/DeleteLogRowAction.java | 70 +++ .../actions/GenerateLengthStepsAction.java | 78 +++ .../species/frequency/actions/ResetAction.java | 43 ++ .../frequency/actions/SaveAndCloseAction.java | 55 ++ .../frequency/actions/SaveAndContinueAction.java | 49 ++ .../frequency/actions/SaveSupportAction.java | 105 ++++ 21 files changed, 1348 insertions(+), 799 deletions(-) diff --git a/pom.xml b/pom.xml index d0e5b16..492c71b 100644 --- a/pom.xml +++ b/pom.xml @@ -132,7 +132,7 @@ <nuitonI18nVersion>3.3</nuitonI18nVersion> <nuitonValidatorVersion>3.0-rc-2</nuitonValidatorVersion> <eugenePluginVersion>2.13</eugenePluginVersion> - <jaxxVersion>2.17</jaxxVersion> + <jaxxVersion>2.20-SNAPSHOT</jaxxVersion> <swingXVersion>1.6.4</swingXVersion> <slf4jVersion>1.7.7</slf4jVersion> <adagioVersion>3.6.4</adagioVersion> diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyTableModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyTableModel.java index e87b7fd..6e497ec 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyTableModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyTableModel.java @@ -101,7 +101,7 @@ public class BenthosFrequencyTableModel extends AbstractApplicationTableModel<Be } @Override - protected void onRowAdded(int rowIndex, BenthosFrequencyRowModel newValue) { + protected void onRowAdded(int rowIndex, BenthosFrequencyRowModel row) { recomputeCanEditLengthStep(); } @@ -169,12 +169,12 @@ public class BenthosFrequencyTableModel extends AbstractApplicationTableModel<Be } @Override - protected void onRowsChanged(List<BenthosFrequencyRowModel> data) { + protected void onRowsChanged(List<BenthosFrequencyRowModel> newRows) { // rebuild row cache rowCache.clear(); - for (BenthosFrequencyRowModel row : data) { + for (BenthosFrequencyRowModel row : newRows) { Float lengthStep = row.getLengthStep(); if (lengthStep != null) { rowCache.put(lengthStep, row); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyCellComponent.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyCellComponent.java index 60515a1..68e1212 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyCellComponent.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyCellComponent.java @@ -24,16 +24,16 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; -import fr.ifremer.tutti.ui.swing.util.computable.ComputableData; import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.SpeciesBatchRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.SpeciesBatchTableModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.SpeciesBatchUI; -import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil; -import org.nuiton.jaxx.application.swing.table.ColumnIdentifier; +import fr.ifremer.tutti.ui.swing.util.computable.ComputableData; import jaxx.runtime.SwingUtil; +import jaxx.runtime.swing.JTables; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.jaxx.application.swing.table.ColumnIdentifier; import javax.swing.AbstractCellEditor; import javax.swing.JTable; @@ -263,7 +263,7 @@ public class SpeciesFrequencyCellComponent extends DefaultTableCellRenderer { stopCellEditing(); // reselect this cell - TuttiUIUtil.doSelectCell(table, r, c); + JTables.doSelectCell(table, r, c); table.requestFocus(); } else { @@ -283,7 +283,7 @@ public class SpeciesFrequencyCellComponent extends DefaultTableCellRenderer { editRow = tableModel.getEntry(rowIndex); // will save the previous row in the species row - TuttiUIUtil.doSelectCell(table, rowIndex, c); + JTables.doSelectCell(table, rowIndex, c); // start edit startEdit(); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogCellComponent.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogCellComponent.java index 47ca61d..c7d306f 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogCellComponent.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogCellComponent.java @@ -22,21 +22,21 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; * #L% */ +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions.DeleteLogRowAction; import jaxx.runtime.swing.JAXXWidgetUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import sun.swing.DefaultLookup; -import javax.swing.*; -import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.AbstractCellEditor; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.UIManager; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.Serializable; - -import static org.nuiton.i18n.I18n.t; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; /** * Component to render and delete log items from logs table. @@ -44,20 +44,14 @@ import static org.nuiton.i18n.I18n.t; * @author Kevin Morin (Code Lutin) * @since 3.8 */ -public class SpeciesFrequencyLogCellComponent extends JPanel implements Serializable { - - private static final long serialVersionUID = 1L; +public class SpeciesFrequencyLogCellComponent extends JPanel { - /** Logger. */ - private static final Log log = LogFactory.getLog(SpeciesFrequencyLogCellComponent.class); + private static final long serialVersionUID = -3050615446905949687L; private JLabel label = new JLabel(); - private JButton deleteButton = new JButton(); - - private SpeciesFrequencyLogRowModel row; + public SpeciesFrequencyLogCellComponent(DeleteLogRowAction action) { - public SpeciesFrequencyLogCellComponent() { setLayout(new BorderLayout()); Font defaultFont = UIManager.getFont("Table.font"); @@ -65,49 +59,29 @@ public class SpeciesFrequencyLogCellComponent extends JPanel implements Serializ label.setOpaque(false); add(label, BorderLayout.CENTER); + JButton deleteButton = new JButton(); deleteButton.setIcon(JAXXWidgetUtil.createActionIcon("delete")); deleteButton.setBorderPainted(false); deleteButton.setBorder(null); deleteButton.setBackground(null); label.setOpaque(false); add(deleteButton, BorderLayout.EAST); - } + if (action != null) { + deleteButton.setAction(action); + } - public SpeciesFrequencyLogCellComponent(final SpeciesFrequencyUIHandler speciesFrequencyUIHandler) { - this(); - deleteButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (row != null) { - int i = JOptionPane.showConfirmDialog( - speciesFrequencyUIHandler.getTopestUI(), - t("tutti.editSpeciesFrequencies.logTable.removeRow.confirm.message", row.getLabel()), - t("tutti.editSpeciesFrequencies.logTable.removeRow.confirm.title"), - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE); - - if (i == JOptionPane.YES_OPTION) { - speciesFrequencyUIHandler.decrementLengthStep(row); - } - } - } - }); } public void setData(String data) { label.setText(data); } - public void setRow(SpeciesFrequencyLogRowModel row) { - this.row = row; - } - public static TableCellRenderer newRender() { return new FrequencyLogCellRenderer(); } - public static TableCellEditor newEditor(SpeciesFrequencyUIHandler speciesFrequencyUIHandler) { - return new FrequencyLogCellEditor(speciesFrequencyUIHandler); + public static TableCellEditor newEditor(SpeciesFrequencyUI speciesFrequencyUI) { + return new FrequencyLogCellEditor(speciesFrequencyUI); } public static class FrequencyLogCellEditor extends AbstractCellEditor implements TableCellEditor { @@ -116,8 +90,18 @@ public class SpeciesFrequencyLogCellComponent extends JPanel implements Serializ protected final SpeciesFrequencyLogCellComponent component; - public FrequencyLogCellEditor(SpeciesFrequencyUIHandler speciesFrequencyUIHandler) { - component = new SpeciesFrequencyLogCellComponent(speciesFrequencyUIHandler); + private SpeciesFrequencyLogRowModel row; + + public FrequencyLogCellEditor(SpeciesFrequencyUI speciesFrequencyUI) { + component = new SpeciesFrequencyLogCellComponent(new DeleteLogRowAction(speciesFrequencyUI, this)); + } + + public void setRow(SpeciesFrequencyLogRowModel row) { + this.row = row; + } + + public SpeciesFrequencyLogRowModel getRow() { + return row; } @Override @@ -129,7 +113,7 @@ public class SpeciesFrequencyLogCellComponent extends JPanel implements Serializ SpeciesFrequencyLogsTableModel tableModel = (SpeciesFrequencyLogsTableModel) table.getModel(); SpeciesFrequencyLogRowModel editRow = tableModel.getEntry(row); - component.setRow(editRow); + setRow(editRow); String data = (String) value; component.setData(data); @@ -149,7 +133,7 @@ public class SpeciesFrequencyLogCellComponent extends JPanel implements Serializ protected final SpeciesFrequencyLogCellComponent component; public FrequencyLogCellRenderer() { - component = new SpeciesFrequencyLogCellComponent(); + component = new SpeciesFrequencyLogCellComponent(null); } @Override diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogRowModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogRowModel.java index 6bee10c..924a934 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogRowModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogRowModel.java @@ -25,10 +25,8 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; */ import org.apache.commons.lang3.time.DateFormatUtils; -import org.jdesktop.beans.AbstractBean; import org.jdesktop.beans.AbstractSerializableBean; -import java.io.Serializable; import java.util.Date; /** @@ -39,7 +37,10 @@ public class SpeciesFrequencyLogRowModel extends AbstractSerializableBean { public static final String PROPERTY_LABEL = "label"; + private static final long serialVersionUID = 1L; + protected Float lengthStep; + protected Date date; public Float getLengthStep() { diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogsTableModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogsTableModel.java index 7736918..8e0f1b4 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogsTableModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyLogsTableModel.java @@ -22,17 +22,10 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; * #L% */ -import com.google.common.collect.Maps; -import fr.ifremer.tutti.type.WeightUnit; import org.jdesktop.swingx.table.TableColumnModelExt; import org.nuiton.jaxx.application.swing.table.AbstractApplicationTableModel; import org.nuiton.jaxx.application.swing.table.ColumnIdentifier; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.List; -import java.util.Map; - import static org.nuiton.i18n.I18n.n; /** diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyTableModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyTableModel.java index 6efd894..2abde8d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyTableModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyTableModel.java @@ -22,17 +22,15 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; * #L% */ -import com.google.common.collect.Maps; import fr.ifremer.tutti.type.WeightUnit; -import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyRowModel; +import org.jdesktop.swingx.table.TableColumnModelExt; +import org.jfree.data.xy.XYSeries; import org.nuiton.jaxx.application.swing.table.AbstractApplicationTableModel; import org.nuiton.jaxx.application.swing.table.ColumnIdentifier; -import org.jdesktop.swingx.table.TableColumnModelExt; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; -import java.util.Map; import static org.nuiton.i18n.I18n.n; @@ -63,7 +61,7 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp private final SpeciesFrequencyUIModel uiModel; - private final Map<Float, SpeciesFrequencyRowModel> rowCache; + private final SpeciesFrequencyUIModelCache modelCache; /** * Weight unit. @@ -72,67 +70,31 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp */ protected final WeightUnit weightUnit; - protected final PropertyChangeListener rowPropertyChangeListener; - protected final PropertyChangeListener onLengthStepChangedListener; + protected transient PropertyChangeListener onLengthStepChangedListener; + + protected transient PropertyChangeListener onWeightChangedListener; + + protected transient PropertyChangeListener onNumberChangedListener; + + protected final XYSeries series; public SpeciesFrequencyTableModel(WeightUnit weightUnit, TableColumnModelExt columnModel, - SpeciesFrequencyUIModel uiModel, - PropertyChangeListener rowPropertyChangeListener) { + SpeciesFrequencyUIModel uiModel) { super(columnModel, true, true); this.weightUnit = weightUnit; this.uiModel = uiModel; - this.rowCache = Maps.newTreeMap(); - this.rowPropertyChangeListener = rowPropertyChangeListener; - this.onLengthStepChangedListener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - Float oldValue = (Float) evt.getOldValue(); - if (oldValue != null) { - rowCache.remove(oldValue); - } - SpeciesFrequencyRowModel row = (SpeciesFrequencyRowModel) evt.getSource(); - Float lengthStep = row.getLengthStep(); - if (lengthStep != null) { - rowCache.put(lengthStep, row); - } - } - }; + this.modelCache = uiModel.cache; + this.series = uiModel.dataset.getSeries(0); setNoneEditableCols(); } @Override - protected void onRowAdded(int rowIndex, SpeciesFrequencyRowModel newValue) { - recomputeCanEditLengthStep(); - } - - public void recomputeCanEditLengthStep() { - - boolean result = true; - - for (SpeciesFrequencyRowModel row : rows) { - - if (row.isEmpty()) { - // la ligne est vide - continue; - } - if (row.getLengthStep() == null || row.getNumber() == null) { - // la ligne n'est pas complete - continue; - } - - // une ligne non vide et complete a ete trouvee - // on ne peut plus editer - result = false; - - } - - uiModel.setCanEditLengthStep(result); - + public SpeciesFrequencyRowModel createNewRow() { + return createNewRow(true); } - @Override - public SpeciesFrequencyRowModel createNewRow() { + public SpeciesFrequencyRowModel createNewRow(boolean attachListeners) { Float defaultStep = null; int rowCount = getRowCount(); @@ -141,18 +103,19 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp SpeciesFrequencyRowModel rowModel = getEntry(rowCount - 1); Float lengthStep = rowModel.getLengthStep(); if (lengthStep != null) { - defaultStep = uiModel.getLengthStep( - lengthStep + uiModel.getStep()); + defaultStep = uiModel.getLengthStep(lengthStep + uiModel.getStep()); } } SpeciesFrequencyRowModel result = new SpeciesFrequencyRowModel(weightUnit); - result.addPropertyChangeListener(SpeciesFrequencyRowModel.PROPERTY_LENGTH_STEP,onLengthStepChangedListener); - result.addPropertyChangeListener(rowPropertyChangeListener); + if (attachListeners) { + attachListeners(result); + } result.setLengthStepCaracteristic(uiModel.getLengthStepCaracteristic()); result.setLengthStep(defaultStep); result.setValid(defaultStep != null); + return result; } @@ -166,23 +129,198 @@ public class SpeciesFrequencyTableModel extends AbstractApplicationTableModel<Sp // TODO Rebuild the computedWeight if possible... } - public Map<Float, SpeciesFrequencyRowModel> getRowCache() { - return rowCache; + @Override + protected void onRowAdded(int rowIndex, SpeciesFrequencyRowModel row) { + uiModel.recomputeCanEditLengthStep(); } @Override - protected void onRowsChanged(List<SpeciesFrequencyRowModel> data) { + protected void onRowUpdated(int rowIndex, SpeciesFrequencyRowModel row) { + uiModel.recomputeCanEditLengthStep(); + } - // rebuild row cache - rowCache.clear(); + @Override + protected void onRowRemoved(int rowIndex, SpeciesFrequencyRowModel row) { + dettachListeners(row); + uiModel.recomputeCanEditLengthStep(); + } + + @Override + protected void onBeforeRowsChanged(List<SpeciesFrequencyRowModel> oldRows) { + + if (oldRows != null) { + + for (SpeciesFrequencyRowModel row : oldRows) { + dettachListeners(row); + } + + } + + } + + @Override + protected void onRowsChanged(List<SpeciesFrequencyRowModel> newRows) { + + if (newRows != null) { + + for (SpeciesFrequencyRowModel row : newRows) { + dettachListeners(row); // prevent leaks! + attachListeners(row); + } + + } + + uiModel.recomputeCanEditLengthStep(); + + } + + public void decrementNumberForLengthStep(Float lengthStep) { + + SpeciesFrequencyRowModel row = modelCache.getRowCache().get(lengthStep); + + if (row != null) { + + Integer number = row.getNumber(); + + if (number != null) { + + if (number > 1) { + row.setNumber(number - 1); + } else { + row.setNumber(null); + } + + int rowIndex = getRowIndex(row); + + fireTableRowsUpdated(rowIndex, rowIndex); - for (SpeciesFrequencyRowModel row : data) { - Float lengthStep = row.getLengthStep(); - if (lengthStep != null) { - rowCache.put(lengthStep, row); } + + uiModel.recomputeCanEditLengthStep(); + + } + + } + + private PropertyChangeListener getOnLengthStepChangedListener() { + if (onLengthStepChangedListener == null) { + onLengthStepChangedListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + Float oldValue = (Float) evt.getOldValue(); + if (oldValue != null) { + + modelCache.removeLengthStep(oldValue); + if (series.indexOf(oldValue) >= 0) { + series.remove(oldValue); + } + + } + + SpeciesFrequencyRowModel row = (SpeciesFrequencyRowModel) evt.getSource(); + + Float newValue = (Float) evt.getNewValue(); + if (newValue != null) { + + modelCache.addLengthStep(row); + + if (row.getNumber() != null) { + + series.addOrUpdate(newValue, row.getNumber()); + + } + + } + + uiModel.recomputeTotalNumberAndWeight(); + uiModel.recomputeRowsValidateState(); + uiModel.recomputeCanEditLengthStep(); + uiModel.updateEmptyRow(row); + + fireTableDataChanged(); + + } + }; } + return onLengthStepChangedListener; + } + + private PropertyChangeListener getOnNumberChangedListener() { + if (onNumberChangedListener == null) { + onNumberChangedListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + SpeciesFrequencyRowModel row = (SpeciesFrequencyRowModel) evt.getSource(); + + Integer newValue = (Integer) evt.getNewValue(); + + Float lengthStep = row.getLengthStep(); + + if (lengthStep != null) { + + if (newValue == null) { + + // remove the value for the lengthStep + if (series.indexOf(lengthStep) >= 0) { + series.remove(lengthStep); + } + + } else { + + series.addOrUpdate(lengthStep, row.getNumber()); + + } + + } + + uiModel.recomputeTotalNumberAndWeight(); + uiModel.recomputeCanEditLengthStep(); + uiModel.recomputeRowValidState(row); + uiModel.updateEmptyRow(row); + + } + }; + } + return onNumberChangedListener; + } + + private PropertyChangeListener getOnWeightChangedListener() { + if (onWeightChangedListener == null) { + onWeightChangedListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + SpeciesFrequencyRowModel row = (SpeciesFrequencyRowModel) evt.getSource(); + modelCache.updateRowWithWeight(row); + + uiModel.recomputeTotalNumberAndWeight(); + uiModel.recomputeRowsValidateState(); + + uiModel.updateEmptyRow(row); + + fireTableDataChanged(); + + } + }; + } + return onWeightChangedListener; + } + + private void dettachListeners(SpeciesFrequencyRowModel result) { + + result.removePropertyChangeListener(SpeciesFrequencyRowModel.PROPERTY_LENGTH_STEP, getOnLengthStepChangedListener()); + result.removePropertyChangeListener(SpeciesFrequencyRowModel.PROPERTY_WEIGHT, getOnWeightChangedListener()); + result.removePropertyChangeListener(SpeciesFrequencyRowModel.PROPERTY_NUMBER, getOnNumberChangedListener()); + + } + + private void attachListeners(SpeciesFrequencyRowModel result) { + + result.addPropertyChangeListener(SpeciesFrequencyRowModel.PROPERTY_LENGTH_STEP, getOnLengthStepChangedListener()); + result.addPropertyChangeListener(SpeciesFrequencyRowModel.PROPERTY_WEIGHT, getOnWeightChangedListener()); + result.addPropertyChangeListener(SpeciesFrequencyRowModel.PROPERTY_NUMBER, getOnNumberChangedListener()); - recomputeCanEditLengthStep(); } } \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.css b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.css index ab2f490..ece6954 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.css +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.css @@ -279,53 +279,71 @@ ComputableDataEditor { _help: {"tutti.editSpeciesFrequencies.field.mode.simpleCounting.help"}; } +#generateLengthStepsAction { + enabled: {model.isCanGenerate()}; +} + #generateButton { - actionIcon: generate; + action: {generateLengthStepsAction}; + /*actionIcon: generate; text: "tutti.editSpeciesFrequencies.action.generate"; toolTipText: "tutti.editSpeciesFrequencies.action.generate.tip"; i18nMnemonic: "tutti.editSpeciesFrequencies.action.generate.mnemonic"; - enabled: {model.isCanGenerate()}; + enabled: {model.isCanGenerate()};*/ _help: {"tutti.editSpeciesFrequencies.action.generate.help"}; } #addLengthStepCaracteristicButton { - text: "tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic"; + action: {addLengthStepCaracteristicAction}; + /*text: "tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic"; toolTipText: "tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic.tip"; - i18nMnemonic: "tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic.mnemonic"; + i18nMnemonic: "tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic.mnemonic";*/ _help: {"tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic.help"}; } #cancelButton { - actionIcon: cancel; + action: {cancelAction}; + /*actionIcon: cancel; text: "tutti.editSpeciesFrequencies.action.cancel"; toolTipText: "tutti.editSpeciesFrequencies.action.cancel.tip"; - i18nMnemonic: "tutti.editSpeciesFrequencies.action.cancel.mnemonic"; + i18nMnemonic: "tutti.editSpeciesFrequencies.action.cancel.mnemonic";*/ _help: {"tutti.editSpeciesFrequencies.action.cancel.help"}; } +#saveAndContinueAction { + enabled: {model.getNextEditableRowIndex() != null && model.isValid()}; +} + #saveAndContinueButton { - actionIcon: save; + action: {saveAndContinueAction}; + /*actionIcon: save; text: "tutti.editSpeciesFrequencies.action.saveAndContinue"; toolTipText: "tutti.editSpeciesFrequencies.action.saveAndContinue.tip"; i18nMnemonic: "tutti.editSpeciesFrequencies.action.saveAndContinue.mnemonic"; - enabled: {model.getNextEditableRowIndex() != null && model.isValid()}; + enabled: {model.getNextEditableRowIndex() != null && model.isValid()};*/ _help: {"tutti.editSpeciesFrequencies.action.saveAndContinue.help"}; } +#saveAndCloseAction { + enabled: {model.isValid()}; +} + #saveAndCloseButton { - actionIcon: save; + action: {saveAndCloseAction}; + /*actionIcon: save; text: "tutti.editSpeciesFrequencies.action.saveAndClose"; toolTipText: "tutti.editSpeciesFrequencies.action.saveAndClose.tip"; i18nMnemonic: "tutti.editSpeciesFrequencies.action.saveAndClose.mnemonic"; - enabled: {model.isValid()}; + enabled: {model.isValid()};*/ _help: {"tutti.editSpeciesFrequencies.action.saveAndClose.help"}; } #resetButton { - actionIcon: reset; + action: {resetAction}; + /*actionIcon: reset; text: "tutti.editSpeciesFrequencies.action.reset"; toolTipText: "tutti.editSpeciesFrequencies.action.reset.tip"; - i18nMnemonic: "tutti.editSpeciesFrequencies.action.reset.mnemonic"; + i18nMnemonic: "tutti.editSpeciesFrequencies.action.reset.mnemonic";*/ _help: {"tutti.editSpeciesFrequencies.action.reset.help"}; } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.jaxx b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.jaxx index b0ffb8a..058784c 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.jaxx +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUI.jaxx @@ -19,8 +19,7 @@ <http://www.gnu.org/licenses/gpl-3.0.html>. #L% --> -<JPanel id='editSpeciesFrequenciesTopPanel' layout='{new BorderLayout()}' - decorator='help' +<JPanel id='editSpeciesFrequenciesTopPanel' layout='{new BorderLayout()}' decorator='help' implements='fr.ifremer.tutti.ui.swing.util.TuttiUI<SpeciesFrequencyUIModel, SpeciesFrequencyUIHandler>'> <import> @@ -28,6 +27,12 @@ fr.ifremer.tutti.ui.swing.TuttiHelpBroker fr.ifremer.tutti.ui.swing.content.operation.catches.FrequencyConfigurationMode + fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions.AddLengthStepCaracteristicAction + fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions.CancelAction + fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions.GenerateLengthStepsAction + fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions.ResetAction + fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions.SaveAndCloseAction + fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions.SaveAndContinueAction fr.ifremer.tutti.ui.swing.util.TuttiUI fr.ifremer.tutti.ui.swing.util.TuttiUIUtil fr.ifremer.tutti.ui.swing.util.computable.ComputableDataEditor @@ -37,7 +42,6 @@ jaxx.runtime.swing.editor.NumberEditor org.jdesktop.swingx.JXTable - org.jdesktop.swingx.JXMultiSplitPane javax.swing.ListSelectionModel javax.swing.SwingConstants @@ -55,8 +59,7 @@ public SpeciesFrequencyUI(TuttiUI parentUI) { } ]]></script> - <SpeciesFrequencyUIModel id='model' - initializer='getContextValue(SpeciesFrequencyUIModel.class)'/> + <SpeciesFrequencyUIModel id='model' initializer='getContextValue(SpeciesFrequencyUIModel.class)'/> <BeanValidator id='validator' bean='model' uiClass='jaxx.runtime.validator.swing.ui.ImageValidationUI'> @@ -67,17 +70,20 @@ public SpeciesFrequencyUI(TuttiUI parentUI) { <field name='totalWeight' component='totalWeightField'/> </BeanValidator> - <TuttiHelpBroker id='broker' - constructorParams='"tutti.editSpeciesFrequencies.help"'/> + <TuttiHelpBroker id='broker' constructorParams='"tutti.editSpeciesFrequencies.help"'/> - <CardLayout2Ext id='modeConfigurationLayout' - constructorParams='this, "modeConfigurationPanel"'/> + <CardLayout2Ext id='modeConfigurationLayout' constructorParams='this, "modeConfigurationPanel"'/> - <CardLayout2Ext id='dataFieldLayout' - constructorParams='this, "dataFieldPanel"'/> + <CardLayout2Ext id='dataFieldLayout' constructorParams='this, "dataFieldPanel"'/> - <JPanel id='configurationPanel' layout='{new BorderLayout()}' - constraints='BorderLayout.NORTH'> + <AddLengthStepCaracteristicAction id="addLengthStepCaracteristicAction" constructorParams="this"/> + <GenerateLengthStepsAction id="generateLengthStepsAction" constructorParams="this"/> + <CancelAction id="cancelAction" constructorParams="this"/> + <ResetAction id="resetAction" constructorParams="this"/> + <SaveAndCloseAction id="saveAndCloseAction" constructorParams="this"/> + <SaveAndContinueAction id="saveAndContinueAction" constructorParams="this"/> + + <JPanel id='configurationPanel' layout='{new BorderLayout()}' constraints='BorderLayout.NORTH'> <VBox id='modePanel' constraints='BorderLayout.WEST' verticalAlignment='{SwingConstants.CENTER}'> @@ -114,8 +120,7 @@ public SpeciesFrequencyUI(TuttiUI parentUI) { <row> <cell columns='2'> <JPanel layout='{new GridLayout(1, 0)}'> - <JButton id='generateButton' - onActionPerformed='handler.generateLengthSteps()'/> + <JButton id='generateButton'/> </JPanel> </cell> </row> @@ -131,21 +136,18 @@ public SpeciesFrequencyUI(TuttiUI parentUI) { </row> <row> <cell weightx='1.0'> - <NumberEditor id='rafaleStepField' - constructorParams='this'/> + <NumberEditor id='rafaleStepField' constructorParams='this'/> </cell> </row> </Table> </JPanel> <JPanel id='simpleCountingModePanel' constraints='"simpleCountingMode"' layout='{new BorderLayout()}'> - <JLabel id='simpleCountingModeLabel' - constraints='BorderLayout.CENTER'/> + <JLabel id='simpleCountingModeLabel' constraints='BorderLayout.CENTER'/> </JPanel> </JPanel> - <Table id="lengthstepSettingsBlock" fill='both' - constraints='BorderLayout.SOUTH'> + <Table id="lengthstepSettingsBlock" fill='both' constraints='BorderLayout.SOUTH'> <row> <cell columns='6'> <JSeparator/> @@ -162,9 +164,7 @@ public SpeciesFrequencyUI(TuttiUI parentUI) { constructorParams='this' genericType='Caracteristic' constraints='BorderLayout.CENTER'/> - <JButton id='addLengthStepCaracteristicButton' - onActionPerformed='handler.addLengthStepCaracteristic()' - constraints='BorderLayout.EAST'/> + <JButton id='addLengthStepCaracteristicButton' constraints='BorderLayout.EAST'/> </JPanel> </cell> </row> @@ -186,36 +186,31 @@ public SpeciesFrequencyUI(TuttiUI parentUI) { <JLabel id='totalWeightLabel'/> </cell> <cell weightx='1.0'> - <ComputableDataEditor id='totalWeightField' - genericType="Float" constructorParams='this'/> + <ComputableDataEditor id='totalWeightField' genericType="Float" constructorParams='this'/> </cell> </row> </Table> </JPanel> <JPanel id='dataFieldPanel' constraints='BorderLayout.CENTER'> - <JSplitPane constraints='"lengthCaracteristicPmfm"' - id="firstSplitPane"> + <JSplitPane constraints='"lengthCaracteristicPmfm"' id="firstSplitPane"> <JSplitPane id="secondSplitPane"> - <JScrollPane id='logsScrollPane' > + <JScrollPane id='logsScrollPane'> <JXTable id='logsTable'/> </JScrollPane> - <JScrollPane id='tableScrollPane' > + <JScrollPane id='tableScrollPane'> <JXTable id='table'/> </JScrollPane> </JSplitPane> - <JPanel id="histogramPanel" - layout="{new BorderLayout()}"> + <JPanel id="histogramPanel" layout="{new BorderLayout()}"> </JPanel> </JSplitPane> <Table constraints='"noLengthCaracteristicPmfm"' fill='horizontal'> <row> <cell columns='2'> - <JPanel id='dataInFrequenciesWarningContainer' - layout='{new BorderLayout(10, 10)}'> - <JLabel id='dataInFrequenciesWarning' - constraints='BorderLayout.CENTER'/> + <JPanel id='dataInFrequenciesWarningContainer' layout='{new BorderLayout(10, 10)}'> + <JLabel id='dataInFrequenciesWarning' constraints='BorderLayout.CENTER'/> </JPanel> </cell> </row> @@ -231,12 +226,11 @@ public SpeciesFrequencyUI(TuttiUI parentUI) { </JPanel> <!-- actions --> - <JPanel id='actionPanel' layout='{new GridLayout(1, 0)}' - constraints='BorderLayout.SOUTH'> - <JButton id='cancelButton' onActionPerformed='handler.cancel()'/> - <JButton id='resetButton' onActionPerformed='handler.reset()'/> - <JButton id='saveAndContinueButton' onActionPerformed='handler.saveAndContinue()'/> - <JButton id='saveAndCloseButton' onActionPerformed='handler.saveAndClose()'/> + <JPanel id='actionPanel' layout='{new GridLayout(1, 0)}' constraints='BorderLayout.SOUTH'> + <JButton id='cancelButton'/> + <JButton id='resetButton'/> + <JButton id='saveAndContinueButton'/> + <JButton id='saveAndCloseButton'/> </JPanel> </JPanel> diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java index 7de2882..397af8d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java @@ -24,7 +24,6 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import fr.ifremer.tutti.ichtyometer.feed.event.FeedReaderEvent; import fr.ifremer.tutti.ichtyometer.feed.event.FeedReaderListener; import fr.ifremer.tutti.ichtyometer.feed.record.FeedReaderMeasureRecord; @@ -38,16 +37,14 @@ import fr.ifremer.tutti.ui.swing.TuttiUIContext; import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUIHandler; import fr.ifremer.tutti.ui.swing.content.operation.catches.FrequencyConfigurationMode; -import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyRowModel; -import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUIModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.SpeciesBatchRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyCellComponent.FrequencyCellEditor; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions.ApplyRafaleAction; import fr.ifremer.tutti.ui.swing.util.TuttiBeanMonitor; import fr.ifremer.tutti.ui.swing.util.TuttiNumberTickUnitSource; import fr.ifremer.tutti.ui.swing.util.TuttiUI; import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil; import fr.ifremer.tutti.ui.swing.util.table.AbstractTuttiTableUIHandler; -import fr.ifremer.tutti.util.Numbers; import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox; import jaxx.runtime.validator.swing.SwingValidator; import org.apache.commons.collections4.CollectionUtils; @@ -63,18 +60,13 @@ import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberTickUnitSource; import org.jfree.chart.axis.ValueAxis; -import org.jfree.data.xy.XYSeries; -import org.jfree.data.xy.XYSeriesCollection; import org.nuiton.jaxx.application.ApplicationBusinessException; -import org.nuiton.jaxx.application.swing.util.Cancelable; import javax.swing.JComponent; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; -import javax.swing.table.TableColumn; import java.awt.BorderLayout; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -82,10 +74,8 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; -import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Set; import static org.nuiton.i18n.I18n.t; @@ -93,11 +83,10 @@ import static org.nuiton.i18n.I18n.t; * @author tchemit <chemit@codelutin.com> * @since 0.2 */ -public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<SpeciesFrequencyRowModel, SpeciesFrequencyUIModel, SpeciesFrequencyUI> implements Cancelable { +public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<SpeciesFrequencyRowModel, SpeciesFrequencyUIModel, SpeciesFrequencyUI> { /** Logger. */ - private static final Log log = - LogFactory.getLog(SpeciesFrequencyUIHandler.class); + private static final Log log = LogFactory.getLog(SpeciesFrequencyUIHandler.class); private FrequencyCellEditor frequencyEditor; @@ -105,8 +94,6 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci private Map<String, Caracteristic> lengthStepCaracteristics; - private XYSeriesCollection dataset; - private JFreeChart chart; /** @@ -121,6 +108,8 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci */ protected final FeedReaderListener feedReaderListener; + ApplyRafaleAction applyRafaleAction; + public SpeciesFrequencyUIHandler() { super(SpeciesFrequencyRowModel.PROPERTY_LENGTH_STEP, @@ -166,49 +155,27 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } @Override - protected boolean isRowValid(SpeciesFrequencyRowModel row) { - Float lengthStep = row.getLengthStep(); + public boolean isRowValid(SpeciesFrequencyRowModel row) { + SpeciesFrequencyUIModel model = getModel(); + boolean valid = model.isRowValid(row); + return valid; - return row.getLengthStepCaracteristic() != null && - lengthStep != null && lengthStep > 0 && - model.numberOfRows(lengthStep) == 1 && - ((row.getNumber() == null && row.getWeight() == null) || - (row.getNumber() != null && row.getNumber() > 0 && - (model.getNbRowsWithWeight() == 0 || row.getWeight() != null && row.getWeight() > 0))); } @Override protected void onModelRowsChanged(List<SpeciesFrequencyRowModel> rows) { - super.onModelRowsChanged(rows); SpeciesFrequencyUIModel model = getModel(); - model.setEmptyRows(Sets.<SpeciesFrequencyRowModel>newHashSet()); - model.resetNumbersOfRows(); - if (CollectionUtils.isNotEmpty(rows)) { - XYSeries series = dataset.getSeries(0); - series.clear(); + model.reloadRows(); - for (SpeciesFrequencyRowModel row : rows) { - model.updateRowWithWeight(row); + getTableModel().setRows(rows); - Float lengthStep = row.getLengthStep(); - if (lengthStep != null) { - model.incNumberOfRows(lengthStep); - } - } + // clean log table + SpeciesFrequencyLogsTableModel logsTableModel = (SpeciesFrequencyLogsTableModel) ui.getLogsTable().getModel(); + logsTableModel.setRows(Lists.<SpeciesFrequencyLogRowModel>newArrayList()); - for (SpeciesFrequencyRowModel row : rows) { - recomputeRowValidState(row); - - if (row.isValid()) { - Float lengthStep = row.getLengthStep(); - series.addOrUpdate(lengthStep, row.getNumber()); - } - } - } - model.recomputeTotalNumberAndWeight(); } @Override @@ -218,59 +185,9 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci Object oldValue, Object newValue) { - SpeciesFrequencyUIModel model = getModel(); - - // keep number of rows with weight - int nbRowsWithWeight = model.getNbRowsWithWeight(); - - // update rowWithWeight cache - model.updateRowWithWeight(row); - - boolean lengthStepModified = SpeciesFrequencyRowModel.PROPERTY_LENGTH_STEP.equals(propertyName); - boolean numberModified = BenthosFrequencyRowModel.PROPERTY_NUMBER.equals(propertyName); - - if (lengthStepModified) { - Float lengthStepToDec = (Float) oldValue; - if (lengthStepToDec != null) { - model.decNumberOfRows(lengthStepToDec); - } - - Float lengthStepToInc = (Float) newValue; - if (lengthStepToInc != null) { - model.incNumberOfRows(lengthStepToInc); - } - } - - // check if no row had a weight, then if one of them now has a weight, - // the other ones must have one too to be valid - // if the lengthstep changed, then recompute to check that there is not twice the same - boolean recomputeAllRows = nbRowsWithWeight != model.getNbRowsWithWeight() || lengthStepModified; - - if (recomputeAllRows) { - if (log.isInfoEnabled()) { - log.info("Revalidate all rows"); - } - for (SpeciesFrequencyRowModel r : model.getRows()) { - recomputeRowValidState(r); - } - getTable().repaint(); - } - - model.recomputeTotalNumberAndWeight(); - - if (!recomputeAllRows) { - if (log.isInfoEnabled()) { - log.info("Revalidate the single selected row"); - } - recomputeRowValidState(row); - } - - model.updateEmptyRow(row); - - if (lengthStepModified || numberModified) { - - getTableModel().recomputeCanEditLengthStep(); - } + // We do nothing here. This API works only on the selected row. + // On this screen, we can interacts with not selected row, so won't come here. + // Better then to work directly on rows in the table model } @@ -300,13 +217,13 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci @Override public void beforeInit(SpeciesFrequencyUI ui) { + this.applyRafaleAction = new ApplyRafaleAction(ui); + super.beforeInit(ui); this.weightUnit = getConfig().getSpeciesWeightUnit(); - SampleCategoryModel sampleCategoryModel = - getDataContext().getSampleCategoryModel(); - SpeciesFrequencyUIModel model = new SpeciesFrequencyUIModel( - weightUnit, sampleCategoryModel); + SampleCategoryModel sampleCategoryModel = getDataContext().getSampleCategoryModel(); + SpeciesFrequencyUIModel model = new SpeciesFrequencyUIModel(weightUnit, sampleCategoryModel); this.ui.setContextValue(model); @@ -321,6 +238,14 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci // listen when itchtyometer is connected and this ui is showing listenItchtyometer(); } + + SwingUtilities.invokeLater( + new Runnable() { + @Override + public void run() { + updateLogVisibility(); + } + }); } }); } @@ -366,7 +291,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci e.consume(); Float step = (Float) SpeciesFrequencyUIHandler.this.ui.getRafaleStepField().getModel(); - applyRafaleStep(step, false); + applyRafaleAction.applyRafaleStep(step, false); //select text JTextField field = (JTextField) e.getSource(); @@ -383,7 +308,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci // get step from the pmfm float step = getStep(newValue); getModel().setStep(step); - dataset.setIntervalWidth(step); + getModel().setDataSetIntervalWidth(step); chart.getXYPlot().getDomainAxis().setStandardTickUnits(new TuttiNumberTickUnitSource(step == 1f)); if (CollectionUtils.isNotEmpty(getModel().getRows())) { for (SpeciesFrequencyRowModel rowModel : getModel().getRows()) { @@ -424,7 +349,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci }); // when configuration mode change, let's focus the best component (see http://forge.codelutin.com/issues/4035) - model.addPropertyChangeListener(BenthosFrequencyUIModel.PROPERTY_CONFIGURATION_MODE, new PropertyChangeListener() { + model.addPropertyChangeListener(SpeciesFrequencyUIModel.PROPERTY_CONFIGURATION_MODE, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { final FrequencyConfigurationMode newValue = (FrequencyConfigurationMode) evt.getNewValue(); @@ -443,21 +368,46 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } }); - getContext().addPropertyChangeListener(TuttiUIContext.PROPERTY_ICHTYOMETER_CONNECTED, new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - SwingUtilities.invokeLater( - new Runnable() { - @Override - public void run() { - updateLogVisibility(); - } - }); - } - }); +// getContext().addPropertyChangeListener(TuttiUIContext.PROPERTY_ICHTYOMETER_CONNECTED, new PropertyChangeListener() { +// @Override +// public void propertyChange(PropertyChangeEvent evt) { +// SwingUtilities.invokeLater( +// new Runnable() { +// @Override +// public void run() { +// updateLogVisibility(); +// } +// }); +// } +// }); // init histogram - final XYSeries series = initHistogram(ui, model.getStep()); + + chart = ChartFactory.createXYBarChart(null, + t("tutti.editSpeciesFrequencies.table.header.lengthStep"), + false, + t("tutti.editSpeciesFrequencies.table.header.number"), + model.dataset); + chart.clearSubtitles(); + + ValueAxis rangeAxis = chart.getXYPlot().getRangeAxis(); + rangeAxis.setAutoRange(true); + rangeAxis.setStandardTickUnits(new NumberTickUnitSource(true)); + + ValueAxis domainAxis = chart.getXYPlot().getDomainAxis(); + domainAxis.setAutoRange(true); + domainAxis.setStandardTickUnits(new TuttiNumberTickUnitSource(true)); + domainAxis.setMinorTickMarksVisible(true); + + chart.getXYPlot().getRenderer().setSeriesPaint(0, getConfig().getColorComputedWeights()); + + final ChartPanel chartPanel = new ChartPanel(chart); + chartPanel.setDomainZoomable(false); + chartPanel.setMouseZoomable(false); + chartPanel.setPopupMenu(null); + + JPanel histogramPanel = ui.getHistogramPanel(); + histogramPanel.add(chartPanel, BorderLayout.CENTER); // init data table @@ -491,29 +441,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } // create table model - SpeciesFrequencyTableModel tableModel = - new SpeciesFrequencyTableModel( - weightUnit, - columnModel, - model, - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - SpeciesFrequencyRowModel row = (SpeciesFrequencyRowModel) evt.getSource(); - - if (SpeciesFrequencyRowModel.PROPERTY_LENGTH_STEP.equals(evt.getPropertyName())) { - Float oldValue = (Float) evt.getOldValue(); - if (oldValue != null && series.indexOf(oldValue) >= 0) { - series.remove(oldValue); - } - } - - Float lengthStep = row.getLengthStep(); - if (lengthStep != null) { - series.addOrUpdate(lengthStep, row.getNumber()); - } - } - }); + SpeciesFrequencyTableModel tableModel = new SpeciesFrequencyTableModel(weightUnit, columnModel, model); table.setModel(tableModel); table.setColumnModel(columnModel); @@ -522,9 +450,34 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci installTableKeyListener(columnModel, table); - initLogTable(ui); + // init log table + JXTable logTable = ui.getLogsTable(); - listenValidatorValid(this.ui.getValidator(), model); + // create log table column model + DefaultTableColumnModelExt logColumnModel = new DefaultTableColumnModelExt(); + + { // Date + addColumnToModel(logColumnModel, + SpeciesFrequencyLogCellComponent.newEditor(ui), + SpeciesFrequencyLogCellComponent.newRender(), + SpeciesFrequencyLogsTableModel.LABEL); + } + + // create log table model + SpeciesFrequencyLogsTableModel logTableModel = new SpeciesFrequencyLogsTableModel(logColumnModel); + logTableModel.setRows(new ArrayList<SpeciesFrequencyLogRowModel>()); + + logTable.setModel(logTableModel); + logTable.setColumnModel(logColumnModel); + + // by default do not authorize to change column orders + logTable.getTableHeader().setReorderingAllowed(false); + Highlighter evenHighlighter = TuttiUIUtil.newBackgroundColorHighlighter( + HighlightPredicate.ODD, + getConfig().getColorAlternateRow()); + logTable.addHighlighter(evenHighlighter); + + listenValidatorValid(ui.getValidator(), model); } @@ -563,165 +516,11 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } } - //------------------------------------------------------------------------// - //-- Cancelable methods --// - //------------------------------------------------------------------------// - - @Override - public void cancel() { - - if (log.isDebugEnabled()) { - log.debug("Cancel UI " + ui); - } - - // close dialog - closeUI(ui); - } - - //------------------------------------------------------------------------// - //-- Public methods --// - //------------------------------------------------------------------------// - - public void addLengthStepCaracteristic() { - - // compute list of possible caracteristics (all but the one in the select box) - List<Caracteristic> allNumericCaracteristic = getPersistenceService().getAllNumericCaracteristic(); - List<Caracteristic> toSelect = Lists.newArrayList(allNumericCaracteristic); - List<Caracteristic> knownCaracteristics = getUI().getLengthStepCaracteristicComboBox().getData(); - toSelect.removeAll(knownCaracteristics); - - // open a dialog to select it - - BeanFilterableComboBox<Caracteristic> editor = - new BeanFilterableComboBox<Caracteristic>(); - editor.setBeanType(Caracteristic.class); - editor.setShowReset(true); - - initBeanFilterableComboBox(editor, toSelect, null); - - int response = JOptionPane.showConfirmDialog( - getTopestUI(), - editor, - t("tutti.editSpeciesFrequencies.title.addLengthStepCaracteristic"), - JOptionPane.OK_CANCEL_OPTION); - - Caracteristic selectedItem; - if (response == JOptionPane.OK_OPTION) { - selectedItem = (Caracteristic) editor.getSelectedItem(); - -// // FIXME ? Should we add it to the combo box universe? -// ui.getLengthStepCaracteristicComboBox().getData().add(selectedItem); - } else { - // user cancel selection - selectedItem = null; - } - // set to model - getModel().setLengthStepCaracteristic(selectedItem); - } - - public void generateLengthSteps() { - - SpeciesFrequencyUIModel model = getModel(); - SpeciesFrequencyTableModel tableModel = getTableModel(); - - Map<Float, SpeciesFrequencyRowModel> rowsByStep = - getTableModel().getRowCache(); - - Float minStep = model.getLengthStep(model.getMinStep()); - Float maxStep = model.getLengthStep(model.getMaxStep()); - Caracteristic lengthStepCaracteristic = model.getLengthStepCaracteristic(); - - Set<Float> existingKeys = Sets.newHashSet(rowsByStep.keySet()); - List<SpeciesFrequencyRowModel> rows = Lists.newArrayList(rowsByStep.values()); - - for (float i = minStep, step = model.getStep(); i <= maxStep; - i = Numbers.getRoundedLengthStep(i + step, true)) { - - if (!existingKeys.contains(i)) { - - // add it - SpeciesFrequencyRowModel newRow = tableModel.createNewRow(); - newRow.setLengthStep(i); - newRow.setLengthStepCaracteristic(lengthStepCaracteristic); - rows.add(newRow); - } - } - Collections.sort(rows); - model.setRows(rows); - - // select first cell in table (see http://forge.codelutin.com/issues/2496) - TuttiUIUtil.doSelectCell(getUI().getTable(), 0, 1); - } - - public void applyRafaleStep(Float step, boolean fromIchtyometer) { - - if (log.isDebugEnabled()) { - log.debug("Will apply rafale step: " + step); - } - SpeciesFrequencyUIModel model = getModel(); - SpeciesFrequencyTableModel tableModel = getTableModel(); - - Map<Float, SpeciesFrequencyRowModel> rowsByStep = tableModel.getRowCache(); - - float aroundLengthStep = model.getLengthStep(step); - - SpeciesFrequencyRowModel row = rowsByStep.get(aroundLengthStep); - - int rowIndex; - - if (row != null) { - - // increments current row - Integer number = row.getNumber(); - row.setNumber((number == null ? 0 : number) + 1); - rowIndex = tableModel.updateRow(row); - - } else { - - // create a new row - - row = tableModel.createNewRow(); - row.setLengthStep(aroundLengthStep); - row.setNumber(1); - row.setValid(isRowValid(row)); - - // get new index - List<Float> steps = Lists.newArrayList(rowsByStep.keySet()); - steps.add(aroundLengthStep); - - Collections.sort(steps); - - rowIndex = steps.indexOf(aroundLengthStep); - - tableModel.addNewRow(rowIndex, row); - } - Integer totalNumber = model.getTotalNumber(); - if (totalNumber == null) { - totalNumber = 0; - } - model.setTotalNumber(totalNumber + 1); - - getTable().scrollRowToVisible(rowIndex); - - if (fromIchtyometer) { - String unit = model.getLengthStepCaracteristicUnit(); - showInformationMessage(t("tutti.editSpeciesFrequencies.addMeasure", step, aroundLengthStep, unit)); - } - - JXTable logsTable = getUI().getLogsTable(); - SpeciesFrequencyLogsTableModel logsTableModel = (SpeciesFrequencyLogsTableModel) logsTable.getModel(); - SpeciesFrequencyLogRowModel newRow = logsTableModel.createNewRow(); - newRow.setDate(new Date()); - newRow.setLengthStep(step); - logsTableModel.addNewRow(0, newRow); - } - public void editBatch(FrequencyCellEditor editor) { SpeciesBatchRowModel speciesBatch = editor.getEditRow(); SpeciesFrequencyUIModel model = getModel(); - model.clearWithWeightRows(); model.setNextEditableRowIndex(editor.getNextEditableRowIndex()); model.setTotalNumber(null); model.setTotalComputedWeight(null); @@ -735,7 +534,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci Caracteristic lengthStepCaracteristic = null; Float lengthStep; - List<SpeciesFrequencyRowModel> editFrequency = Lists.newArrayList(); + List<SpeciesFrequencyRowModel> rows = Lists.newArrayList(); if (speciesBatch != null) { @@ -751,12 +550,12 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci for (SpeciesFrequencyRowModel rowModel : frequency) { - SpeciesFrequencyRowModel newRow = tableModel.createNewRow(); + SpeciesFrequencyRowModel newRow = tableModel.createNewRow(false); newRow.setLengthStepCaracteristic(rowModel.getLengthStepCaracteristic()); newRow.setLengthStep(rowModel.getLengthStep()); newRow.setNumber(rowModel.getNumber()); newRow.setWeight(rowModel.getWeight()); - editFrequency.add(newRow); + rows.add(newRow); } // use first frequency row length step caracteristics @@ -773,21 +572,18 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } } - SpeciesBatchRowModel previousSiblingRow = - frequencyEditor.getPreviousSiblingRow(); + SpeciesBatchRowModel previousSiblingRow = frequencyEditor.getPreviousSiblingRow(); if (lengthStepCaracteristic == null && previousSiblingRow != null) { // try to get it from his previous brother row - List<SpeciesFrequencyRowModel> previousFrequency = - previousSiblingRow.getFrequency(); + List<SpeciesFrequencyRowModel> previousFrequency = previousSiblingRow.getFrequency(); if (CollectionUtils.isNotEmpty(previousFrequency)) { // use the first frequency length step caracteristic / step SpeciesFrequencyRowModel rowModel = previousFrequency.get(0); - lengthStepCaracteristic = - rowModel.getLengthStepCaracteristic(); + lengthStepCaracteristic = rowModel.getLengthStepCaracteristic(); lengthStep = rowModel.getLengthStep(); if (log.isInfoEnabled()) { log.info("Use previous sibling existing lengthStep " + @@ -802,16 +598,13 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci Species species = speciesBatch.getSpecies(); - SpeciesProtocol sProtocol = - speciesProtocol.get(species.getReferenceTaxonId()); + SpeciesProtocol sProtocol = speciesProtocol.get(species.getReferenceTaxonId()); if (sProtocol != null) { - String lengthStepPmfmId = sProtocol.getLengthStepPmfmId(); - lengthStepCaracteristic = - this.lengthStepCaracteristics.get(lengthStepPmfmId); + lengthStepCaracteristic = lengthStepCaracteristics.get(lengthStepPmfmId); lengthStep = sProtocol.getLengthStep(); if (log.isInfoEnabled()) { @@ -827,12 +620,12 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci // let's listen the ichtyometer listenItchtyometer(); + } } if (log.isDebugEnabled()) { - log.debug("Will edit batch row: " + speciesBatch + " with " + - editFrequency.size() + " frequency"); + log.debug("Will edit batch row: " + speciesBatch + " with " + rows.size() + " frequency"); } FrequencyConfigurationMode mode = FrequencyConfigurationMode.AUTO_GEN; @@ -844,7 +637,7 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } } Integer number = speciesBatch.getNumber(); - if (number != null && editFrequency.isEmpty()) { + if (number != null && rows.isEmpty()) { mode = FrequencyConfigurationMode.SIMPLE_COUNTING; model.setSimpleCount(number); } @@ -857,96 +650,14 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci // always sort row by their length // see http://forge.codelutin.com/issues/2482 - Collections.sort(editFrequency); + Collections.sort(rows); model.setLengthStepCaracteristic(lengthStepCaracteristic); - model.setRows(editFrequency); - -// // compute total number -// int totalNumber = model.computeTotalNumber(false); -// model.setTotalNumber(totalNumber); -// -// // compute total weight -// Float totalWeight = null; -// if (model.isAllRowsWithWeight()) { -// totalWeight = model.computeTotalWeight(false); -// } -// model.setTotalWeight(totalWeight); + model.setRows(rows); // keep batch (will be used to push back editing entry) model.setBatch(speciesBatch); - //remove log rows - SpeciesFrequencyLogsTableModel logsTableModel = (SpeciesFrequencyLogsTableModel) getUI().getLogsTable().getModel(); - logsTableModel.setRows(new ArrayList<SpeciesFrequencyLogRowModel>()); - } - - public void reset() { - - // remove all frequencies - getModel().setRows(Lists.<SpeciesFrequencyRowModel>newArrayList()); - - //remove log rows - SpeciesFrequencyLogsTableModel logsTableModel = (SpeciesFrequencyLogsTableModel) getUI().getLogsTable().getModel(); - logsTableModel.setRows(new ArrayList<SpeciesFrequencyLogRowModel>()); - } - - public void saveAndClose() { - - if (log.isDebugEnabled()) { - log.debug("Save And Close UI " + ui); - } - - boolean doSave = canSaveFrequencies(); - - if (doSave) { - frequencyEditor.save(getModel(), true); - - closeUI(ui); - } - } - - public void saveAndContinue() { - - if (log.isDebugEnabled()) { - log.debug("Save And Continue UI " + ui); - } - - boolean doSave = canSaveFrequencies(); - - if (doSave) { - frequencyEditor.save(getModel(), false); - } - } - - /** - * Decrement the frequency of the lengthstep of the row - * - * @param logRow - */ - public void decrementLengthStep(SpeciesFrequencyLogRowModel logRow) { - if (logRow != null) { - SpeciesFrequencyTableModel tableModel = getTableModel(); - SpeciesFrequencyRowModel speciesFrequencyRowModel = tableModel.getRowCache().get(logRow.getLengthStep()); - if (speciesFrequencyRowModel != null) { - Integer number = speciesFrequencyRowModel.getNumber(); - if (number != null) { - - if (number > 1) { - speciesFrequencyRowModel.setNumber(number - 1); - } else { - speciesFrequencyRowModel.setNumber(null); - } - - tableModel.fireTableDataChanged(); - } - tableModel.recomputeCanEditLengthStep(); - } - - SpeciesFrequencyLogsTableModel logsTableModel = (SpeciesFrequencyLogsTableModel) getUI().getLogsTable().getModel(); - int index = logsTableModel.getRowIndex(logRow); - logsTableModel.removeRow(index); - } } //------------------------------------------------------------------------// @@ -974,7 +685,8 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci } - applyRafaleStep(length, true); + applyRafaleAction.applyRafaleStep(length, true); + } else { throw new ApplicationBusinessException( t("tutti.editSpeciesFrequencies.error.itchyometer.bad.record", record.getRecord())); @@ -1025,74 +737,6 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci return componentToFocus; } - protected boolean canSaveFrequencies() { - boolean doSave = true; - - // check for doublon - // check that we do not have doublon in length - // see http://forge.codelutin.com/issues/2499 - Set<Float> lengths = Sets.newHashSet(); - - Float doublon = null; - int index = 0; - List<SpeciesFrequencyRowModel> rows = getModel().getRows(); - for (SpeciesFrequencyRowModel row : rows) { - Float lengthStep = row.getLengthStep(); - if (!lengths.add(lengthStep)) { - - // already exist - doublon = lengthStep; - break; - } - index++; - } - if (doublon != null) { - - // can't save mensurations (found doublon) - String message = - t("tutti.editSpeciesFrequencies.error.length.doublon", - doublon, index + 1); - getContext().getErrorHelper().showErrorDialog( - message); - - // focus to first error row - TuttiUIUtil.selectFirstCellOnRow(getTable(), index, false); - doSave = false; - } - - // ask user if there is some rows we can't save - // see http://forge.codelutin.com/issues/4046 - if (doSave && getModel().isSomeRowsWithWeightAndOtherWithout()) { - - // there is some rows with weight and other without - // ask user what to do - - String htmlMessage = String.format( - CONFIRMATION_FORMAT, - t("tutti.editSpeciesFrequencies.askBeforeSave.message"), - t("tutti.editSpeciesFrequencies.askBeforeSave.help")); - int answer = JOptionPane.showConfirmDialog( - getTopestUI(), - htmlMessage, - t("tutti.editSpeciesFrequencies.askBeforeSave.title"), - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE); - - switch (answer) { - case JOptionPane.YES_OPTION: - - // ok can save - break; - default: - - // do not save - doSave = false; - } - } - - return doSave; - } - protected float getStep(Caracteristic caracteristic) { Float precision = null; if (caracteristic != null) { @@ -1107,7 +751,6 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci protected void updateLogVisibility() { boolean logVisible = getModel().isRafaleMode() || getContext().isIchtyometerConnected(); - SpeciesFrequencyUI ui = getUI(); JSplitPane firstSplitPane = ui.getFirstSplitPane(); JSplitPane secondSplitPane = ui.getSecondSplitPane(); @@ -1121,70 +764,16 @@ public class SpeciesFrequencyUIHandler extends AbstractTuttiTableUIHandler<Speci ui.getLogsScrollPane().setVisible(logVisible); } - protected XYSeries initHistogram(SpeciesFrequencyUI ui, float step) { - final XYSeries series = new XYSeries("", true, false); - dataset = new XYSeriesCollection(series); - dataset.setIntervalPositionFactor(0); - dataset.setIntervalWidth(step); - - chart = ChartFactory.createXYBarChart(null, - t("tutti.editSpeciesFrequencies.table.header.lengthStep"), - false, - t("tutti.editSpeciesFrequencies.table.header.number"), - dataset); - chart.clearSubtitles(); - - ValueAxis rangeAxis = chart.getXYPlot().getRangeAxis(); - rangeAxis.setAutoRange(true); - rangeAxis.setStandardTickUnits(new NumberTickUnitSource(true)); - - ValueAxis domainAxis = chart.getXYPlot().getDomainAxis(); - domainAxis.setAutoRange(true); - domainAxis.setStandardTickUnits(new TuttiNumberTickUnitSource(true)); - domainAxis.setMinorTickMarksVisible(true); - - chart.getXYPlot().getRenderer().setSeriesPaint(0, getConfig().getColorComputedWeights()); - - final ChartPanel chartPanel = new ChartPanel(chart); - chartPanel.setDomainZoomable(false); - chartPanel.setMouseZoomable(false); - chartPanel.setPopupMenu(null); - - JPanel histogramPanel = ui.getHistogramPanel(); - histogramPanel.add(chartPanel, BorderLayout.CENTER); - return series; + protected String getLabelWithUnit(String label, String unit) { + return label + " (" + unit + ")"; } - protected void initLogTable(SpeciesFrequencyUI ui) { - JXTable logTable = ui.getLogsTable(); - - // create log table column model - DefaultTableColumnModelExt logColumnModel = new DefaultTableColumnModelExt(); - - { // Date - addColumnToModel(logColumnModel, - SpeciesFrequencyLogCellComponent.newEditor(this), - SpeciesFrequencyLogCellComponent.newRender(), - SpeciesFrequencyLogsTableModel.LABEL); - } - - // create log table model - SpeciesFrequencyLogsTableModel logTableModel = new SpeciesFrequencyLogsTableModel(logColumnModel); - logTableModel.setRows(new ArrayList<SpeciesFrequencyLogRowModel>()); - - logTable.setModel(logTableModel); - logTable.setColumnModel(logColumnModel); - - // by default do not authorize to change column orders - logTable.getTableHeader().setReorderingAllowed(false); - Highlighter evenHighlighter = TuttiUIUtil.newBackgroundColorHighlighter( - HighlightPredicate.ODD, -// Color.RED); - getConfig().getColorAlternateRow()); - logTable.addHighlighter(evenHighlighter); + @Override + public <E> void initBeanFilterableComboBox(BeanFilterableComboBox<E> comboBox, List<E> data, E selectedData) { + super.initBeanFilterableComboBox(comboBox, data, selectedData); } - protected String getLabelWithUnit(String label, String unit) { - return label + " (" + unit + ")"; + public FrequencyCellEditor getFrequencyEditor() { + return frequencyEditor; } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModel.java index 8d9b11d..d2899a2 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModel.java @@ -22,7 +22,6 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; * #L% */ -import com.google.common.base.Preconditions; import com.google.common.collect.Sets; import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; @@ -33,9 +32,11 @@ import fr.ifremer.tutti.ui.swing.util.computable.ComputableData; import fr.ifremer.tutti.ui.swing.util.table.AbstractTuttiTableUIModel; import fr.ifremer.tutti.util.Weights; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; -import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -45,6 +46,9 @@ import java.util.Set; */ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBatchRowModel, SpeciesFrequencyRowModel, SpeciesFrequencyUIModel> { + /** Logger. */ + private static final Log log = LogFactory.getLog(SpeciesFrequencyUIModel.class); + private static final long serialVersionUID = 1L; public static final String PROPERTY_BATCH = "batch"; @@ -172,34 +176,102 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa protected final WeightUnit weightUnit; /** - * Rows with a filled weight. + * To store all caches used by the screen * - * @since 3.0 + * @since 3.11 */ - protected Set<SpeciesFrequencyRowModel> withWeightRows = Sets.newHashSet(); + protected final SpeciesFrequencyUIModelCache cache = new SpeciesFrequencyUIModelCache(); /** - * Number of rows for each lengthstep + * Can edit length step? (only if no row is filled). + * see https://forge.codelutin.com/issues/5694 * - * @since 3.10 + * @since 3.11 */ - protected Map<Integer, MutableInt> nbOfRowsByLengthStep = new HashMap<Integer, MutableInt>(); + protected boolean canEditLengthStep = true; /** - * Can edit length step? (only if no row is filled). - * see https://forge.codelutin.com/issues/5694 + * To store graph series. * * @since 3.11 */ - protected boolean canEditLengthStep = true; + protected final XYSeriesCollection dataset; - public SpeciesFrequencyUIModel(WeightUnit weightUnit, - SampleCategoryModel sampleCategoryModel) { + public SpeciesFrequencyUIModel(WeightUnit weightUnit, SampleCategoryModel sampleCategoryModel) { super(SpeciesBatchRowModel.class, null, null); this.weightUnit = weightUnit; this.sampleCategoryModel = sampleCategoryModel; this.totalComputedOrNotWeight.addPropagateListener(PROPERTY_TOTAL_WEIGHT, this); setEmptyRows(Sets.<SpeciesFrequencyRowModel>newHashSet()); + + XYSeries series = new XYSeries("", true, false); + + dataset = new XYSeriesCollection(series); + dataset.setIntervalPositionFactor(0); + dataset.setIntervalWidth(step); + } + + public void reloadRows() { + + setEmptyRows(Sets.<SpeciesFrequencyRowModel>newHashSet()); + + XYSeries series = dataset.getSeries(0); + series.clear(); + + cache.loadCache(rows); + + recomputeRowsValidateState(); + + if (rows != null) { + + for (SpeciesFrequencyRowModel row : rows) { + + if (row.isValid()) { + + Float lengthStep = row.getLengthStep(); + series.addOrUpdate(lengthStep, row.getNumber()); + + } + + } + + } + + recomputeTotalNumberAndWeight(); + + } + + public boolean isRowValid(SpeciesFrequencyRowModel row) { + + // lengthStepCaracteristic conditions : not null + boolean valid = row.getLengthStepCaracteristic() != null; + + if (valid) { + + // lengthStep conditions : not null and positive + not found in more than one row + Float lengthStep = row.getLengthStep(); + valid = lengthStep != null + && lengthStep > 0 + && numberOfRows(lengthStep) < 2; + } + + if (valid) { + + // number conditions : not null and positive number + Integer number = row.getNumber(); + valid = number != null && number > 0; + + } + + if (valid) { + + // weight conditions + Float weight = row.getWeight(); + valid = getNbRowsWithWeight() == 0 || (weight != null && weight > 0); + + } + + return valid; } @Override @@ -207,12 +279,6 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa return new SpeciesBatchRowModel(weightUnit, sampleCategoryModel); } -// @Override -// public void setRows(List<SpeciesFrequencyRowModel> rows) { -// super.setRows(rows); -// setEmptyRows(Sets.<SpeciesFrequencyRowModel>newHashSet()); -// } - public FrequencyConfigurationMode getConfigurationMode() { return configurationMode; } @@ -397,16 +463,12 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa firePropertyChange(PROPERTY_EMPTY_ROWS, null, emptyRows); } - public void clearWithWeightRows() { - withWeightRows.clear(); - } - public int getNbRowsWithWeight() { - return withWeightRows.size(); + return cache.getNbRowsWithWeight(); } public boolean isAllRowsWithWeight() { - return withWeightRows.size() == rows.size(); + return cache.getNbRowsWithWeight() == rows.size(); } public boolean isSomeRowsWithWeightAndOtherWithout() { @@ -429,7 +491,7 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa if (row.isEmpty()) { - // no value on rows, no chekc on it + // no value on rows, no check on it continue; } @@ -451,15 +513,6 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa } - public void updateRowWithWeight(SpeciesFrequencyRowModel row) { - - if (row.getWeight() == null) { - withWeightRows.remove(row); - } else { - withWeightRows.add(row); - } - } - public void updateEmptyRow(SpeciesFrequencyRowModel row) { if (row.isValid() && row.getNumber() == null && row.getWeight() == null) { emptyRows.add(row); @@ -469,17 +522,6 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa firePropertyChange(PROPERTY_EMPTY_ROWS, null, emptyRows); } - public Float computeTotalWeight() { - float result = 0f; - for (SpeciesFrequencyRowModel row : withWeightRows) { - if (!row.isValid()) { - continue; - } - result += row.getWeight(); - } - return result; - } - public int computeTotalNumber() { int result = 0; if (rows != null) { @@ -496,50 +538,76 @@ public class SpeciesFrequencyUIModel extends AbstractTuttiTableUIModel<SpeciesBa } public void recomputeTotalNumberAndWeight() { - int totalNumber = computeTotalNumber(); - Float totalWeight = computeTotalWeight(); - setTotalNumber(totalNumber); - setTotalComputedWeight(totalWeight); + + int computeTotalNumber = computeTotalNumber(); + Float computeTotalWeight = cache.computeTotalWeight(); + setTotalNumber(computeTotalNumber); + setTotalComputedWeight(computeTotalWeight); + } - public int numberOfRows(float lengthStep) { - //convert the lengthstep into millimeter to avoid float inprecision in map equality - int mmLengthStep = Math.round(lengthStep * 10); - int result = 0; - MutableInt mutableInt = nbOfRowsByLengthStep.get(mmLengthStep); - if (mutableInt != null) { - result = mutableInt.intValue(); + public void recomputeCanEditLengthStep() { + + boolean result = true; + + for (SpeciesFrequencyRowModel row : rows) { + + if (row.isEmpty()) { + // la ligne est vide + continue; + } + if (row.getLengthStep() == null || row.getNumber() == null) { + // la ligne n'est pas complete + continue; + } + + // une ligne non vide et complete a ete trouvee + // on ne peut plus editer + result = false; + } - return result; + + setCanEditLengthStep(result); + } - public void resetNumbersOfRows() { - nbOfRowsByLengthStep = new HashMap<Integer, MutableInt>(); + public int numberOfRows(float lengthStep) { + return cache.numberOfRows(lengthStep); + } + + public Map<Float, SpeciesFrequencyRowModel> getRowCache() { + return cache.getRowCache(); } - public int incNumberOfRows(float lengthStep) { - //convert the lengthstep into millimeter to avoid float inprecision in map equality - int mmLengthStep = Math.round(lengthStep * 10); - MutableInt mutableInt = nbOfRowsByLengthStep.get(mmLengthStep); - if (mutableInt == null) { - mutableInt = new MutableInt(1); - nbOfRowsByLengthStep.put(mmLengthStep, mutableInt); + protected final void recomputeRowValidState(SpeciesFrequencyRowModel row) { + // recompute row valid state + boolean valid = isRowValid(row); + + // apply it to row + row.setValid(valid); + + if (valid) { + removeRowInError(row); } else { - mutableInt.increment(); + addRowInError(row); } - return mutableInt.intValue(); + } - public int decNumberOfRows(float lengthStep) { - //convert the lengthstep into millimeter to avoid float inprecision in map equality - int mmLengthStep = Math.round(lengthStep * 10); + public void recomputeRowsValidateState() { + + if (log.isInfoEnabled()) { + log.info("Revalidate all rows"); + } + + for (SpeciesFrequencyRowModel r : rows) { + recomputeRowValidState(r); + } - MutableInt mutableInt = nbOfRowsByLengthStep.get(mmLengthStep); - Preconditions.checkNotNull(mutableInt); - Preconditions.checkArgument(mutableInt.intValue() > 0); - mutableInt.decrement(); - return mutableInt.intValue(); } + public void setDataSetIntervalWidth(float step) { + dataset.setIntervalWidth(step); + } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModelCache.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModelCache.java new file mode 100644 index 0000000..5001d57 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIModelCache.java @@ -0,0 +1,134 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency; + +import com.google.common.collect.Sets; +import org.apache.commons.lang3.mutable.MutableInt; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Put here all possible caches used by model. + * + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class SpeciesFrequencyUIModelCache implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Rows with a filled weight. + * + * @since 3.0 + */ + protected final Set<SpeciesFrequencyRowModel> withWeightRows = Sets.newHashSet(); + + /** + * Number of rows for each lengthstep (keys are a round value (*10) of the real float step, values are number of such steps. + * + * The cache is used to check if there is no a doublon of step in the rows. + * + * @since 3.10 + */ + protected final Map<Integer, MutableInt> nbOfRowsByLengthStep = new TreeMap<Integer, MutableInt>(); + + private final Map<Float, SpeciesFrequencyRowModel> rowCache = new TreeMap<Float, SpeciesFrequencyRowModel>(); + + public void loadCache(List<SpeciesFrequencyRowModel> rows) { + + withWeightRows.clear(); + nbOfRowsByLengthStep.clear(); + rowCache.clear(); + + for (SpeciesFrequencyRowModel row : rows) { + + Float lengthStep = row.getLengthStep(); + if (lengthStep != null) { + rowCache.put(lengthStep, row); + incNumberOfRows(lengthStep); + } + + updateRowWithWeight(row); + + } + + } + + public void updateRowWithWeight(SpeciesFrequencyRowModel row) { + + if (row.getWeight() == null) { + withWeightRows.remove(row); + } else { + withWeightRows.add(row); + } + } + + public int getNbRowsWithWeight() { + return withWeightRows.size(); + } + + public int numberOfRows(float lengthStep) { + MutableInt mutableInt = getNbRowsByLengthStep(lengthStep); + int result = mutableInt.intValue(); + return result; + } + + public void incNumberOfRows(float lengthStep) { + MutableInt mutableInt = getNbRowsByLengthStep(lengthStep); + mutableInt.increment(); + } + + public void decNumberOfRows(float lengthStep) { + MutableInt mutableInt = getNbRowsByLengthStep(lengthStep); + mutableInt.decrement(); + } + + protected MutableInt getNbRowsByLengthStep(float lengthStep) { + + //convert the lengthStep into millimeter to avoid float inprecision in map equality + int mmLengthStep = Math.round(lengthStep * 10); + MutableInt mutableInt = nbOfRowsByLengthStep.get(mmLengthStep); + if (mutableInt == null) { + mutableInt = new MutableInt(0); + nbOfRowsByLengthStep.put(mmLengthStep, mutableInt); + } + return mutableInt; + + } + + public void addLengthStep(SpeciesFrequencyRowModel row) { + + Float lengthStep = row.getLengthStep(); + rowCache.put(lengthStep, row); + incNumberOfRows(lengthStep); + + } + + public void removeLengthStep(Float oldValue) { + + rowCache.remove(oldValue); + decNumberOfRows(oldValue); + + } + + public Map<Float, SpeciesFrequencyRowModel> getRowCache() { + return rowCache; + } + + + public Float computeTotalWeight() { + float result = 0f; + for (SpeciesFrequencyRowModel row : withWeightRows) { + if (!row.isValid()) { + continue; + } + result += row.getWeight(); + } + return result; + } +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/AddLengthStepCaracteristicAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/AddLengthStepCaracteristicAction.java new file mode 100644 index 0000000..8576a5e --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/AddLengthStepCaracteristicAction.java @@ -0,0 +1,75 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import com.google.common.collect.Lists; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import jaxx.runtime.SwingUtil; +import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox; + +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; +import java.awt.event.ActionEvent; +import java.util.List; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class AddLengthStepCaracteristicAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final SpeciesFrequencyUI ui; + + public AddLengthStepCaracteristicAction(SpeciesFrequencyUI ui) { + this.ui = ui; + + putValue(NAME, t("tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic")); + putValue(SHORT_DESCRIPTION, t("tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editSpeciesFrequencies.action.addLengthStepCaracteristic.mnemonic"), 'Z')); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + // compute list of possible caracteristics (all but the one in the select box) + List<Caracteristic> allNumericCaracteristic = ui.getHandler().getPersistenceService().getAllNumericCaracteristic(); + List<Caracteristic> toSelect = Lists.newArrayList(allNumericCaracteristic); + List<Caracteristic> knownCaracteristics = ui.getLengthStepCaracteristicComboBox().getData(); + toSelect.removeAll(knownCaracteristics); + + // open a dialog to select it + + BeanFilterableComboBox<Caracteristic> editor = new BeanFilterableComboBox<Caracteristic>(); + editor.setBeanType(Caracteristic.class); + editor.setShowReset(true); + + ui.getHandler().initBeanFilterableComboBox(editor, toSelect, null); + + int response = JOptionPane.showConfirmDialog( + ui.getHandler().getTopestUI(), + editor, + t("tutti.editSpeciesFrequencies.title.addLengthStepCaracteristic"), + JOptionPane.OK_CANCEL_OPTION); + + Caracteristic selectedItem; + if (response == JOptionPane.OK_OPTION) { + selectedItem = (Caracteristic) editor.getSelectedItem(); + +// // FIXME ? Should we add it to the combo box universe? +// ui.getLengthStepCaracteristicComboBox().getData().add(selectedItem); + } else { + // user cancel selection + selectedItem = null; + } + // set to model + ui.getModel().setLengthStepCaracteristic(selectedItem); + + } + +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ApplyRafaleAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ApplyRafaleAction.java new file mode 100644 index 0000000..1d5f74d --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ApplyRafaleAction.java @@ -0,0 +1,106 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import com.google.common.collect.Lists; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyLogRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyLogsTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIHandler; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIModel; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.swingx.JXTable; + +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class ApplyRafaleAction { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ApplyRafaleAction.class); + + private final SpeciesFrequencyUI ui; + + public ApplyRafaleAction(SpeciesFrequencyUI ui) { + this.ui = ui; + } + + public void applyRafaleStep(Float step, boolean fromIchtyometer) { + + if (log.isDebugEnabled()) { + log.debug("Will apply rafale step: " + step); + } + SpeciesFrequencyUIModel model = ui.getModel(); + SpeciesFrequencyUIHandler handler = ui.getHandler(); + + SpeciesFrequencyTableModel tableModel = handler.getTableModel(); + + Map<Float, SpeciesFrequencyRowModel> rowsByStep = model.getRowCache(); + + float aroundLengthStep = model.getLengthStep(step); + + SpeciesFrequencyRowModel row = rowsByStep.get(aroundLengthStep); + + int rowIndex; + + if (row != null) { + + // increments current row + Integer number = row.getNumber(); + row.setNumber((number == null ? 0 : number) + 1); + rowIndex = tableModel.updateRow(row); + + } else { + + // create a new row + + row = tableModel.createNewRow(); + row.setLengthStep(aroundLengthStep); + row.setNumber(1); + row.setValid(handler.isRowValid(row)); + + // get new index + List<Float> steps = Lists.newArrayList(rowsByStep.keySet()); + steps.add(aroundLengthStep); + + Collections.sort(steps); + + rowIndex = steps.indexOf(aroundLengthStep); + + tableModel.addNewRow(rowIndex, row); + } + + Integer totalNumber = model.getTotalNumber(); + if (totalNumber == null) { + totalNumber = 0; + } + model.setTotalNumber(totalNumber + 1); + + ui.getTable().scrollRowToVisible(rowIndex); + + if (fromIchtyometer) { + String unit = model.getLengthStepCaracteristicUnit(); + handler.showInformationMessage(t("tutti.editSpeciesFrequencies.addMeasure", step, aroundLengthStep, unit)); + } + + JXTable logsTable = ui.getLogsTable(); + SpeciesFrequencyLogsTableModel logsTableModel = (SpeciesFrequencyLogsTableModel) logsTable.getModel(); + SpeciesFrequencyLogRowModel newRow = logsTableModel.createNewRow(); + newRow.setDate(new Date()); + newRow.setLengthStep(step); + logsTableModel.addNewRow(0, newRow); + + } + +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/CancelAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/CancelAction.java new file mode 100644 index 0000000..a25142c --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/CancelAction.java @@ -0,0 +1,49 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import jaxx.runtime.SwingUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.AbstractAction; +import java.awt.event.ActionEvent; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class CancelAction extends AbstractAction { + + /** Logger. */ + private static final Log log = LogFactory.getLog(CancelAction.class); + + private static final long serialVersionUID = 1L; + + final SpeciesFrequencyUI ui; + + public CancelAction(SpeciesFrequencyUI ui) { + this.ui = ui; + + putValue(NAME, t("tutti.editSpeciesFrequencies.action.cancel")); + putValue(SHORT_DESCRIPTION, t("tutti.editSpeciesFrequencies.action.cancel.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editSpeciesFrequencies.action.cancel.mnemonic"), 'Z')); + putValue(SMALL_ICON, SwingUtil.createActionIcon("cancel")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + if (log.isDebugEnabled()) { + log.debug("Cancel UI " + ui); + } + + // close dialog + ui.getHandler().onCloseUI(); + + } +} \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/DeleteLogRowAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/DeleteLogRowAction.java new file mode 100644 index 0000000..bfe9821 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/DeleteLogRowAction.java @@ -0,0 +1,70 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyLogCellComponent; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyLogRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyLogsTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIHandler; +import jaxx.runtime.SwingUtil; + +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; +import java.awt.event.ActionEvent; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class DeleteLogRowAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final SpeciesFrequencyUI ui; + + private final SpeciesFrequencyLogCellComponent.FrequencyLogCellEditor component; + + public DeleteLogRowAction(SpeciesFrequencyUI ui, SpeciesFrequencyLogCellComponent.FrequencyLogCellEditor component) { + + this.ui = ui; + this.component = component; + putValue(SMALL_ICON, SwingUtil.createActionIcon("delete")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + SpeciesFrequencyLogRowModel row = component.getRow(); + + if (row != null) { + + SpeciesFrequencyUIHandler handler = ui.getHandler(); + + int i = JOptionPane.showConfirmDialog( + handler.getTopestUI(), + t("tutti.editSpeciesFrequencies.logTable.removeRow.confirm.message", row.getLabel()), + t("tutti.editSpeciesFrequencies.logTable.removeRow.confirm.title"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (i == JOptionPane.YES_OPTION) { + + SpeciesFrequencyTableModel tableModel = handler.getTableModel(); + tableModel.decrementNumberForLengthStep(row.getLengthStep()); + + SpeciesFrequencyLogsTableModel logsTableModel = (SpeciesFrequencyLogsTableModel) ui.getLogsTable().getModel(); + int index = logsTableModel.getRowIndex(row); + logsTableModel.removeRow(index); + + } + + } + + } + +} \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/GenerateLengthStepsAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/GenerateLengthStepsAction.java new file mode 100644 index 0000000..baa3bd8 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/GenerateLengthStepsAction.java @@ -0,0 +1,78 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIModel; +import fr.ifremer.tutti.util.Numbers; +import jaxx.runtime.SwingUtil; +import jaxx.runtime.swing.JTables; + +import javax.swing.AbstractAction; +import java.awt.event.ActionEvent; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class GenerateLengthStepsAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final SpeciesFrequencyUI ui; + + public GenerateLengthStepsAction(SpeciesFrequencyUI ui) { + this.ui = ui; + + putValue(NAME, t("tutti.editSpeciesFrequencies.action.generate")); + putValue(SHORT_DESCRIPTION, t("tutti.editSpeciesFrequencies.action.generate.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editSpeciesFrequencies.action.generate.mnemonic"), 'Z')); + putValue(SMALL_ICON, SwingUtil.createActionIcon("generate")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + SpeciesFrequencyUIModel model = ui.getModel(); + SpeciesFrequencyTableModel tableModel = ui.getHandler().getTableModel(); + + Map<Float, SpeciesFrequencyRowModel> rowsByStep = model.getRowCache(); + + Float minStep = model.getLengthStep(model.getMinStep()); + Float maxStep = model.getLengthStep(model.getMaxStep()); + Caracteristic lengthStepCaracteristic = model.getLengthStepCaracteristic(); + + Set<Float> existingKeys = Sets.newHashSet(rowsByStep.keySet()); + List<SpeciesFrequencyRowModel> rows = Lists.newArrayList(rowsByStep.values()); + + for (float i = minStep, step = model.getStep(); i <= maxStep; i = Numbers.getRoundedLengthStep(i + step, true)) { + + if (!existingKeys.contains(i)) { + + // add it + SpeciesFrequencyRowModel newRow = tableModel.createNewRow(); + newRow.setLengthStep(i); + newRow.setLengthStepCaracteristic(lengthStepCaracteristic); + rows.add(newRow); + } + } + Collections.sort(rows); + model.setRows(rows); + + // select first cell in table (see http://forge.codelutin.com/issues/2496) + JTables.doSelectCell(ui.getTable(), 0, 1); + + } +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ResetAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ResetAction.java new file mode 100644 index 0000000..a25a4f3 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/ResetAction.java @@ -0,0 +1,43 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import com.google.common.collect.Lists; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import jaxx.runtime.SwingUtil; + +import javax.swing.AbstractAction; +import java.awt.event.ActionEvent; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class ResetAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final SpeciesFrequencyUI ui; + + public ResetAction(SpeciesFrequencyUI ui) { + + this.ui = ui; + + putValue(NAME, t("tutti.editSpeciesFrequencies.action.reset")); + putValue(SHORT_DESCRIPTION, t("tutti.editSpeciesFrequencies.action.reset.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editSpeciesFrequencies.action.reset.mnemonic"), 'Z')); + putValue(SMALL_ICON, SwingUtil.createActionIcon("reset")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + // remove all frequencies + ui.getModel().setRows(Lists.<SpeciesFrequencyRowModel>newArrayList()); + + } +} \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveAndCloseAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveAndCloseAction.java new file mode 100644 index 0000000..187078b --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveAndCloseAction.java @@ -0,0 +1,55 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIHandler; +import jaxx.runtime.SwingUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.awt.event.ActionEvent; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class SaveAndCloseAction extends SaveSupportAction { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SaveAndCloseAction.class); + + private static final long serialVersionUID = 1L; + + public SaveAndCloseAction(SpeciesFrequencyUI ui) { + super(ui); + + putValue(NAME, t("tutti.editSpeciesFrequencies.action.saveAndClose")); + putValue(SHORT_DESCRIPTION, t("tutti.editSpeciesFrequencies.action.saveAndClose.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editSpeciesFrequencies.action.saveAndClose.mnemonic"), 'Z')); + putValue(SMALL_ICON, SwingUtil.createActionIcon("save")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + if (log.isDebugEnabled()) { + log.debug("Save And Close UI " + ui); + } + + boolean doSave = canSaveFrequencies(); + + if (doSave) { + + SpeciesFrequencyUIHandler handler = ui.getHandler(); + handler.getFrequencyEditor().save(ui.getModel(), true); + handler.onCloseUI(); + + } + + } + +} \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveAndContinueAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveAndContinueAction.java new file mode 100644 index 0000000..4ae45c8 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveAndContinueAction.java @@ -0,0 +1,49 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import jaxx.runtime.SwingUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.awt.event.ActionEvent; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public class SaveAndContinueAction extends SaveSupportAction { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SaveAndContinueAction.class); + + private static final long serialVersionUID = 1L; + + public SaveAndContinueAction(SpeciesFrequencyUI ui) { + super(ui); + + putValue(NAME, t("tutti.editSpeciesFrequencies.action.saveAndContinue")); + putValue(SHORT_DESCRIPTION, t("tutti.editSpeciesFrequencies.action.saveAndContinue.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editSpeciesFrequencies.action.saveAndContinue.mnemonic"), 'Z')); + putValue(SMALL_ICON, SwingUtil.createActionIcon("save")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + if (log.isDebugEnabled()) { + log.debug("Save And Continue UI " + ui); + } + + boolean doSave = canSaveFrequencies(); + + if (doSave) { + ui.getHandler().getFrequencyEditor().save(ui.getModel(), false); + } + + } +} \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveSupportAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveSupportAction.java new file mode 100644 index 0000000..be77d15 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/actions/SaveSupportAction.java @@ -0,0 +1,105 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.actions; + +import com.google.common.collect.Sets; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIHandler; +import fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency.SpeciesFrequencyUIModel; +import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil; +import org.nuiton.jaxx.application.swing.AbstractApplicationUIHandler; + +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; +import java.util.List; +import java.util.Set; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 1/1/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.11 + */ +public abstract class SaveSupportAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final SpeciesFrequencyUI ui; + + public SaveSupportAction(SpeciesFrequencyUI ui) { + this.ui = ui; + } + + protected boolean canSaveFrequencies() { + boolean doSave = true; + + SpeciesFrequencyUIModel model = ui.getModel(); + + // check for doublon + // check that we do not have doublon in length + // see http://forge.codelutin.com/issues/2499 + Set<Float> lengths = Sets.newHashSet(); + + Float doublon = null; + int index = 0; + List<SpeciesFrequencyRowModel> rows = model.getRows(); + for (SpeciesFrequencyRowModel row : rows) { + Float lengthStep = row.getLengthStep(); + if (!lengths.add(lengthStep)) { + + // already exist + doublon = lengthStep; + break; + } + index++; + } + SpeciesFrequencyUIHandler handler = ui.getHandler(); + + if (doublon != null) { + + // can't save mensurations (found doublon) + String message = + t("tutti.editSpeciesFrequencies.error.length.doublon", + doublon, index + 1); + handler.getContext().getErrorHelper().showErrorDialog( + message); + + // focus to first error row + TuttiUIUtil.selectFirstCellOnRow(ui.getTable(), index, false); + doSave = false; + } + + // ask user if there is some rows we can't save + // see http://forge.codelutin.com/issues/4046 + if (doSave && model.isSomeRowsWithWeightAndOtherWithout()) { + + // there is some rows with weight and other without + // ask user what to do + + String htmlMessage = String.format( + AbstractApplicationUIHandler.CONFIRMATION_FORMAT, + t("tutti.editSpeciesFrequencies.askBeforeSave.message"), + t("tutti.editSpeciesFrequencies.askBeforeSave.help")); + int answer = JOptionPane.showConfirmDialog( + handler.getTopestUI(), + htmlMessage, + t("tutti.editSpeciesFrequencies.askBeforeSave.title"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + switch (answer) { + case JOptionPane.YES_OPTION: + + // ok can save + break; + default: + + // do not save + doSave = false; + } + } + + return doSave; + } +} \ No newline at end of file -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.