package org.esa.snap.binning.operator.ui; import com.bc.ceres.binding.Property; import com.bc.ceres.binding.PropertyContainer; import com.bc.ceres.binding.PropertyDescriptor; import com.bc.ceres.binding.ValidationException; import com.bc.ceres.binding.Validator; import com.bc.ceres.swing.TableLayout; import com.bc.ceres.swing.binding.BindingContext; import com.bc.ceres.swing.binding.PropertyEditor; import com.bc.ceres.swing.binding.PropertyEditorRegistry; import com.bc.ceres.swing.binding.internal.TextComponentAdapter; import com.bc.ceres.swing.binding.internal.TextFieldEditor; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.dataop.barithm.BandArithmetic; import org.esa.snap.core.gpf.annotations.ParameterDescriptorFactory; import org.esa.snap.core.jexp.ParseException; import org.esa.snap.core.util.StringUtils; import org.esa.snap.ui.AbstractDialog; import org.esa.snap.ui.ModalDialog; import org.esa.snap.ui.product.ProductExpressionPane; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; class VariableItemDialog extends ModalDialog { private static final String PROPERTY_VARIABLE_NAME = "name"; private static final String PROPERTY_EXPRESSION = "expr"; private final VariableItem variableItem; private final boolean newVariable; private final Product contextProduct; private final BindingContext bindingContext; VariableItemDialog(final Window parent, VariableItem variableItem, boolean createNewVariable, Product contextProduct) { super(parent, "Intermediate Source Band", ID_OK_CANCEL, null); this.variableItem = variableItem; newVariable = createNewVariable; this.contextProduct = contextProduct; bindingContext = createBindingContext(); makeUI(); } @Override protected boolean verifyUserInput() { String expression = variableItem.variableConfig.getExpr() != null ? variableItem.variableConfig.getExpr().trim() : ""; if (StringUtils.isNullOrEmpty(expression)) { AbstractDialog.showInformationDialog(getParent(), "The source band could not be created. The expression is empty.", "Information"); return false; } String variableName = variableItem.variableConfig.getName() != null ? variableItem.variableConfig.getName().trim() : ""; if (StringUtils.isNullOrEmpty(variableName)) { AbstractDialog.showInformationDialog(getParent(), "The source band could not be created. The name is empty.", "Information"); return false; } if (newVariable && contextProduct.containsBand(variableName)) { String message = String.format("A source band or band with the name '%s' is already defined", variableName); AbstractDialog.showInformationDialog(getParent(), message, "Information"); return false; } try { BandArithmetic.getValidMaskExpression(expression, contextProduct, null); } catch (ParseException e) { String errorMessage = "The source band could not be created.\nThe expression could not be parsed:\n" + e.getMessage(); /*I18N*/ AbstractDialog.showErrorDialog(getParent(), errorMessage, "Error"); return false; } return true; } @Override protected void onOK() { variableItem.variableConfig.setName(variableItem.variableConfig.getName().trim()); variableItem.variableConfig.setExpr(variableItem.variableConfig.getExpr().trim()); super.onOK(); } VariableItem getVariableItem() { return variableItem; } private BindingContext createBindingContext() { final PropertyContainer container = PropertyContainer.createObjectBacked(variableItem.variableConfig, new ParameterDescriptorFactory()); final BindingContext context = new BindingContext(container); PropertyDescriptor descriptor = container.getDescriptor(PROPERTY_VARIABLE_NAME); descriptor.setDescription("The name for the source band."); descriptor.setValidator(new VariableNameValidator()); container.setDefaultValues(); return context; } private void makeUI() { JComponent[] variableComponents = createComponents(PROPERTY_VARIABLE_NAME, TextFieldEditor.class); final TableLayout layout = new TableLayout(2); layout.setTablePadding(4, 3); layout.setCellWeightX(0, 1, 1.0); layout.setCellWeightX(1, 1, 1.0); layout.setCellWeightX(2, 0, 1.0); layout.setCellColspan(2, 0, 2); layout.setTableFill(TableLayout.Fill.HORIZONTAL); final JPanel panel = new JPanel(layout); panel.add(variableComponents[1]); panel.add(variableComponents[0]); JLabel expressionLabel = new JLabel("Variable expression:"); JTextArea expressionArea = new JTextArea(); expressionArea.setRows(3); TextComponentAdapter textComponentAdapter = new TextComponentAdapter(expressionArea); bindingContext.bind(PROPERTY_EXPRESSION, textComponentAdapter); panel.add(expressionLabel); panel.add(layout.createHorizontalSpacer()); panel.add(expressionArea); JButton editExpressionButton = new JButton("Edit Expression..."); editExpressionButton.setName("editExpressionButton"); editExpressionButton.addActionListener(createEditExpressionButtonListener()); panel.add(layout.createHorizontalSpacer()); panel.add(editExpressionButton); setContent(panel); } private JComponent[] createComponents(String propertyName, Class<? extends PropertyEditor> editorClass) { PropertyDescriptor descriptor = bindingContext.getPropertySet().getDescriptor(propertyName); PropertyEditor editor = PropertyEditorRegistry.getInstance().getPropertyEditor(editorClass.getName()); return editor.createComponents(descriptor, bindingContext); } private ActionListener createEditExpressionButtonListener() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ProductExpressionPane expressionPane = ProductExpressionPane.createGeneralExpressionPane(new Product[]{contextProduct}, contextProduct, null); expressionPane.setCode(variableItem.variableConfig.getExpr()); int status = expressionPane.showModalDialog(getJDialog(), "Expression Editor"); if (status == ModalDialog.ID_OK) { bindingContext.getBinding(PROPERTY_EXPRESSION).setPropertyValue(expressionPane.getCode()); } expressionPane.dispose(); } }; } private class VariableNameValidator implements Validator { @Override public void validateValue(Property property, Object value) throws ValidationException { final String name = (String) value; if (contextProduct.containsRasterDataNode(name)) { throw new ValidationException("The source band name must be unique."); } } } }