Blame view

src/main/java/eu/omp/irap/vespa/epntapclient/view/ParamField.java 9.9 KB
eb483599   Nathanael Jourdane   Add missing Param...
1
2
3
4
package eu.omp.irap.vespa.epntapclient.view;

import java.awt.Color;
import java.awt.Dimension;
a99d92fa   Nathanael Jourdane   Add JComboBox for...
5
6
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
eb483599   Nathanael Jourdane   Add missing Param...
7
8
9
10
11
12
13
14
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;
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
15
import javax.swing.JComboBox;
eb483599   Nathanael Jourdane   Add missing Param...
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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;

05b140ed   Nathanael Jourdane   TargetNameField J...
30
31
32
33
34
35
36
37
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableConnection;
import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.BadRequestException;
import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.HTTPRequestException;

eb483599   Nathanael Jourdane   Add missing Param...
38
39
40
41
42
public abstract class ParamField extends JPanel {

	/** The logger for this class. */
	private static final Logger logger = LogManager.getLogger(ParamField.class);

05b140ed   Nathanael Jourdane   TargetNameField J...
43
	private static final String RESOLVER_URL = "http://voparis-registry.obspm.fr/ssodnet/1/autocomplete";
eb483599   Nathanael Jourdane   Add missing Param...
44
45
46
47
48
49
50
51
52
	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;

eb483599   Nathanael Jourdane   Add missing Param...
53
54
55
56
57
58
59
	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);
41133475   Nathanael Jourdane   build floatRangeF...
60
		// TODO: Add tooltip text based on rr.table_column.column_description
eb483599   Nathanael Jourdane   Add missing Param...
61
62
63
64
65
		this.requestView = requestView;
		this.paramName = paramName;
	}

	public static class StringField extends ParamField {
667dd80c   Nathanael Jourdane   JTextField as Par...
66
67
		JTextField field;

eb483599   Nathanael Jourdane   Add missing Param...
68
69
		StringField(RequestView requestView, String paramName) {
			super(requestView, paramName);
667dd80c   Nathanael Jourdane   JTextField as Par...
70
71
			field = new JTextField();
			addChangeListener(field, e -> onUpdate());
eb483599   Nathanael Jourdane   Add missing Param...
72
73
74
			this.add(field);
		}

667dd80c   Nathanael Jourdane   JTextField as Par...
75
		private void onUpdate() {
eb483599   Nathanael Jourdane   Add missing Param...
76
77
78
79
80
81
82
83
84
			if ("".equals(field.getText())) {
				requestView.updateParam(paramName, null);
			} else {
				requestView.updateParam(paramName, field.getText());
			}
		}
	}

	public static class FloatField extends ParamField {
667dd80c   Nathanael Jourdane   JTextField as Par...
85
86
		JTextField field;

eb483599   Nathanael Jourdane   Add missing Param...
87
88
		FloatField(RequestView requestView, String paramName) {
			super(requestView, paramName);
667dd80c   Nathanael Jourdane   JTextField as Par...
89
90
			field = new JTextField();
			addChangeListener(field, e -> onUpdate());
eb483599   Nathanael Jourdane   Add missing Param...
91
92
93
			this.add(field);
		}

667dd80c   Nathanael Jourdane   JTextField as Par...
94
		private void onUpdate() {
eb483599   Nathanael Jourdane   Add missing Param...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
			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 {
667dd80c   Nathanael Jourdane   JTextField as Par...
110
111
112
		JTextField fieldMin;
		JTextField fieldMax;

eb483599   Nathanael Jourdane   Add missing Param...
113
114
		DateRangeField(RequestView requestView, String paramName) {
			super(requestView, paramName);
667dd80c   Nathanael Jourdane   JTextField as Par...
115
			fieldMin = new JTextField();
eb483599   Nathanael Jourdane   Add missing Param...
116
117
118
			addChangeListener(fieldMin, e -> onUpdate(fieldMin, MIN_SUFFIX));
			this.add(fieldMin);

667dd80c   Nathanael Jourdane   JTextField as Par...
119
			fieldMax = new JTextField();
eb483599   Nathanael Jourdane   Add missing Param...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
			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 {
41133475   Nathanael Jourdane   build floatRangeF...
146
147
		JTextField fieldMin;
		JTextField fieldMax;
eb483599   Nathanael Jourdane   Add missing Param...
148
149
150

		FloatRangeField(RequestView requestView, String paramName) {
			super(requestView, paramName);
41133475   Nathanael Jourdane   build floatRangeF...
151
152
			fieldMin = new JTextField();
			addChangeListener(fieldMin, e -> onUpdate(fieldMin, MIN_SUFFIX));
eb483599   Nathanael Jourdane   Add missing Param...
153
154
			this.add(fieldMin);

41133475   Nathanael Jourdane   build floatRangeF...
155
156
			fieldMax = new JTextField();
			addChangeListener(fieldMax, e -> onUpdate(fieldMax, MAX_SUFFIX));
eb483599   Nathanael Jourdane   Add missing Param...
157
158
			this.add(fieldMax);
		}
41133475   Nathanael Jourdane   build floatRangeF...
159
160
161
162
163
164
165
166
167
168
169
170
171
172

		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);
				}
			}
		}
eb483599   Nathanael Jourdane   Add missing Param...
173
174
175
	}

	public static class TargetNameField extends ParamField {
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
176
		JComboBox<String> comboBox;
667dd80c   Nathanael Jourdane   JTextField as Par...
177
		JTextField field;
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
178
		String lastContent;
667dd80c   Nathanael Jourdane   JTextField as Par...
179

eb483599   Nathanael Jourdane   Add missing Param...
180
181
		TargetNameField(RequestView requestView, String paramName) {
			super(requestView, paramName);
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
182
183
184
			comboBox = new JComboBox();
			comboBox.setEditable(true);
			field = (JTextField) comboBox.getEditor().getEditorComponent();
667dd80c   Nathanael Jourdane   JTextField as Par...
185
			addChangeListener(field, e -> onUpdate());
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
186
187
188
			this.add(comboBox);
		}

a99d92fa   Nathanael Jourdane   Add JComboBox for...
189
		private String[] getItems(String begining) {
05b140ed   Nathanael Jourdane   TargetNameField J...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
			StringBuilder resolverResult = null;
			try {
				resolverResult = VOTableConnection.sendGet(RESOLVER_URL, "q=\"" + begining + "\"");
			} catch (HTTPRequestException | BadRequestException e) {
				logger.fatal("Can not send sersolver query: ", e);
			}
			JsonObject root = new JsonParser().parse(resolverResult.toString()).getAsJsonObject();
			int count = Integer.parseInt(root.get("count").toString());
			String[] targetNames = new String[count];
			JsonArray hits = root.getAsJsonArray("hits");
			for (int i = 0; i < count; i++) {
				JsonObject elmt = hits.get(i).getAsJsonObject();
				targetNames[i] = elmt.get("name").toString().replace("\"", "");
				// TODO: Display "[name] ([type])" on the JComboBox, but only "[name]" on the query.
			}
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
205
			return targetNames;
eb483599   Nathanael Jourdane   Add missing Param...
206
207
		}

667dd80c   Nathanael Jourdane   JTextField as Par...
208
		private void onUpdate() {
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
209
210
211
212
213
			String content = field.getText();
			if (content.length() >= 2 && !content.equals(lastContent)) {
				lastContent = content;
				int nbItems = comboBox.getItemCount();
				comboBox.removeAllItems();
a99d92fa   Nathanael Jourdane   Add JComboBox for...
214
				for (String s : getItems(content)) {
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
215
216
217
218
					comboBox.addItem(s);
				}
				field.setText(content);
				requestView.updateParam(paramName, content);
eb483599   Nathanael Jourdane   Add missing Param...
219
220
221
222
223
			}
		}
	}

	public static class DataProductTypeField extends ParamField {
a99d92fa   Nathanael Jourdane   Add JComboBox for...
224
		JComboBox<String> comboBox;
667dd80c   Nathanael Jourdane   JTextField as Par...
225

eb483599   Nathanael Jourdane   Add missing Param...
226
227
		DataProductTypeField(RequestView requestView, String paramName) {
			super(requestView, paramName);
a99d92fa   Nathanael Jourdane   Add JComboBox for...
228
229
230
231
232
233
234
235
236
237
238
239
240
			comboBox = new JComboBox(getItems());
			comboBox.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					onUpdate();
				}
			});
			this.add(comboBox);
		}

		private String[] getItems() {
			return new String[] { "All", "Image", "Spectrum", "Dynamic spectrum", "Spectral cube",
					"Profile", "Volume", "Movie", "Cube" };
eb483599   Nathanael Jourdane   Add missing Param...
241
242
		}

667dd80c   Nathanael Jourdane   JTextField as Par...
243
		private void onUpdate() {
a99d92fa   Nathanael Jourdane   Add JComboBox for...
244
245
			String value = comboBox.getSelectedItem().toString().replace(" ", "-").toLowerCase();
			requestView.updateParam(paramName, "All".equals(value) ? null : value);
eb483599   Nathanael Jourdane   Add missing Param...
246
247
248
249
		}
	}

	public static class TargetClassField extends ParamField {
a99d92fa   Nathanael Jourdane   Add JComboBox for...
250
		JComboBox<String> comboBox;
667dd80c   Nathanael Jourdane   JTextField as Par...
251

eb483599   Nathanael Jourdane   Add missing Param...
252
253
		TargetClassField(RequestView requestView, String paramName) {
			super(requestView, paramName);
a99d92fa   Nathanael Jourdane   Add JComboBox for...
254
255
256
257
258
259
260
261
262
263
264
265
266
			comboBox = new JComboBox(getItems());
			comboBox.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					onUpdate();
				}
			});
			this.add(comboBox);
		}

		private String[] getItems() {
			return new String[] { "All", "Comet", "Exoplanet", "Interplanetary medium", "Ring",
					"Sample", "Sky", "Spacecraft", "Spacejunk", "Star" };
eb483599   Nathanael Jourdane   Add missing Param...
267
268
		}

667dd80c   Nathanael Jourdane   JTextField as Par...
269
		private void onUpdate() {
a99d92fa   Nathanael Jourdane   Add JComboBox for...
270
271
			String value = comboBox.getSelectedItem().toString().replace(" ", "_").toLowerCase();
			requestView.updateParam(paramName, "All".equals(value) ? null : value);
eb483599   Nathanael Jourdane   Add missing Param...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
		}
	}

	// 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);
	}
}