package eu.omp.irap.vespa.epntapclient.view; import java.awt.Color; import java.awt.Dimension; import java.beans.PropertyChangeEvent; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.Objects; import javax.swing.BoxLayout; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public abstract class ParamField extends JPanel { /** The logger for this class. */ private static final Logger logger = LogManager.getLogger(ParamField.class); private static final String DATE_FORMAT = "dd/MM/yyyy"; private static final String DATE_REGEX = "(^(((0[1-9]|1[0-9]|2[0-8])[\\/](0[1-9]|1[012]))|((29|30|31)[\\/](0[13578]|1[02]))|((29|30)[\\/](0[4,6,9]|11)))[\\/](19|[2-9][0-9])\\d\\d$)|(^29[\\/]02[\\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)"; private static final String MIN_SUFFIX = "min"; private static final String MAX_SUFFIX = "max"; protected static RequestView requestView; protected String paramName; public ParamField(RequestView requestView, String paramName) { super(); this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); String strLabel = paramName.replaceAll("_", " ").trim(); JLabel label = new JLabel(strLabel.substring(0, 1).toUpperCase() + strLabel.substring(1)); label.setPreferredSize(new Dimension(140, 15)); this.add(label); // TODO: Add tooltip text based on rr.table_column.column_description this.requestView = requestView; this.paramName = paramName; } public static class StringField extends ParamField { JTextField field; StringField(RequestView requestView, String paramName) { super(requestView, paramName); field = new JTextField(); addChangeListener(field, e -> onUpdate()); this.add(field); } private void onUpdate() { if ("".equals(field.getText())) { requestView.updateParam(paramName, null); } else { requestView.updateParam(paramName, field.getText()); } } } public static class FloatField extends ParamField { JTextField field; FloatField(RequestView requestView, String paramName) { super(requestView, paramName); field = new JTextField(); addChangeListener(field, e -> onUpdate()); this.add(field); } private void onUpdate() { if ("".equals(field.getText())) { field.setBackground(Color.WHITE); requestView.updateParam(paramName, null); } else { try { requestView.updateParam(paramName, Float.parseFloat(field.getText())); field.setBackground(Color.WHITE); } catch (NumberFormatException e) { field.setBackground(Color.PINK); } } } } public static class DateRangeField extends ParamField { JTextField fieldMin; JTextField fieldMax; DateRangeField(RequestView requestView, String paramName) { super(requestView, paramName); fieldMin = new JTextField(); addChangeListener(fieldMin, e -> onUpdate(fieldMin, MIN_SUFFIX)); this.add(fieldMin); fieldMax = new JTextField(); addChangeListener(fieldMax, e -> onUpdate(fieldMax, MAX_SUFFIX)); this.add(fieldMax); } private void onUpdate(JTextField field, String suffix) { DateFormat df = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH); if ("".equals(field.getText())) { field.setBackground(Color.WHITE); requestView.updateParam(paramName + suffix, null); } else if (field.getText().matches(DATE_REGEX)) { try { long date = df.parse(field.getText()).getTime(); date = (Math.round((date / 86400000.0) + 2440587.5)); // to JD requestView.updateParam(paramName + suffix, date); field.setBackground(Color.WHITE); } catch (ParseException e) { field.setBackground(Color.PINK); } // TODO: check if date min < date max } else { field.setBackground(Color.PINK); } } } public static class FloatRangeField extends ParamField { JTextField fieldMin; JTextField fieldMax; FloatRangeField(RequestView requestView, String paramName) { super(requestView, paramName); fieldMin = new JTextField(); addChangeListener(fieldMin, e -> onUpdate(fieldMin, MIN_SUFFIX)); this.add(fieldMin); fieldMax = new JTextField(); addChangeListener(fieldMax, e -> onUpdate(fieldMax, MAX_SUFFIX)); this.add(fieldMax); } private void onUpdate(JTextField field, String suffix) { if ("".equals(field.getText())) { field.setBackground(Color.WHITE); requestView.updateParam(paramName + suffix, null); } else { try { requestView.updateParam(paramName + suffix, Float.parseFloat(field.getText())); field.setBackground(Color.WHITE); } catch (NumberFormatException e) { field.setBackground(Color.PINK); } } } } public static class TargetNameField extends ParamField { JComboBox comboBox; JTextField field; String lastContent; TargetNameField(RequestView requestView, String paramName) { super(requestView, paramName); comboBox = new JComboBox(); comboBox.setEditable(true); field = (JTextField) comboBox.getEditor().getEditorComponent(); addChangeListener(field, e -> onUpdate()); this.add(comboBox); } private String[] getTargetNames(String begining) { String[] targetNames = { begining + "Bird", begining + "Cat", begining + "Dog" }; return targetNames; } private void onUpdate() { String content = field.getText(); if (content.length() >= 2 && !content.equals(lastContent)) { lastContent = content; int nbItems = comboBox.getItemCount(); comboBox.removeAllItems(); for (String s : getTargetNames(content)) { comboBox.addItem(s); } field.setText(content); requestView.updateParam(paramName, content); } } } public static class DataProductTypeField extends ParamField { JTextField field; DataProductTypeField(RequestView requestView, String paramName) { super(requestView, paramName); JTextField field = new JTextField(); // TODO: listbox with enumerated values instead of JTextField addChangeListener(field, e -> onUpdate()); this.add(field); } private void onUpdate() { if ("".equals(field.getText())) { requestView.updateParam(paramName, null); } else { requestView.updateParam(paramName, field.getText()); } } } public static class TargetClassField extends ParamField { JTextField field; TargetClassField(RequestView requestView, String paramName) { super(requestView, paramName); JTextField field = new JTextField(); // TODO: listbox with enumerated values instead of JTextField addChangeListener(field, e -> onUpdate()); this.add(field); } private void onUpdate() { if ("".equals(field.getText())) { requestView.updateParam(paramName, null); } else { requestView.updateParam(paramName, field.getText()); } } } // public class EnumParamField extends ParamField { // EnumParamField() { // super(); // } // } public static void addChangeListener(JTextComponent text, ChangeListener changeListener) { Objects.requireNonNull(text); Objects.requireNonNull(changeListener); DocumentListener dl = new DocumentListener() { private int lastChange = 0, lastNotifiedChange = 0; @Override public void insertUpdate(DocumentEvent e) { changedUpdate(e); } @Override public void removeUpdate(DocumentEvent e) { changedUpdate(e); } @Override public void changedUpdate(DocumentEvent e) { lastChange++; SwingUtilities.invokeLater(() -> { if (lastNotifiedChange != lastChange) { lastNotifiedChange = lastChange; changeListener.stateChanged(new ChangeEvent(text)); } }); } }; text.addPropertyChangeListener("document", (PropertyChangeEvent e) -> { Document d1 = (Document) e.getOldValue(); Document d2 = (Document) e.getNewValue(); if (d1 != null) d1.removeDocumentListener(dl); if (d2 != null) d2.addDocumentListener(dl); dl.changedUpdate(null); }); Document d = text.getDocument(); if (d != null) d.addDocumentListener(dl); } }