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 ac45b230e09d8d2ad4a1db7b27d9ab3aace5895e Author: Tony CHEMIT <chemit@codelutin.com> Date: Thu Jan 1 15:59:03 2015 +0100 remise a plat de l'ecran BenthosFrequency --- .../frequency/BenthosFrequencyCellComponent.java | 10 +- .../BenthosFrequencyLogCellComponent.java | 82 ++- .../frequency/BenthosFrequencyLogRowModel.java | 3 + .../frequency/BenthosFrequencyRowModel.java | 2 +- .../frequency/BenthosFrequencyTableModel.java | 283 +++++++--- .../benthos/frequency/BenthosFrequencyUI.css | 44 +- .../benthos/frequency/BenthosFrequencyUI.jaxx | 203 ++++--- .../frequency/BenthosFrequencyUIHandler.java | 603 ++++----------------- .../benthos/frequency/BenthosFrequencyUIModel.java | 217 +++++--- .../frequency/BenthosFrequencyUIModelCache.java | 133 +++++ ...thosFrequencyLengthStepCaracteristicAction.java | 75 +++ .../actions/ApplyBenthosFrequencyRafaleAction.java | 106 ++++ .../actions/CancelEditBenthosFrequencyAction.java | 49 ++ .../DeleteBenthosFrequencyLogRowAction.java | 70 +++ .../GenerateBenthosFrequencyLengthStepsAction.java | 78 +++ .../actions/ResetBenthosFrequencyAction.java | 43 ++ .../SaveAndCloseBenthosFrequencyAction.java | 55 ++ .../SaveAndContinueBenthosFrequencyAction.java | 49 ++ .../frequency/actions/SaveSupportAction.java | 105 ++++ .../resources/i18n/tutti-ui-swing_en_GB.properties | 4 + .../resources/i18n/tutti-ui-swing_fr_FR.properties | 6 + 21 files changed, 1386 insertions(+), 834 deletions(-) diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyCellComponent.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyCellComponent.java index 2f4df26..dad0276 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyCellComponent.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyCellComponent.java @@ -24,16 +24,16 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; -import fr.ifremer.tutti.ui.swing.util.computable.ComputableData; -import org.nuiton.jaxx.application.swing.table.ColumnIdentifier; import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.BenthosBatchRowModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.BenthosBatchTableModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.BenthosBatchUI; -import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil; +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 BenthosFrequencyCellComponent 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 BenthosFrequencyCellComponent 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/benthos/frequency/BenthosFrequencyLogCellComponent.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyLogCellComponent.java index 8dc9ad5..9e227d4 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyLogCellComponent.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyLogCellComponent.java @@ -22,20 +22,23 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency; * #L% */ +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions.DeleteBenthosFrequencyLogRowAction; import jaxx.runtime.swing.JAXXWidgetUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import javax.swing.*; +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.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; import java.io.Serializable; -import static org.nuiton.i18n.I18n.t; - /** * Component to render and delete log items from logs table. * @@ -46,16 +49,9 @@ public class BenthosFrequencyLogCellComponent extends JPanel implements Serializ private static final long serialVersionUID = 1L; - /** Logger. */ - private static final Log log = LogFactory.getLog(BenthosFrequencyLogCellComponent.class); - private JLabel label = new JLabel(); - private JButton deleteButton = new JButton(); - - private BenthosFrequencyLogRowModel row; - - public BenthosFrequencyLogCellComponent() { + public BenthosFrequencyLogCellComponent(DeleteBenthosFrequencyLogRowAction action) { setLayout(new BorderLayout()); Font defaultFont = UIManager.getFont("Table.font"); @@ -63,49 +59,28 @@ public class BenthosFrequencyLogCellComponent 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); - } - - public BenthosFrequencyLogCellComponent(final BenthosFrequencyUIHandler benthosFrequencyUIHandler) { - this(); - deleteButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (row != null) { - int i = JOptionPane.showConfirmDialog( - benthosFrequencyUIHandler.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) { - benthosFrequencyUIHandler.decrementLengthStep(row); - } - } - } - }); + if (action != null) { + deleteButton.setAction(action); + } } public void setData(String data) { label.setText(data); } - public void setRow(BenthosFrequencyLogRowModel row) { - this.row = row; - } - public static TableCellRenderer newRender() { return new FrequencyLogCellRenderer(); } - public static TableCellEditor newEditor(BenthosFrequencyUIHandler benthosFrequencyUIHandler) { - return new FrequencyLogCellEditor(benthosFrequencyUIHandler); + public static TableCellEditor newEditor(BenthosFrequencyUI benthosFrequencyUI) { + return new FrequencyLogCellEditor(benthosFrequencyUI); } public static class FrequencyLogCellEditor extends AbstractCellEditor implements TableCellEditor { @@ -114,8 +89,19 @@ public class BenthosFrequencyLogCellComponent extends JPanel implements Serializ protected final BenthosFrequencyLogCellComponent component; - public FrequencyLogCellEditor(BenthosFrequencyUIHandler benthosFrequencyUIHandler) { - component = new BenthosFrequencyLogCellComponent(benthosFrequencyUIHandler); + private BenthosFrequencyLogRowModel row; + + public FrequencyLogCellEditor(BenthosFrequencyUI benthosFrequencyUI) { + component = new BenthosFrequencyLogCellComponent(new DeleteBenthosFrequencyLogRowAction(benthosFrequencyUI, this)); + } + + + public void setRow(BenthosFrequencyLogRowModel row) { + this.row = row; + } + + public BenthosFrequencyLogRowModel getRow() { + return row; } @Override @@ -127,7 +113,7 @@ public class BenthosFrequencyLogCellComponent extends JPanel implements Serializ BenthosFrequencyLogsTableModel tableModel = (BenthosFrequencyLogsTableModel) table.getModel(); BenthosFrequencyLogRowModel editRow = tableModel.getEntry(row); - component.setRow(editRow); + setRow(editRow); String data = (String) value; component.setData(data); @@ -147,7 +133,7 @@ public class BenthosFrequencyLogCellComponent extends JPanel implements Serializ protected final BenthosFrequencyLogCellComponent component; public FrequencyLogCellRenderer() { - component = new BenthosFrequencyLogCellComponent(); + component = new BenthosFrequencyLogCellComponent(null); } @Override @@ -167,4 +153,4 @@ public class BenthosFrequencyLogCellComponent extends JPanel implements Serializ } -} +} \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyLogRowModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyLogRowModel.java index ed70446..7dc5bc6 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyLogRowModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyLogRowModel.java @@ -37,7 +37,10 @@ public class BenthosFrequencyLogRowModel 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/benthos/frequency/BenthosFrequencyRowModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyRowModel.java index 47949f2..ac99072 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyRowModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyRowModel.java @@ -24,11 +24,11 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; -import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.persistence.entities.data.BenthosBatch; import fr.ifremer.tutti.persistence.entities.data.BenthosBatchFrequency; import fr.ifremer.tutti.persistence.entities.data.BenthosBatchFrequencys; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.type.WeightUnit; import fr.ifremer.tutti.ui.swing.util.AbstractTuttiBeanUIModel; import org.nuiton.util.beans.Binder; import org.nuiton.util.beans.BinderFactory; 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 6e497ec..246821b 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 @@ -22,16 +22,15 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency; * #L% */ -import com.google.common.collect.Maps; -import org.nuiton.jaxx.application.swing.table.AbstractApplicationTableModel; import fr.ifremer.tutti.type.WeightUnit; -import org.nuiton.jaxx.application.swing.table.ColumnIdentifier; 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 java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; -import java.util.Map; import static org.nuiton.i18n.I18n.n; @@ -47,22 +46,24 @@ public class BenthosFrequencyTableModel extends AbstractApplicationTableModel<Be public static final ColumnIdentifier<BenthosFrequencyRowModel> LENGTH_STEP = ColumnIdentifier.newId( BenthosFrequencyRowModel.PROPERTY_LENGTH_STEP, - n("tutti.editSpeciesFrequencies.table.header.lengthStep"), - n("tutti.editSpeciesFrequencies.table.header.lengthStep")); + n("tutti.editBenthosFrequencies.table.header.lengthStep"), + n("tutti.editBenthosFrequencies.table.header.lengthStep")); public static final ColumnIdentifier<BenthosFrequencyRowModel> NUMBER = ColumnIdentifier.newId( BenthosFrequencyRowModel.PROPERTY_NUMBER, - n("tutti.editSpeciesFrequencies.table.header.number"), - n("tutti.editSpeciesFrequencies.table.header.number")); + n("tutti.editBenthosFrequencies.table.header.number"), + n("tutti.editBenthosFrequencies.table.header.number")); public static final ColumnIdentifier<BenthosFrequencyRowModel> WEIGHT = ColumnIdentifier.newId( BenthosFrequencyRowModel.PROPERTY_WEIGHT, - n("tutti.editSpeciesFrequencies.table.header.weight"), - n("tutti.editSpeciesFrequencies.table.header.weight")); + n("tutti.editBenthosFrequencies.table.header.weight"), + n("tutti.editBenthosFrequencies.table.header.weight")); private final BenthosFrequencyUIModel uiModel; - private final Map<Float, BenthosFrequencyRowModel> rowCache; + private final BenthosFrequencyUIModelCache modelCache; + + protected final XYSeries series; /** * Weight unit. @@ -71,67 +72,29 @@ public class BenthosFrequencyTableModel extends AbstractApplicationTableModel<Be */ protected final WeightUnit weightUnit; - protected final PropertyChangeListener rowPropertyChangeListener; - protected final PropertyChangeListener onLengthStepChangedListener;; + protected transient PropertyChangeListener onLengthStepChangedListener; + + protected transient PropertyChangeListener onWeightChangedListener; + + protected transient PropertyChangeListener onNumberChangedListener; public BenthosFrequencyTableModel(WeightUnit weightUnit, TableColumnModelExt columnModel, - BenthosFrequencyUIModel uiModel, - PropertyChangeListener rowPropertyChangeListener) { + BenthosFrequencyUIModel 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); - } - BenthosFrequencyRowModel row = (BenthosFrequencyRowModel) 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, BenthosFrequencyRowModel row) { - recomputeCanEditLengthStep(); - } - - public void recomputeCanEditLengthStep() { - - boolean result = true; - - for (BenthosFrequencyRowModel 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 BenthosFrequencyRowModel createNewRow() { + return createNewRow(true); } - @Override - public BenthosFrequencyRowModel createNewRow() { + public BenthosFrequencyRowModel createNewRow(boolean attachListeners) { Float defaultStep = null; int rowCount = getRowCount(); @@ -145,12 +108,14 @@ public class BenthosFrequencyTableModel extends AbstractApplicationTableModel<Be } BenthosFrequencyRowModel result = new BenthosFrequencyRowModel(weightUnit); - result.addPropertyChangeListener(BenthosFrequencyRowModel.PROPERTY_LENGTH_STEP, onLengthStepChangedListener); - result.addPropertyChangeListener(rowPropertyChangeListener); + if (attachListeners) { + attachListeners(result); + } result.setLengthStepCaracteristic(uiModel.getLengthStepCaracteristic()); result.setLengthStep(defaultStep); result.setValid(defaultStep != null); + return result; } @@ -164,23 +129,199 @@ public class BenthosFrequencyTableModel extends AbstractApplicationTableModel<Be // TODO Rebuild the computedWeight if possible... } - public Map<Float, BenthosFrequencyRowModel> getRowCache() { - return rowCache; + @Override + protected void onRowAdded(int rowIndex, BenthosFrequencyRowModel row) { + uiModel.recomputeCanEditLengthStep(); + } + + @Override + protected void onRowUpdated(int rowIndex, BenthosFrequencyRowModel row) { + uiModel.recomputeCanEditLengthStep(); + } + + @Override + protected void onRowRemoved(int rowIndex, BenthosFrequencyRowModel row) { + dettachListeners(row); + uiModel.recomputeCanEditLengthStep(); + } + + @Override + protected void onBeforeRowsChanged(List<BenthosFrequencyRowModel> oldRows) { + + if (oldRows != null) { + + for (BenthosFrequencyRowModel row : oldRows) { + dettachListeners(row); + } + + } + } @Override protected void onRowsChanged(List<BenthosFrequencyRowModel> newRows) { - // rebuild row cache - rowCache.clear(); + if (newRows != null) { - for (BenthosFrequencyRowModel row : newRows) { - Float lengthStep = row.getLengthStep(); - if (lengthStep != null) { - rowCache.put(lengthStep, row); + for (BenthosFrequencyRowModel row : newRows) { + dettachListeners(row); // prevent leaks! + attachListeners(row); } + } - recomputeCanEditLengthStep(); + uiModel.recomputeCanEditLengthStep(); + } + + public void decrementNumberForLengthStep(Float lengthStep) { + + BenthosFrequencyRowModel 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); + + } + + 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); + } + + } + + BenthosFrequencyRowModel row = (BenthosFrequencyRowModel) 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) { + + BenthosFrequencyRowModel row = (BenthosFrequencyRowModel) 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) { + + BenthosFrequencyRowModel row = (BenthosFrequencyRowModel) evt.getSource(); + modelCache.updateRowWithWeight(row); + + uiModel.recomputeTotalNumberAndWeight(); + uiModel.recomputeRowsValidateState(); + + uiModel.updateEmptyRow(row); + + fireTableDataChanged(); + + } + }; + } + return onWeightChangedListener; + } + + private void dettachListeners(BenthosFrequencyRowModel result) { + + result.removePropertyChangeListener(BenthosFrequencyRowModel.PROPERTY_LENGTH_STEP, getOnLengthStepChangedListener()); + result.removePropertyChangeListener(BenthosFrequencyRowModel.PROPERTY_WEIGHT, getOnWeightChangedListener()); + result.removePropertyChangeListener(BenthosFrequencyRowModel.PROPERTY_NUMBER, getOnNumberChangedListener()); + + } + + private void attachListeners(BenthosFrequencyRowModel result) { + + result.addPropertyChangeListener(BenthosFrequencyRowModel.PROPERTY_LENGTH_STEP, getOnLengthStepChangedListener()); + result.addPropertyChangeListener(BenthosFrequencyRowModel.PROPERTY_WEIGHT, getOnWeightChangedListener()); + result.addPropertyChangeListener(BenthosFrequencyRowModel.PROPERTY_NUMBER, getOnNumberChangedListener()); + + } + } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUI.css b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUI.css index 5a85bdf..3f5e8e5 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUI.css +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUI.css @@ -279,52 +279,44 @@ ComputableDataEditor { _help: {"tutti.editBenthosFrequencies.field.mode.simpleCounting.help"}; } -#generateButton { - actionIcon: generate; - text: "tutti.editBenthosFrequencies.action.generate"; - toolTipText: "tutti.editBenthosFrequencies.action.generate.tip"; - i18nMnemonic: "tutti.editBenthosFrequencies.action.generate.mnemonic"; +#generateLengthStepsAction { enabled: {model.isCanGenerate()}; +} + +#generateButton { + action: {generateLengthStepsAction}; _help: {"tutti.editBenthosFrequencies.action.generate.help"}; } #addLengthStepCaracteristicButton { - text: "tutti.editBenthosFrequencies.action.addLengthStepCaracteristic"; - toolTipText: "tutti.editBenthosFrequencies.action.addLengthStepCaracteristic.tip"; - i18nMnemonic: "tutti.editBenthosFrequencies.action.addLengthStepCaracteristic.mnemonic"; + action: {addLengthStepCaracteristicAction}; _help: {"tutti.editBenthosFrequencies.action.addLengthStepCaracteristic.help"}; } #cancelButton { - actionIcon: cancel; - text: "tutti.editBenthosFrequencies.action.cancel"; - toolTipText: "tutti.editBenthosFrequencies.action.cancel.tip"; - i18nMnemonic: "tutti.editBenthosFrequencies.action.cancel.mnemonic"; + action: {cancelAction}; _help: {"tutti.editBenthosFrequencies.action.cancel.help"}; } -#saveAndContinueButton { - actionIcon: save; - text: "tutti.editBenthosFrequencies.action.saveAndContinue"; - toolTipText: "tutti.editBenthosFrequencies.action.saveAndContinue.tip"; - i18nMnemonic: "tutti.editBenthosFrequencies.action.saveAndContinue.mnemonic"; +#saveAndContinueAction { enabled: {model.getNextEditableRowIndex() != null && model.isValid()}; +} + +#saveAndContinueButton { + action: {saveAndContinueAction}; _help: {"tutti.editBenthosFrequencies.action.saveAndContinue.help"}; } -#saveAndCloseButton { - actionIcon: save; - text: "tutti.editBenthosFrequencies.action.saveAndClose"; - toolTipText: "tutti.editBenthosFrequencies.action.saveAndClose.tip"; - i18nMnemonic: "tutti.editBenthosFrequencies.action.saveAndClose.mnemonic"; +#saveAndCloseAction { enabled: {model.isValid()}; +} + +#saveAndCloseButton { + action: {saveAndCloseAction}; _help: {"tutti.editBenthosFrequencies.action.saveAndClose.help"}; } #resetButton { - actionIcon: reset; - text: "tutti.editBenthosFrequencies.action.reset"; - toolTipText: "tutti.editBenthosFrequencies.action.reset.tip"; - i18nMnemonic: "tutti.editBenthosFrequencies.action.reset.mnemonic"; + action: {resetAction}; _help: {"tutti.editBenthosFrequencies.action.reset.help"}; } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUI.jaxx b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUI.jaxx index dfeed1f..3c90364 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUI.jaxx +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUI.jaxx @@ -19,8 +19,7 @@ <http://www.gnu.org/licenses/gpl-3.0.html>. #L% --> -<JPanel id='editBenthosFrequenciesTopPanel' layout='{new BorderLayout()}' - decorator='help' +<JPanel id='editBenthosFrequenciesTopPanel' layout='{new BorderLayout()}' decorator='help' implements='fr.ifremer.tutti.ui.swing.util.TuttiUI<BenthosFrequencyUIModel, BenthosFrequencyUIHandler>'> <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.benthos.frequency.actions.AddBenthosFrequencyLengthStepCaracteristicAction + fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions.CancelEditBenthosFrequencyAction + fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions.GenerateBenthosFrequencyLengthStepsAction + fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions.ResetBenthosFrequencyAction + fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions.SaveAndCloseBenthosFrequencyAction + fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions.SaveAndContinueBenthosFrequencyAction fr.ifremer.tutti.ui.swing.util.TuttiUI fr.ifremer.tutti.ui.swing.util.TuttiUIUtil fr.ifremer.tutti.ui.swing.util.computable.ComputableDataEditor @@ -54,97 +59,91 @@ public BenthosFrequencyUI(TuttiUI parentUI) { } ]]></script> - <BenthosFrequencyUIModel id='model' - initializer='getContextValue(BenthosFrequencyUIModel.class)'/> + <BenthosFrequencyUIModel id='model' initializer='getContextValue(BenthosFrequencyUIModel.class)'/> - <BeanValidator id='validator' bean='model' - uiClass='jaxx.runtime.validator.swing.ui.ImageValidationUI'> - <field name='lengthStepCaracteristic' - component='lengthStepCaracteristicComboBox'/> + <BeanValidator id='validator' bean='model' uiClass='jaxx.runtime.validator.swing.ui.ImageValidationUI'> + <field name='lengthStepCaracteristic' component='lengthStepCaracteristicComboBox'/> <field name='step' component='stepField'/> <field name='rows' component='tableScrollPane'/> <field name='totalWeight' component='totalWeightField'/> </BeanValidator> - <TuttiHelpBroker id='broker' - constructorParams='"tutti.editBenthosFrequencies.help"'/> - - <CardLayout2Ext id='modeConfigurationLayout' - constructorParams='this, "modeConfigurationPanel"'/> - - <CardLayout2Ext id='dataFieldLayout' - constructorParams='this, "dataFieldPanel"'/> - - <JPanel id='configurationPanel' layout='{new BorderLayout()}' - constraints='BorderLayout.NORTH'> - - <VBox id='modePanel' constraints='BorderLayout.WEST' - verticalAlignment='{SwingConstants.CENTER}'> - <JRadioButton id='autoGenModeButton' - onActionPerformed='model.setConfigurationMode(FrequencyConfigurationMode.AUTO_GEN)'/> - <JRadioButton id='rafaleModeButton' - onActionPerformed='model.setConfigurationMode(FrequencyConfigurationMode.RAFALE)'/> - <JRadioButton id='simpleCountingModeButton' - onActionPerformed='model.setConfigurationMode(FrequencyConfigurationMode.SIMPLE_COUNTING)'/> - </VBox> - - <JPanel id='modeConfigurationPanel' constraints='BorderLayout.CENTER'> - <JPanel id='autoGenModePanel' constraints='"autoGenMode"'> - <Table fill='both' constraints='BorderLayout.SOUTH'> - <!-- Min step--> - <row> - <cell anchor='west'> - <JLabel id='minStepLabel'/> - </cell> - <cell weightx='1.0'> - <NumberEditor id='minStepField' constructorParams='this'/> - </cell> - </row> - <!-- Max step--> - <row> - <cell anchor='west'> - <JLabel id='maxStepLabel'/> - </cell> - <cell weightx='1.0'> - <NumberEditor id='maxStepField' constructorParams='this'/> - </cell> - </row> - <!-- Actions --> - <row> - <cell columns='2'> - <JPanel layout='{new GridLayout(1, 0)}'> - <JButton id='generateButton' - onActionPerformed='handler.generateLengthSteps()'/> - </JPanel> - </cell> - </row> - </Table> - </JPanel> - <JPanel id='rafaleModePanel' constraints='"rafaleMode"'> - <Table fill='both' constraints='BorderLayout.SOUTH'> - <!-- Rafale step--> - <row> - <cell weightx='1.0'> - <JLabel id='rafaleStepLabel'/> - </cell> - </row> - <row> - <cell weightx='1.0'> - <NumberEditor id='rafaleStepField' - constructorParams='this'/> - </cell> - </row> - </Table> - </JPanel> - <JPanel id='simpleCountingModePanel' constraints='"simpleCountingMode"' - layout='{new BorderLayout()}'> - <JLabel id='simpleCountingModeLabel' - constraints='BorderLayout.CENTER'/> - </JPanel> + <TuttiHelpBroker id='broker' constructorParams='"tutti.editBenthosFrequencies.help"'/> + + <CardLayout2Ext id='modeConfigurationLayout' constructorParams='this, "modeConfigurationPanel"'/> + + <CardLayout2Ext id='dataFieldLayout' constructorParams='this, "dataFieldPanel"'/> + + <AddBenthosFrequencyLengthStepCaracteristicAction id="addLengthStepCaracteristicAction" constructorParams="this"/> + <GenerateBenthosFrequencyLengthStepsAction id="generateLengthStepsAction" constructorParams="this"/> + <CancelEditBenthosFrequencyAction id="cancelAction" constructorParams="this"/> + <ResetBenthosFrequencyAction id="resetAction" constructorParams="this"/> + <SaveAndCloseBenthosFrequencyAction id="saveAndCloseAction" constructorParams="this"/> + <SaveAndContinueBenthosFrequencyAction id="saveAndContinueAction" constructorParams="this"/> + + <JPanel id='configurationPanel' layout='{new BorderLayout()}' constraints='BorderLayout.NORTH'> + + <VBox id='modePanel' constraints='BorderLayout.WEST' verticalAlignment='{SwingConstants.CENTER}'> + <JRadioButton id='autoGenModeButton' + onActionPerformed='model.setConfigurationMode(FrequencyConfigurationMode.AUTO_GEN)'/> + <JRadioButton id='rafaleModeButton' + onActionPerformed='model.setConfigurationMode(FrequencyConfigurationMode.RAFALE)'/> + <JRadioButton id='simpleCountingModeButton' + onActionPerformed='model.setConfigurationMode(FrequencyConfigurationMode.SIMPLE_COUNTING)'/> + </VBox> + + <JPanel id='modeConfigurationPanel' constraints='BorderLayout.CENTER'> + <JPanel id='autoGenModePanel' constraints='"autoGenMode"'> + <Table fill='both' constraints='BorderLayout.SOUTH'> + <!-- Min step--> + <row> + <cell anchor='west'> + <JLabel id='minStepLabel'/> + </cell> + <cell weightx='1.0'> + <NumberEditor id='minStepField' constructorParams='this'/> + </cell> + </row> + <!-- Max step--> + <row> + <cell anchor='west'> + <JLabel id='maxStepLabel'/> + </cell> + <cell weightx='1.0'> + <NumberEditor id='maxStepField' constructorParams='this'/> + </cell> + </row> + <!-- Actions --> + <row> + <cell columns='2'> + <JPanel layout='{new GridLayout(1, 0)}'> + <JButton id='generateButton'/> + </JPanel> + </cell> + </row> + </Table> + </JPanel> + <JPanel id='rafaleModePanel' constraints='"rafaleMode"'> + <Table fill='both' constraints='BorderLayout.SOUTH'> + <!-- Rafale step--> + <row> + <cell weightx='1.0'> + <JLabel id='rafaleStepLabel'/> + </cell> + </row> + <row> + <cell weightx='1.0'> + <NumberEditor id='rafaleStepField' constructorParams='this'/> + </cell> + </row> + </Table> + </JPanel> + <JPanel id='simpleCountingModePanel' constraints='"simpleCountingMode"' layout='{new BorderLayout()}'> + <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/> @@ -161,9 +160,7 @@ public BenthosFrequencyUI(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> @@ -185,36 +182,31 @@ public BenthosFrequencyUI(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> @@ -230,12 +222,11 @@ public BenthosFrequencyUI(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/benthos/frequency/BenthosFrequencyUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIHandler.java index d9ecc9f..a2c409e 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIHandler.java @@ -24,7 +24,6 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import fr.ifremer.tutti.persistence.entities.TuttiEntities; import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel; import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; @@ -35,12 +34,12 @@ 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.BenthosBatchRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions.ApplyBenthosFrequencyRafaleAction; 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; @@ -56,12 +55,8 @@ 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.swing.util.Cancelable; import javax.swing.JComponent; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JTextField; @@ -73,10 +68,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; @@ -84,7 +77,7 @@ import static org.nuiton.i18n.I18n.t; * @author tchemit <chemit@codelutin.com> * @since 0.2 */ -public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<BenthosFrequencyRowModel, BenthosFrequencyUIModel, BenthosFrequencyUI> implements Cancelable { +public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<BenthosFrequencyRowModel, BenthosFrequencyUIModel, BenthosFrequencyUI> { /** Logger. */ private static final Log log = @@ -96,8 +89,6 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth private Map<String, Caracteristic> lengthStepCaracteristics; - private XYSeriesCollection dataset; - private JFreeChart chart; /** @@ -107,6 +98,8 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth */ protected WeightUnit weightUnit; + protected ApplyBenthosFrequencyRafaleAction applyBenthosFrequencyRafaleAction; + public BenthosFrequencyUIHandler() { super(BenthosFrequencyRowModel.PROPERTY_LENGTH_STEP, BenthosFrequencyRowModel.PROPERTY_NUMBER, @@ -128,49 +121,27 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth } @Override - protected boolean isRowValid(BenthosFrequencyRowModel row) { - Float lengthStep = row.getLengthStep(); + public boolean isRowValid(BenthosFrequencyRowModel row) { + BenthosFrequencyUIModel 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<BenthosFrequencyRowModel> rows) { - super.onModelRowsChanged(rows); BenthosFrequencyUIModel model = getModel(); - model.setEmptyRows(Sets.<BenthosFrequencyRowModel>newHashSet()); - model.resetNumbersOfRows(); - if (CollectionUtils.isNotEmpty(rows)) { - XYSeries series = dataset.getSeries(0); - series.clear(); + model.reloadRows(); - for (BenthosFrequencyRowModel row : rows) { - model.updateRowWithWeight(row); + getTableModel().setRows(rows); - Float lengthStep = row.getLengthStep(); - if (lengthStep != null) { - model.incNumberOfRows(lengthStep); - } - } + // clean log table + BenthosFrequencyLogsTableModel logsTableModel = (BenthosFrequencyLogsTableModel) ui.getLogsTable().getModel(); + logsTableModel.setRows(Lists.<BenthosFrequencyLogRowModel>newArrayList()); - for (BenthosFrequencyRowModel row : rows) { - recomputeRowValidState(row); - - if (row.isValid()) { - Float lengthStep = row.getLengthStep(); - series.addOrUpdate(lengthStep, row.getNumber()); - } - } - } - model.recomputeTotalNumberAndWeight(); } @Override @@ -180,58 +151,9 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth Object oldValue, Object newValue) { - BenthosFrequencyUIModel model = getModel(); - - // keep number of rows with weight - int nbRowsWithWeight = model.getNbRowsWithWeight(); - - // update rowWithWeight cache - model.updateRowWithWeight(row); - - boolean lengthStepModified = BenthosFrequencyRowModel.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 (BenthosFrequencyRowModel 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 } @@ -261,14 +183,14 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth @Override public void beforeInit(BenthosFrequencyUI ui) { + this.applyBenthosFrequencyRafaleAction = new ApplyBenthosFrequencyRafaleAction(ui); + super.beforeInit(ui); this.weightUnit = getConfig().getBenthosWeightUnit(); - SampleCategoryModel sampleCategoryModel = - getDataContext().getSampleCategoryModel(); + SampleCategoryModel sampleCategoryModel = getDataContext().getSampleCategoryModel(); - BenthosFrequencyUIModel model = - new BenthosFrequencyUIModel(weightUnit, sampleCategoryModel); + BenthosFrequencyUIModel model = new BenthosFrequencyUIModel(weightUnit, sampleCategoryModel); this.ui.setContextValue(model); } @@ -288,8 +210,7 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth if (getContext().isProtocolFilled()) { // FIXME 20130128 kmorin: the species have no technical id - speciesProtocol = - getContext().getPersistenceService().toBenthosProtocolMap(); + speciesProtocol = getPersistenceService().toBenthosProtocolMap(); } else { speciesProtocol = Maps.newHashMap(); @@ -315,7 +236,7 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth e.consume(); Float step = (Float) BenthosFrequencyUIHandler.this.ui.getRafaleStepField().getModel(); - applyRafaleStep(step); + applyBenthosFrequencyRafaleAction.applyRafaleStep(step, false); //select text JTextField field = (JTextField) e.getSource(); @@ -332,7 +253,7 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth // 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 (BenthosFrequencyRowModel rowModel : getModel().getRows()) { @@ -393,7 +314,32 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth }); // init histogram - final XYSeries series = initHistogram(ui, step); + + 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 JXTable table = getTable(); @@ -427,29 +373,7 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth // create table model BenthosFrequencyTableModel tableModel = - new BenthosFrequencyTableModel( - weightUnit, - columnModel, - model, - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - BenthosFrequencyRowModel row = (BenthosFrequencyRowModel) evt.getSource(); - - if (BenthosFrequencyRowModel.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()); - } - } - }); - + new BenthosFrequencyTableModel(weightUnit, columnModel, model); table.setModel(tableModel); table.setColumnModel(columnModel); @@ -458,9 +382,35 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth installTableKeyListener(columnModel, table); - initLogTable(ui); + // init log table + JXTable logTable = ui.getLogsTable(); + + // create log table column model + DefaultTableColumnModelExt logColumnModel = new DefaultTableColumnModelExt(); + + { // Date + addColumnToModel(logColumnModel, + BenthosFrequencyLogCellComponent.newEditor(ui), + BenthosFrequencyLogCellComponent.newRender(), + BenthosFrequencyLogsTableModel.LABEL); + } + + // create log table model + BenthosFrequencyLogsTableModel logTableModel = new BenthosFrequencyLogsTableModel(logColumnModel); + logTableModel.setRows(new ArrayList<BenthosFrequencyLogRowModel>()); + + 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); + } @Override @@ -493,160 +443,11 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth parent.getHandler().setBenthosSelectedCard(EditCatchesUIHandler.MAIN_CARD); } - //------------------------------------------------------------------------// - //-- 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.editBenthosFrequencies.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() { - - BenthosFrequencyUIModel model = getModel(); - BenthosFrequencyTableModel tableModel = getTableModel(); - - Map<Float, BenthosFrequencyRowModel> 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<BenthosFrequencyRowModel> 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 - BenthosFrequencyRowModel 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) { - - if (log.isDebugEnabled()) { - log.debug("Will apply rafale step: " + step); - } - BenthosFrequencyUIModel model = getModel(); - BenthosFrequencyTableModel tableModel = getTableModel(); - - Map<Float, BenthosFrequencyRowModel> rowsByStep = tableModel.getRowCache(); - - float aroundLengthStep = model.getLengthStep(step); - - BenthosFrequencyRowModel 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); - - JXTable logsTable = getUI().getLogsTable(); - BenthosFrequencyLogsTableModel logsTableModel = (BenthosFrequencyLogsTableModel) logsTable.getModel(); - BenthosFrequencyLogRowModel newRow = logsTableModel.createNewRow(); - newRow.setDate(new Date()); - newRow.setLengthStep(step); - logsTableModel.addNewRow(0, newRow); - } - public void editBatch(BenthosFrequencyCellComponent.FrequencyCellEditor editor) { BenthosBatchRowModel speciesBatch = editor.getEditRow(); BenthosFrequencyUIModel model = getModel(); - model.clearWithWeightRows(); model.setNextEditableRowIndex(editor.getNextEditableRowIndex()); model.setTotalNumber(null); model.setTotalComputedWeight(null); @@ -660,14 +461,13 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth Caracteristic lengthStepCaracteristic = null; Float lengthStep; - List<BenthosFrequencyRowModel> editFrequency = Lists.newArrayList(); + List<BenthosFrequencyRowModel> rows = Lists.newArrayList(); if (speciesBatch != null) { model.setTotalWeight(speciesBatch.getWeight()); - List<BenthosFrequencyRowModel> frequency = - speciesBatch.getFrequency(); + List<BenthosFrequencyRowModel> frequency = speciesBatch.getFrequency(); // try to load existing frequency @@ -677,12 +477,12 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth for (BenthosFrequencyRowModel rowModel : frequency) { - BenthosFrequencyRowModel newRow = tableModel.createNewRow(); + BenthosFrequencyRowModel 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 @@ -699,14 +499,12 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth } } - BenthosBatchRowModel previousSiblingRow = - frequencyEditor.getPreviousSiblingRow(); + BenthosBatchRowModel previousSiblingRow = frequencyEditor.getPreviousSiblingRow(); if (lengthStepCaracteristic == null && previousSiblingRow != null) { // try to get it from his previous brother row - List<BenthosFrequencyRowModel> previousFrequency = - previousSiblingRow.getFrequency(); + List<BenthosFrequencyRowModel> previousFrequency = previousSiblingRow.getFrequency(); if (CollectionUtils.isNotEmpty(previousFrequency)) { @@ -728,16 +526,13 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth 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()) { @@ -751,8 +546,7 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth } 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; @@ -764,7 +558,7 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth } } Integer number = speciesBatch.getNumber(); - if (number != null && editFrequency.isEmpty()) { + if (number != null && rows.isEmpty()) { mode = FrequencyConfigurationMode.SIMPLE_COUNTING; model.setSimpleCount(number); } @@ -777,97 +571,14 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth // 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 - BenthosFrequencyLogsTableModel logsTableModel = (BenthosFrequencyLogsTableModel) getUI().getLogsTable().getModel(); - logsTableModel.setRows(new ArrayList<BenthosFrequencyLogRowModel>()); - - } - - public void reset() { - - // remove all frequencies - getModel().setRows(Lists.<BenthosFrequencyRowModel>newArrayList()); - - //remove log rows - BenthosFrequencyLogsTableModel logsTableModel = (BenthosFrequencyLogsTableModel) getUI().getLogsTable().getModel(); - logsTableModel.setRows(new ArrayList<BenthosFrequencyLogRowModel>()); - } - - 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(BenthosFrequencyLogRowModel logRow) { - if (logRow != null) { - BenthosFrequencyTableModel tableModel = getTableModel(); - BenthosFrequencyRowModel 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(); - } - - BenthosFrequencyLogsTableModel logsTableModel = (BenthosFrequencyLogsTableModel) getUI().getLogsTable().getModel(); - int index = logsTableModel.getRowIndex(logRow); - logsTableModel.removeRow(index); - } } //------------------------------------------------------------------------// @@ -908,74 +619,6 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth 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<BenthosFrequencyRowModel> rows = getModel().getRows(); - for (BenthosFrequencyRowModel 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.editBenthosFrequencies.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.editBenthosFrequencies.askBeforeSave.message"), - t("tutti.editBenthosFrequencies.askBeforeSave.help")); - int answer = JOptionPane.showConfirmDialog( - getTopestUI(), - htmlMessage, - t("tutti.editBenthosFrequencies.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) { @@ -1004,70 +647,16 @@ public class BenthosFrequencyUIHandler extends AbstractTuttiTableUIHandler<Benth ui.getLogsScrollPane().setVisible(logVisible); } - protected XYSeries initHistogram(BenthosFrequencyUI 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(BenthosFrequencyUI ui) { - JXTable logTable = ui.getLogsTable(); - - // create log table column model - DefaultTableColumnModelExt logColumnModel = new DefaultTableColumnModelExt(); - - { // Date - addColumnToModel(logColumnModel, - BenthosFrequencyLogCellComponent.newEditor(this), - BenthosFrequencyLogCellComponent.newRender(), - BenthosFrequencyLogsTableModel.LABEL); - } - - // create log table model - BenthosFrequencyLogsTableModel logTableModel = new BenthosFrequencyLogsTableModel(logColumnModel); - logTableModel.setRows(new ArrayList<BenthosFrequencyLogRowModel>()); - - 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 BenthosFrequencyCellComponent.FrequencyCellEditor getFrequencyEditor() { + return frequencyEditor; } } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIModel.java index 0966ffa..e8b375f 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIModel.java @@ -22,7 +22,6 @@ package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.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 BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBatchRowModel, BenthosFrequencyRowModel, BenthosFrequencyUIModel> { + /** Logger. */ + private static final Log log = LogFactory.getLog(BenthosFrequencyUIModel.class); + private static final long serialVersionUID = 1L; public static final String PROPERTY_BATCH = "batch"; @@ -172,26 +176,26 @@ public class BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBa 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<BenthosFrequencyRowModel> withWeightRows = Sets.newHashSet(); + protected final BenthosFrequencyUIModelCache cache = new BenthosFrequencyUIModelCache(); /** - * 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<Float, MutableInt> nbOfRowsByLengthStep = new HashMap<Float, 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 BenthosFrequencyUIModel(WeightUnit weightUnit, SampleCategoryModel sampleCategoryModel) { @@ -200,6 +204,75 @@ public class BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBa this.sampleCategoryModel = sampleCategoryModel; this.totalComputedOrNotWeight.addPropagateListener(PROPERTY_TOTAL_WEIGHT, this); setEmptyRows(Sets.<BenthosFrequencyRowModel>newHashSet()); + + XYSeries series = new XYSeries("", true, false); + + dataset = new XYSeriesCollection(series); + dataset.setIntervalPositionFactor(0); + dataset.setIntervalWidth(step); + } + + public void reloadRows() { + + setEmptyRows(Sets.<BenthosFrequencyRowModel>newHashSet()); + + XYSeries series = dataset.getSeries(0); + series.clear(); + + cache.loadCache(rows); + + recomputeRowsValidateState(); + + if (rows != null) { + + for (BenthosFrequencyRowModel row : rows) { + + if (row.isValid()) { + + Float lengthStep = row.getLengthStep(); + series.addOrUpdate(lengthStep, row.getNumber()); + + } + + } + + } + + recomputeTotalNumberAndWeight(); + + } + + public boolean isRowValid(BenthosFrequencyRowModel 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 +280,6 @@ public class BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBa return new BenthosBatchRowModel(weightUnit, sampleCategoryModel); } -// @Override -// public void setRows(List<BenthosFrequencyRowModel> rows) { -// super.setRows(rows); -// setEmptyRows(Sets.<BenthosFrequencyRowModel>newHashSet()); -// } - public FrequencyConfigurationMode getConfigurationMode() { return configurationMode; } @@ -397,16 +464,12 @@ public class BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBa 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 +492,7 @@ public class BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBa if (row.isEmpty()) { - // no value on rows, no chekc on it + // no value on rows, no check on it continue; } @@ -451,15 +514,6 @@ public class BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBa } - public void updateRowWithWeight(BenthosFrequencyRowModel row) { - - if (row.getWeight() == null) { - withWeightRows.remove(row); - } else { - withWeightRows.add(row); - } - } - public void updateEmptyRow(BenthosFrequencyRowModel row) { if (row.isValid() && row.getNumber() == null && row.getWeight() == null) { emptyRows.add(row); @@ -469,17 +523,6 @@ public class BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBa firePropertyChange(PROPERTY_EMPTY_ROWS, null, emptyRows); } - public Float computeTotalWeight() { - float result = 0f; - for (BenthosFrequencyRowModel row : withWeightRows) { - if (!row.isValid()) { - continue; - } - result += row.getWeight(); - } - return result; - } - public int computeTotalNumber() { int result = 0; if (rows != null) { @@ -496,42 +539,76 @@ public class BenthosFrequencyUIModel extends AbstractTuttiTableUIModel<BenthosBa } 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) { - int result = 0; - MutableInt mutableInt = nbOfRowsByLengthStep.get(lengthStep); - if (mutableInt != null) { - result = mutableInt.intValue(); + public void recomputeCanEditLengthStep() { + + boolean result = true; + + for (BenthosFrequencyRowModel 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 int numberOfRows(float lengthStep) { + return cache.numberOfRows(lengthStep); } - public void resetNumbersOfRows() { - nbOfRowsByLengthStep = new HashMap<Float, MutableInt>(); + public Map<Float, BenthosFrequencyRowModel> getRowCache() { + return cache.getRowCache(); } - public int incNumberOfRows(float lengthStep) { - MutableInt mutableInt = nbOfRowsByLengthStep.get(lengthStep); - if (mutableInt == null) { - mutableInt = new MutableInt(1); - nbOfRowsByLengthStep.put(lengthStep, mutableInt); + protected final void recomputeRowValidState(BenthosFrequencyRowModel 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 void recomputeRowsValidateState() { + + if (log.isInfoEnabled()) { + log.info("Revalidate all rows"); + } + + for (BenthosFrequencyRowModel r : rows) { + recomputeRowValidState(r); + } + } - public int decNumberOfRows(float lengthStep) { - MutableInt mutableInt = nbOfRowsByLengthStep.get(lengthStep); - 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/benthos/frequency/BenthosFrequencyUIModelCache.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIModelCache.java new file mode 100644 index 0000000..ad6ed7e --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/BenthosFrequencyUIModelCache.java @@ -0,0 +1,133 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.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 BenthosFrequencyUIModelCache implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Rows with a filled weight. + * + * @since 3.0 + */ + protected final Set<BenthosFrequencyRowModel> 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, BenthosFrequencyRowModel> rowCache = new TreeMap<Float, BenthosFrequencyRowModel>(); + + public void loadCache(List<BenthosFrequencyRowModel> rows) { + + withWeightRows.clear(); + nbOfRowsByLengthStep.clear(); + rowCache.clear(); + + for (BenthosFrequencyRowModel row : rows) { + + Float lengthStep = row.getLengthStep(); + if (lengthStep != null) { + rowCache.put(lengthStep, row); + incNumberOfRows(lengthStep); + } + + updateRowWithWeight(row); + + } + + } + + public void updateRowWithWeight(BenthosFrequencyRowModel 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(BenthosFrequencyRowModel row) { + + Float lengthStep = row.getLengthStep(); + rowCache.put(lengthStep, row); + incNumberOfRows(lengthStep); + + } + + public void removeLengthStep(Float oldValue) { + + rowCache.remove(oldValue); + decNumberOfRows(oldValue); + + } + + public Map<Float, BenthosFrequencyRowModel> getRowCache() { + return rowCache; + } + + public Float computeTotalWeight() { + float result = 0f; + for (BenthosFrequencyRowModel 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/benthos/frequency/actions/AddBenthosFrequencyLengthStepCaracteristicAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/AddBenthosFrequencyLengthStepCaracteristicAction.java new file mode 100644 index 0000000..d2166b7 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/AddBenthosFrequencyLengthStepCaracteristicAction.java @@ -0,0 +1,75 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.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.benthos.frequency.BenthosFrequencyUI; +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 AddBenthosFrequencyLengthStepCaracteristicAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final BenthosFrequencyUI ui; + + public AddBenthosFrequencyLengthStepCaracteristicAction(BenthosFrequencyUI ui) { + this.ui = ui; + + putValue(NAME, t("tutti.editBenthosFrequencies.action.addLengthStepCaracteristic")); + putValue(SHORT_DESCRIPTION, t("tutti.editBenthosFrequencies.action.addLengthStepCaracteristic.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editBenthosFrequencies.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.editBenthosFrequencies.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/benthos/frequency/actions/ApplyBenthosFrequencyRafaleAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/ApplyBenthosFrequencyRafaleAction.java new file mode 100644 index 0000000..7780b51 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/ApplyBenthosFrequencyRafaleAction.java @@ -0,0 +1,106 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions; + +import com.google.common.collect.Lists; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyLogRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyLogsTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUIHandler; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUIModel; +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 ApplyBenthosFrequencyRafaleAction { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ApplyBenthosFrequencyRafaleAction.class); + + private final BenthosFrequencyUI ui; + + public ApplyBenthosFrequencyRafaleAction(BenthosFrequencyUI ui) { + this.ui = ui; + } + + public void applyRafaleStep(Float step, boolean fromIchtyometer) { + + if (log.isDebugEnabled()) { + log.debug("Will apply rafale step: " + step); + } + BenthosFrequencyUIModel model = ui.getModel(); + BenthosFrequencyUIHandler handler = ui.getHandler(); + + BenthosFrequencyTableModel tableModel = handler.getTableModel(); + + Map<Float, BenthosFrequencyRowModel> rowsByStep = model.getRowCache(); + + float aroundLengthStep = model.getLengthStep(step); + + BenthosFrequencyRowModel 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.editBenthosFrequencies.addMeasure", step, aroundLengthStep, unit)); + } + + JXTable logsTable = ui.getLogsTable(); + BenthosFrequencyLogsTableModel logsTableModel = (BenthosFrequencyLogsTableModel) logsTable.getModel(); + BenthosFrequencyLogRowModel 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/benthos/frequency/actions/CancelEditBenthosFrequencyAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/CancelEditBenthosFrequencyAction.java new file mode 100644 index 0000000..54763b1 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/CancelEditBenthosFrequencyAction.java @@ -0,0 +1,49 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions; + +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI; +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 CancelEditBenthosFrequencyAction extends AbstractAction { + + /** Logger. */ + private static final Log log = LogFactory.getLog(CancelEditBenthosFrequencyAction.class); + + private static final long serialVersionUID = 1L; + + final BenthosFrequencyUI ui; + + public CancelEditBenthosFrequencyAction(BenthosFrequencyUI ui) { + this.ui = ui; + + putValue(NAME, t("tutti.editBenthosFrequencies.action.cancel")); + putValue(SHORT_DESCRIPTION, t("tutti.editBenthosFrequencies.action.cancel.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editBenthosFrequencies.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/benthos/frequency/actions/DeleteBenthosFrequencyLogRowAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/DeleteBenthosFrequencyLogRowAction.java new file mode 100644 index 0000000..91e7b04 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/DeleteBenthosFrequencyLogRowAction.java @@ -0,0 +1,70 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions; + +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyLogCellComponent; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyLogRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyLogsTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUIHandler; +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 DeleteBenthosFrequencyLogRowAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final BenthosFrequencyUI ui; + + private final BenthosFrequencyLogCellComponent.FrequencyLogCellEditor component; + + public DeleteBenthosFrequencyLogRowAction(BenthosFrequencyUI ui, BenthosFrequencyLogCellComponent.FrequencyLogCellEditor component) { + + this.ui = ui; + this.component = component; + putValue(SMALL_ICON, SwingUtil.createActionIcon("delete")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + BenthosFrequencyLogRowModel row = component.getRow(); + + if (row != null) { + + BenthosFrequencyUIHandler handler = ui.getHandler(); + + int i = JOptionPane.showConfirmDialog( + handler.getTopestUI(), + t("tutti.editBenthosFrequencies.logTable.removeRow.confirm.message", row.getLabel()), + t("tutti.editBenthosFrequencies.logTable.removeRow.confirm.title"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (i == JOptionPane.YES_OPTION) { + + BenthosFrequencyTableModel tableModel = handler.getTableModel(); + tableModel.decrementNumberForLengthStep(row.getLengthStep()); + + BenthosFrequencyLogsTableModel logsTableModel = (BenthosFrequencyLogsTableModel) 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/benthos/frequency/actions/GenerateBenthosFrequencyLengthStepsAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/GenerateBenthosFrequencyLengthStepsAction.java new file mode 100644 index 0000000..1194eac --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/GenerateBenthosFrequencyLengthStepsAction.java @@ -0,0 +1,78 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.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.benthos.frequency.BenthosFrequencyRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyTableModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUIModel; +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 GenerateBenthosFrequencyLengthStepsAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final BenthosFrequencyUI ui; + + public GenerateBenthosFrequencyLengthStepsAction(BenthosFrequencyUI ui) { + this.ui = ui; + + putValue(NAME, t("tutti.editBenthosFrequencies.action.generate")); + putValue(SHORT_DESCRIPTION, t("tutti.editBenthosFrequencies.action.generate.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editBenthosFrequencies.action.generate.mnemonic"), 'Z')); + putValue(SMALL_ICON, SwingUtil.createActionIcon("generate")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + BenthosFrequencyUIModel model = ui.getModel(); + BenthosFrequencyTableModel tableModel = ui.getHandler().getTableModel(); + + Map<Float, BenthosFrequencyRowModel> 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<BenthosFrequencyRowModel> 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 + BenthosFrequencyRowModel 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/benthos/frequency/actions/ResetBenthosFrequencyAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/ResetBenthosFrequencyAction.java new file mode 100644 index 0000000..4f75ae8 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/ResetBenthosFrequencyAction.java @@ -0,0 +1,43 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions; + +import com.google.common.collect.Lists; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI; +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 ResetBenthosFrequencyAction extends AbstractAction { + + private static final long serialVersionUID = 1L; + + final BenthosFrequencyUI ui; + + public ResetBenthosFrequencyAction(BenthosFrequencyUI ui) { + + this.ui = ui; + + putValue(NAME, t("tutti.editBenthosFrequencies.action.reset")); + putValue(SHORT_DESCRIPTION, t("tutti.editBenthosFrequencies.action.reset.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editBenthosFrequencies.action.reset.mnemonic"), 'Z')); + putValue(SMALL_ICON, SwingUtil.createActionIcon("reset")); + + } + + @Override + public void actionPerformed(ActionEvent e) { + + // remove all frequencies + ui.getModel().setRows(Lists.<BenthosFrequencyRowModel>newArrayList()); + + } +} \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/SaveAndCloseBenthosFrequencyAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/SaveAndCloseBenthosFrequencyAction.java new file mode 100644 index 0000000..72c63c8 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/SaveAndCloseBenthosFrequencyAction.java @@ -0,0 +1,55 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions; + +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUIHandler; +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 SaveAndCloseBenthosFrequencyAction extends SaveSupportAction { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SaveAndCloseBenthosFrequencyAction.class); + + private static final long serialVersionUID = 1L; + + public SaveAndCloseBenthosFrequencyAction(BenthosFrequencyUI ui) { + super(ui); + + putValue(NAME, t("tutti.editBenthosFrequencies.action.saveAndClose")); + putValue(SHORT_DESCRIPTION, t("tutti.editBenthosFrequencies.action.saveAndClose.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editBenthosFrequencies.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) { + + BenthosFrequencyUIHandler 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/benthos/frequency/actions/SaveAndContinueBenthosFrequencyAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/SaveAndContinueBenthosFrequencyAction.java new file mode 100644 index 0000000..ce3a797 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/SaveAndContinueBenthosFrequencyAction.java @@ -0,0 +1,49 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions; + +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI; +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 SaveAndContinueBenthosFrequencyAction extends SaveSupportAction { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SaveAndContinueBenthosFrequencyAction.class); + + private static final long serialVersionUID = 1L; + + public SaveAndContinueBenthosFrequencyAction(BenthosFrequencyUI ui) { + super(ui); + + putValue(NAME, t("tutti.editBenthosFrequencies.action.saveAndContinue")); + putValue(SHORT_DESCRIPTION, t("tutti.editBenthosFrequencies.action.saveAndContinue.tip")); + putValue(MNEMONIC_KEY, (int) SwingUtil.getFirstCharAt(t("tutti.editBenthosFrequencies.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/benthos/frequency/actions/SaveSupportAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/SaveSupportAction.java new file mode 100644 index 0000000..9224d5c --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/benthos/frequency/actions/SaveSupportAction.java @@ -0,0 +1,105 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.actions; + +import com.google.common.collect.Sets; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyRowModel; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUI; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUIHandler; +import fr.ifremer.tutti.ui.swing.content.operation.catches.benthos.frequency.BenthosFrequencyUIModel; +import jaxx.runtime.swing.JTables; +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 BenthosFrequencyUI ui; + + public SaveSupportAction(BenthosFrequencyUI ui) { + this.ui = ui; + } + + protected boolean canSaveFrequencies() { + boolean doSave = true; + + BenthosFrequencyUIModel 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<BenthosFrequencyRowModel> rows = model.getRows(); + for (BenthosFrequencyRowModel row : rows) { + Float lengthStep = row.getLengthStep(); + if (!lengths.add(lengthStep)) { + + // already exist + doublon = lengthStep; + break; + } + index++; + } + BenthosFrequencyUIHandler handler = ui.getHandler(); + + if (doublon != null) { + + // can't save mensurations (found doublon) + String message = + t("tutti.editBenthosFrequencies.error.length.doublon", + doublon, index + 1); + handler.getContext().getErrorHelper().showErrorDialog( + message); + + // focus to first error row + JTables.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.editBenthosFrequencies.askBeforeSave.message"), + t("tutti.editBenthosFrequencies.askBeforeSave.help")); + int answer = JOptionPane.showConfirmDialog( + handler.getTopestUI(), + htmlMessage, + t("tutti.editBenthosFrequencies.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 diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties index 7fa3b46..e6507bb 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties @@ -506,6 +506,7 @@ tutti.editBenthosFrequencies.action.saveAndClose.tip= tutti.editBenthosFrequencies.action.saveAndContinue= tutti.editBenthosFrequencies.action.saveAndContinue.mnemonic= tutti.editBenthosFrequencies.action.saveAndContinue.tip= +tutti.editBenthosFrequencies.addMeasure= tutti.editBenthosFrequencies.askBeforeSave.help= tutti.editBenthosFrequencies.askBeforeSave.message= tutti.editBenthosFrequencies.askBeforeSave.title= @@ -538,9 +539,12 @@ tutti.editBenthosFrequencies.field.totalWeight= tutti.editBenthosFrequencies.field.totalWeight.tip= tutti.editBenthosFrequencies.label.no.configuration= tutti.editBenthosFrequencies.logTable.header.label= +tutti.editBenthosFrequencies.logTable.removeRow.confirm.message= +tutti.editBenthosFrequencies.logTable.removeRow.confirm.title= tutti.editBenthosFrequencies.simpleCountingAndFrequencies= tutti.editBenthosFrequencies.table.header.lengthStep= tutti.editBenthosFrequencies.table.header.number= +tutti.editBenthosFrequencies.table.header.weight= tutti.editBenthosFrequencies.title= tutti.editBenthosFrequencies.title.addLengthStepCaracteristic= tutti.editBenthosFrequencies.unkownStepUnit= diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties index 3b7eb1b..2034954 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties @@ -494,6 +494,7 @@ tutti.editBenthosFrequencies.action.saveAndClose.tip=Enregistrer les mensuration tutti.editBenthosFrequencies.action.saveAndContinue=Enregistrer et Continuer tutti.editBenthosFrequencies.action.saveAndContinue.mnemonic=C tutti.editBenthosFrequencies.action.saveAndContinue.tip=Enregistrer les mensurations et saisir les mensurations pour le lot suivant +tutti.editBenthosFrequencies.addMeasure=Ajout d'un individu de taille <strong>%1$s</strong>%3$s (classe de taille <strong>%2$s</strong>%3$s) tutti.editBenthosFrequencies.askBeforeSave.help=Que voulez-vous faire?<ul><li><strong>Non</strong> pour rester sur cet écran</li><li><strong>Oui</strong> pour enregisrer les mensurations avec poids</li></ul> tutti.editBenthosFrequencies.askBeforeSave.message=La saisie comporte des classes de taille avec et sans poids associés.<br/><strong>Seules les classes de taille avec poids seront dans ce cas sauvegardées.</strong> tutti.editBenthosFrequencies.askBeforeSave.title=Confirmer l'enregistrement des mensurations @@ -527,6 +528,11 @@ tutti.editBenthosFrequencies.field.totalWeight.tip=Poids total des lignes valide tutti.editBenthosFrequencies.label.no.configuration=< Pas de configuration > tutti.editBenthosFrequencies.logTable.header.label=Logs tutti.editBenthosFrequencies.simpleCountingAndFrequencies=Des mensurations ont été saisies dans le tableau. Saisir un simple dénombrement les effacera. +tutti.editBenthosFrequencies.logTable.removeRow.confirm.message=Êtes-vous sûr de vouloir supprimer la mesure %s ? +tutti.editBenthosFrequencies.logTable.removeRow.confirm.title=Suppression d'une mesure +tutti.editBenthosFrequencies.table.header.lengthStep=Classe de taille +tutti.editBenthosFrequencies.table.header.number=Nombre +tutti.editBenthosFrequencies.table.header.weight=Poids observé tutti.editBenthosFrequencies.title=Mensuration tutti.editBenthosFrequencies.title.addLengthStepCaracteristic=Choisir une autre caractéristique tutti.editBenthosFrequencies.unkownStepUnit=NA -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.