Blame view

src/main/java/eu/omp/irap/vespa/epntapclient/view/ParamField.java 21.9 KB
506d0c0b   Nathanael Jourdane   Add licence heade...
1
2
3
4
5
/*
 * This file is a part of EpnTAPClient.
 * This program aims to provide EPN-TAP support for software clients, like CASSIS spectrum analyzer.
 * See draft specifications: https://voparis-confluence.obspm.fr/pages/viewpage.action?pageId=559861
 * Copyright (C) 2016 Institut de Recherche en Astrophysique et Planétologie.
1e543ea0   Nathanael Jourdane   Code clean-up
6
 *
506d0c0b   Nathanael Jourdane   Add licence heade...
7
8
9
10
11
12
13
14
15
16
 * This program is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or (at your option) any later
 * version. This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU General Public License for more details. You should have received a copy of
 * the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */

eb483599   Nathanael Jourdane   Add missing Param...
17
18
19
20
package eu.omp.irap.vespa.epntapclient.view;

import java.awt.Color;
import java.awt.Dimension;
a99d92fa   Nathanael Jourdane   Add JComboBox for...
21
22
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
eb483599   Nathanael Jourdane   Add missing Param...
23
24
25
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
e7647bba   Nathanael Jourdane   change query to g...
26
import java.util.ArrayList;
e7647bba   Nathanael Jourdane   change query to g...
27
import java.util.List;
eb483599   Nathanael Jourdane   Add missing Param...
28
import java.util.Locale;
b6627be6   Nathanael Jourdane   Improve Exceptions
29
import java.util.logging.Level;
5d3c344e   Nathanael Jourdane   Use Java logging ...
30
import java.util.logging.Logger;
eb483599   Nathanael Jourdane   Add missing Param...
31
32

import javax.swing.BoxLayout;
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
33
import javax.swing.JComboBox;
eb483599   Nathanael Jourdane   Add missing Param...
34
35
36
37
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
eb483599   Nathanael Jourdane   Add missing Param...
38
39
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
eb483599   Nathanael Jourdane   Add missing Param...
40

05b140ed   Nathanael Jourdane   TargetNameField J...
41
42
43
44
45
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableConnection;
d3a65e87   Nathanael Jourdane   Improve Javadoc.
46
import eu.omp.irap.vespa.epntapclient.votable.controller.VOTableException.CantSendQueryException;
05b140ed   Nathanael Jourdane   TargetNameField J...
47

a227a22d   Nathanael Jourdane   Add comments.
48
/**
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
49
50
51
52
 * A field used to set a service parameter to build the query (in the parameter panel). ParamField
 * is an abstract method and all type of parameter field should extend it. See
 * https://voparis-confluence.obspm.fr/display/VES/4+-+EPN-TAP+queries to get all parameters
 * details.
1e543ea0   Nathanael Jourdane   Code clean-up
53
 *
a227a22d   Nathanael Jourdane   Add comments.
54
55
 * @author N. Jourdane
 */
eb483599   Nathanael Jourdane   Add missing Param...
56
public abstract class ParamField extends JPanel {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
57

1e543ea0   Nathanael Jourdane   Code clean-up
58
59
	/** The serial version UID. */
	private static final long serialVersionUID = 1L;
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
60

5d3c344e   Nathanael Jourdane   Use Java logging ...
61
	/** The logger for the class ParamField. */
869d1749   Nathanael Jourdane   remove unused log...
62
	protected static final Logger logger = Logger.getLogger(ParamField.class.getName());
eb483599   Nathanael Jourdane   Add missing Param...
63

a227a22d   Nathanael Jourdane   Add comments.
64
	/** The minimum width of the field. */
68ae1315   Nathanael Jourdane   Improve GUI appar...
65
	private static final int MIN_FIELD_WIDTH = 30;
1e543ea0   Nathanael Jourdane   Code clean-up
66

a227a22d   Nathanael Jourdane   Add comments.
67
	/** The preferred field height. */
68ae1315   Nathanael Jourdane   Improve GUI appar...
68
	private static final int FIELD_HEIGHT = 20;
1e543ea0   Nathanael Jourdane   Code clean-up
69

a227a22d   Nathanael Jourdane   Add comments.
70
	/** The maximum width of the field. */
68ae1315   Nathanael Jourdane   Improve GUI appar...
71
	private static final int MAX_FIELD_WIDTH = 400;
1e543ea0   Nathanael Jourdane   Code clean-up
72

a227a22d   Nathanael Jourdane   Add comments.
73
	/** The preferred label width. */
68ae1315   Nathanael Jourdane   Improve GUI appar...
74
75
	private static final int LABEL_WIDTH = 140;

a227a22d   Nathanael Jourdane   Add comments.
76
	/** The URL of the resolver used for the `target name` field. */
05b140ed   Nathanael Jourdane   TargetNameField J...
77
	private static final String RESOLVER_URL = "http://voparis-registry.obspm.fr/ssodnet/1/autocomplete";
1e543ea0   Nathanael Jourdane   Code clean-up
78

a227a22d   Nathanael Jourdane   Add comments.
79
	/** The date format used in the DateRange field */
eb483599   Nathanael Jourdane   Add missing Param...
80
	private static final String DATE_FORMAT = "dd/MM/yyyy";
1e543ea0   Nathanael Jourdane   Code clean-up
81

a227a22d   Nathanael Jourdane   Add comments.
82
	/** The regex used to validate the Date fields */
eb483599   Nathanael Jourdane   Add missing Param...
83
	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)$)";
1e543ea0   Nathanael Jourdane   Code clean-up
84

a227a22d   Nathanael Jourdane   Add comments.
85
	/** The suffix used in REG-TAP parameters names, indicating that it's a beginning of a range. */
eb483599   Nathanael Jourdane   Add missing Param...
86
	private static final String MIN_SUFFIX = "min";
1e543ea0   Nathanael Jourdane   Code clean-up
87

a227a22d   Nathanael Jourdane   Add comments.
88
	/** The suffix used in REG-TAP parameters names, indicating that it is a end of a range. */
eb483599   Nathanael Jourdane   Add missing Param...
89
90
	private static final String MAX_SUFFIX = "max";

a227a22d   Nathanael Jourdane   Add comments.
91
	/** The main view of the application. */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
92
	protected EpnTapMainView mainView;
1e543ea0   Nathanael Jourdane   Code clean-up
93

a227a22d   Nathanael Jourdane   Add comments.
94
	/** The parameter name of the field */
eb483599   Nathanael Jourdane   Add missing Param...
95
96
	protected String paramName;

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
97

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
98
99
100
	/**
	 * Method constructor for the parameter field abstract class, which do all common action for all
	 * type of field, such as displaying the name of the parameter.
1e543ea0   Nathanael Jourdane   Code clean-up
101
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
102
103
104
	 * @param mainView The main view of the application.
	 * @param paramName The name of the parameter.
	 */
5af53be7   Nathanael Jourdane   Make the applicat...
105
	public ParamField(EpnTapMainView mainView, String paramName) {
eb483599   Nathanael Jourdane   Add missing Param...
106
		super();
5af53be7   Nathanael Jourdane   Make the applicat...
107
108
109
110

		this.mainView = mainView;
		this.paramName = paramName;

1e543ea0   Nathanael Jourdane   Code clean-up
111
112
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		setMaximumSize(new Dimension(ParamField.MAX_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
eb483599   Nathanael Jourdane   Add missing Param...
113
114
		String strLabel = paramName.replaceAll("_", " ").trim();
		JLabel label = new JLabel(strLabel.substring(0, 1).toUpperCase() + strLabel.substring(1));
1e543ea0   Nathanael Jourdane   Code clean-up
115
		label.setPreferredSize(new Dimension(ParamField.LABEL_WIDTH, ParamField.FIELD_HEIGHT));
eb483599   Nathanael Jourdane   Add missing Param...
116
		this.add(label);
41133475   Nathanael Jourdane   build floatRangeF...
117
		// TODO: Add tooltip text based on rr.table_column.column_description
eb483599   Nathanael Jourdane   Add missing Param...
118
119
	}

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
120

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
121
122
123
	/**
	 * The string field is used for parameter with a `String` class. It is a simple JTextField with
	 * no verification. The parameter is sent to the controller each time it is modified.
1e543ea0   Nathanael Jourdane   Code clean-up
124
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
125
126
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
127
	public static class StringField extends ParamField implements TextFieldListener {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
128

1e543ea0   Nathanael Jourdane   Code clean-up
129
130
131
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
132
		/** The JTextField used to put the parameter value. */
667dd80c   Nathanael Jourdane   JTextField as Par...
133
134
		JTextField field;

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
135

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
136
137
		/**
		 * Method constructor for the string field.
1e543ea0   Nathanael Jourdane   Code clean-up
138
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
139
140
141
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
142
143
		public StringField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
667dd80c   Nathanael Jourdane   JTextField as Par...
144
			field = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
145
			ParamField.addChangeListener(this, field);
eb483599   Nathanael Jourdane   Add missing Param...
146
147
148
			this.add(field);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
149
150
151
		/**
		 * This method is called each time the field is modified.
		 */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
152
153
154
		@Override
		public void update(JTextField textField) {
			if ("".equals(textField.getText())) {
4268557f   Nathanael Jourdane   Fix some Sonar is...
155
				mainView.event(Event.PARAMETER_CHANGED, paramName, null);
eb483599   Nathanael Jourdane   Add missing Param...
156
			} else {
4268557f   Nathanael Jourdane   Fix some Sonar is...
157
				mainView.event(Event.PARAMETER_CHANGED, paramName, textField.getText());
eb483599   Nathanael Jourdane   Add missing Param...
158
159
160
161
			}
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
162
163
164
165
	/**
	 * The float field is used for parameter with a `Float` class. It is a JTextField which checks
	 * if the content is a valid float. If the parameter is valid or if it is empty, then the float
	 * value is sent to the controller.
1e543ea0   Nathanael Jourdane   Code clean-up
166
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
167
168
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
169
	public static class FloatField extends ParamField implements TextFieldListener {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
170

1e543ea0   Nathanael Jourdane   Code clean-up
171
172
173
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
174
		/** The JTextField used to put the parameter value. */
667dd80c   Nathanael Jourdane   JTextField as Par...
175
176
		JTextField field;

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
177

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
178
179
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
180
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
181
182
183
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
184
185
		public FloatField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
667dd80c   Nathanael Jourdane   JTextField as Par...
186
			field = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
187
			ParamField.addChangeListener(this, field);
eb483599   Nathanael Jourdane   Add missing Param...
188
189
190
			this.add(field);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
191
192
193
		/**
		 * This method is called each time the field is modified.
		 */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
194
195
196
197
		@Override
		public void update(JTextField textField) {
			if ("".equals(textField.getText())) {
				textField.setBackground(Color.WHITE);
4268557f   Nathanael Jourdane   Fix some Sonar is...
198
				mainView.event(Event.PARAMETER_REMOVED, paramName);
eb483599   Nathanael Jourdane   Add missing Param...
199
200
			} else {
				try {
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
201
					float value = Float.parseFloat(textField.getText());
4268557f   Nathanael Jourdane   Fix some Sonar is...
202
					mainView.event(Event.PARAMETER_CHANGED, paramName, value);
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
203
204
205
					textField.setBackground(Color.WHITE);
				} catch (@SuppressWarnings("unused") NumberFormatException e) {
					textField.setBackground(Color.PINK);
eb483599   Nathanael Jourdane   Add missing Param...
206
207
208
209
210
				}
			}
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
211
212
213
214
215
	/**
	 * The date range field is used for couples of parameter with both a `Date` type (actually only
	 * `time_min` and `time_max` parameters is concerned for now). These are JTextFields which check
	 * if the content is a valid date, according to DATE_FORMAT. If the parameter is valid or if it
	 * is empty, then the dates value are sent to the controller, in Julian Day format.
1e543ea0   Nathanael Jourdane   Code clean-up
216
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
217
218
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
219
	public static class DateRangeField extends ParamField implements TextFieldListener {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
220

1e543ea0   Nathanael Jourdane   Code clean-up
221
222
223
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
224
		/** The JTextField used to put the parameter minimum value of the range. */
667dd80c   Nathanael Jourdane   JTextField as Par...
225
		JTextField fieldMin;
1e543ea0   Nathanael Jourdane   Code clean-up
226

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
227
		/** The JTextField used to put the parameter maximum value of the range. */
667dd80c   Nathanael Jourdane   JTextField as Par...
228
229
		JTextField fieldMax;

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
230

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
231
232
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
233
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
234
235
236
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
237
238
		public DateRangeField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
68ae1315   Nathanael Jourdane   Improve GUI appar...
239
			this.add(new JLabel("min "));
667dd80c   Nathanael Jourdane   JTextField as Par...
240
			fieldMin = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
241
242
243
244
			fieldMin.setName(ParamField.MIN_SUFFIX);
			fieldMin.setPreferredSize(
					new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
			ParamField.addChangeListener(this, fieldMin);
eb483599   Nathanael Jourdane   Add missing Param...
245
246
			this.add(fieldMin);

68ae1315   Nathanael Jourdane   Improve GUI appar...
247
			this.add(new JLabel("max "));
667dd80c   Nathanael Jourdane   JTextField as Par...
248
			fieldMax = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
249
250
251
252
			fieldMax.setName(ParamField.MAX_SUFFIX);
			fieldMax.setPreferredSize(
					new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
			ParamField.addChangeListener(this, fieldMin);
eb483599   Nathanael Jourdane   Add missing Param...
253
254
255
			this.add(fieldMax);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
256
257
258
		/**
		 * This method is called each time the field is modified.
		 */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
259
		@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
260
		public void update(JTextField field) {
1e543ea0   Nathanael Jourdane   Code clean-up
261
			DateFormat df = new SimpleDateFormat(ParamField.DATE_FORMAT, Locale.ENGLISH);
eb483599   Nathanael Jourdane   Add missing Param...
262
263
			if ("".equals(field.getText())) {
				field.setBackground(Color.WHITE);
4268557f   Nathanael Jourdane   Fix some Sonar is...
264
				mainView.event(Event.PARAMETER_REMOVED, paramName + field.getName());
1e543ea0   Nathanael Jourdane   Code clean-up
265
			} else if (field.getText().matches(ParamField.DATE_REGEX)) {
eb483599   Nathanael Jourdane   Add missing Param...
266
267
				try {
					long date = df.parse(field.getText()).getTime();
1e543ea0   Nathanael Jourdane   Code clean-up
268
					date = Math.round(date / 86400000.0 + 2440587.5); // to JD
4268557f   Nathanael Jourdane   Fix some Sonar is...
269
					mainView.event(Event.PARAMETER_CHANGED, paramName + field.getName(), date);
eb483599   Nathanael Jourdane   Add missing Param...
270
					field.setBackground(Color.WHITE);
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
271
				} catch (@SuppressWarnings("unused") ParseException e) {
eb483599   Nathanael Jourdane   Add missing Param...
272
273
274
275
276
277
278
279
280
					field.setBackground(Color.PINK);
				}
				// TODO: check if date min < date max
			} else {
				field.setBackground(Color.PINK);
			}
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
281
282
283
284
	/**
	 * The float range field is used for couples of parameter with both a `Float` class. These are
	 * JTextFields which check if the content is a valid float. If the parameter is valid or if it
	 * is empty, then the float value are sent to the controller.
1e543ea0   Nathanael Jourdane   Code clean-up
285
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
286
287
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
288
	public static class FloatRangeField extends ParamField implements TextFieldListener {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
289

1e543ea0   Nathanael Jourdane   Code clean-up
290
291
292
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
293
		/** The JTextField used to put the parameter minimum value of the range. */
41133475   Nathanael Jourdane   build floatRangeF...
294
		JTextField fieldMin;
1e543ea0   Nathanael Jourdane   Code clean-up
295

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
296
		/** The JTextField used to put the parameter maximum value of the range. */
41133475   Nathanael Jourdane   build floatRangeF...
297
		JTextField fieldMax;
eb483599   Nathanael Jourdane   Add missing Param...
298

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
299

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
300
301
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
302
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
303
304
305
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
306
307
		public FloatRangeField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
41133475   Nathanael Jourdane   build floatRangeF...
308
			fieldMin = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
309
310
			fieldMin.setName(ParamField.MIN_SUFFIX);
			ParamField.addChangeListener(this, fieldMin);
eb483599   Nathanael Jourdane   Add missing Param...
311
312
			this.add(fieldMin);

41133475   Nathanael Jourdane   build floatRangeF...
313
			fieldMax = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
314
315
			fieldMax.setName(ParamField.MAX_SUFFIX);
			ParamField.addChangeListener(this, fieldMax);
eb483599   Nathanael Jourdane   Add missing Param...
316
317
			this.add(fieldMax);
		}
41133475   Nathanael Jourdane   build floatRangeF...
318

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
319
320
321
		/**
		 * This method is called each time the field is modified.
		 */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
322
		@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
323
		public void update(JTextField field) {
41133475   Nathanael Jourdane   build floatRangeF...
324
325
			if ("".equals(field.getText())) {
				field.setBackground(Color.WHITE);
4268557f   Nathanael Jourdane   Fix some Sonar is...
326
				mainView.event(Event.PARAMETER_REMOVED, paramName + field.getName());
41133475   Nathanael Jourdane   build floatRangeF...
327
328
			} else {
				try {
4268557f   Nathanael Jourdane   Fix some Sonar is...
329
					mainView.event(Event.PARAMETER_CHANGED, paramName + field.getName(),
e97b40e8   Nathanael Jourdane   Make ParamField c...
330
							Float.parseFloat(field.getText()));
41133475   Nathanael Jourdane   build floatRangeF...
331
					field.setBackground(Color.WHITE);
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
332
				} catch (@SuppressWarnings("unused") NumberFormatException e) {
41133475   Nathanael Jourdane   build floatRangeF...
333
334
335
336
					field.setBackground(Color.PINK);
				}
			}
		}
eb483599   Nathanael Jourdane   Add missing Param...
337
338
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
339
340
341
342
343
	/**
	 * The target name field is used only for the `target_name` parameter. It is a ComboBox which is
	 * automatically filled with actual target names which begins by the entered characters, by
	 * asking to an online resolver (RESOLVER_URL). The parameter is sent to the controller each
	 * time it is updated, so it is possible to enter a parameter that the resolver do not know.
1e543ea0   Nathanael Jourdane   Code clean-up
344
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
345
346
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
347
	public static class TargetNameField extends ParamField implements TextFieldListener {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
348

1e543ea0   Nathanael Jourdane   Code clean-up
349
350
351
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
352
		/** The comboBox to enter the target_name and display target name propositions. */
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
353
		JComboBox<String> comboBox;
1e543ea0   Nathanael Jourdane   Code clean-up
354

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
355
		/** The JTextField related to the ComboBox, allowing to listen for text content update. */
667dd80c   Nathanael Jourdane   JTextField as Par...
356
		JTextField field;
1e543ea0   Nathanael Jourdane   Code clean-up
357

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
358
359
360
361
362
		/**
		 * The content of the last entered value. It is used to avoid recursions, because each time
		 * an update event is detected, the resolver is called and the ComboBox is filled with new
		 * values, which trigger a new event.
		 */
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
363
		String lastContent;
667dd80c   Nathanael Jourdane   JTextField as Par...
364

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
365
		/**
4268557f   Nathanael Jourdane   Fix some Sonar is...
366
367
368
369
		 * This method is called each time the field is modified. A Runnable is used it is
		 * impossible to modify the comboBox from a DocumentEvent.
		 */
		Runnable updateComboBox = new Runnable() {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
370

4268557f   Nathanael Jourdane   Fix some Sonar is...
371
372
373
374
375
376
377
378
			@Override
			public void run() {
				String content = field.getText();
				if (!content.equals(lastContent)) {
					if (content.length() >= 2) {
						lastContent = content;
						comboBox.removeAllItems();
						try {
1e543ea0   Nathanael Jourdane   Code clean-up
379
							for (String s : TargetNameField.getItems(content)) {
4268557f   Nathanael Jourdane   Fix some Sonar is...
380
381
382
								comboBox.addItem(s);
							}
						} catch (CantSendQueryException e) {
1e543ea0   Nathanael Jourdane   Code clean-up
383
384
							ParamField.logger.log(Level.WARNING,
									"Can't get table names for the resolver", e);
4268557f   Nathanael Jourdane   Fix some Sonar is...
385
386
387
388
389
390
391
392
393
394
395
396
						}
						comboBox.getEditor().setItem(content);
					}
					if ("".equals(content)) {
						mainView.event(Event.PARAMETER_REMOVED, paramName);
					} else {
						mainView.event(Event.PARAMETER_CHANGED, paramName, content);
					}
				}
			}
		};

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
397

4268557f   Nathanael Jourdane   Fix some Sonar is...
398
		/**
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
399
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
400
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
401
402
403
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
404
405
		public TargetNameField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
406
			comboBox = new JComboBox<>();
1e543ea0   Nathanael Jourdane   Code clean-up
407
408
			comboBox.setPreferredSize(
					new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
68ae1315   Nathanael Jourdane   Improve GUI appar...
409

f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
410
411
			comboBox.setEditable(true);
			field = (JTextField) comboBox.getEditor().getEditorComponent();
1e543ea0   Nathanael Jourdane   Code clean-up
412
			ParamField.addChangeListener(this, field);
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
413
414
415
			this.add(comboBox);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
416
417
		/**
		 * The method used to get target names propositions by asking to the resolver.
1e543ea0   Nathanael Jourdane   Code clean-up
418
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
419
420
		 * @param begining The beginning of the target_name.
		 * @return An array of Strings corresponding to the target names got.
d3a65e87   Nathanael Jourdane   Improve Javadoc.
421
		 * @throws CantSendQueryException If the resolver do not work.
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
422
		 */
d3a65e87   Nathanael Jourdane   Improve Javadoc.
423
		static String[] getItems(String begining) throws CantSendQueryException {
4268557f   Nathanael Jourdane   Fix some Sonar is...
424
			StringBuilder resolverResult;
1e543ea0   Nathanael Jourdane   Code clean-up
425
426
			resolverResult = VOTableConnection.sendGet(ParamField.RESOLVER_URL,
					"q=\"" + begining + "\"");
05b140ed   Nathanael Jourdane   TargetNameField J...
427
428
429
430
431
432
433
434
435
			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...
436
			return targetNames;
eb483599   Nathanael Jourdane   Add missing Param...
437
438
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
439
		/**
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
440
441
		 * This method is called each time the field is modified.
		 */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
442
443
		@Override
		public void update(JTextField textField) {
3d80f3c3   Nathanael Jourdane   bugFix: targetNam...
444
			SwingUtilities.invokeLater(updateComboBox);
eb483599   Nathanael Jourdane   Add missing Param...
445
446
447
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
448
449
450
451
452
453
	/**
	 * The data product type field is used only for the `dataproduct_type` parameter. It is a
	 * ComboBox filled with a list of static data product types (see
	 * https://voparis-confluence.obspm.fr/display/VES/4+-+EPN-TAP+queries#id-4-EPN-TAPqueries-
	 * __RefHeading__35_312326667_Toc3037660444.2.4DataProductType). The parameter is sent to the
	 * controller each time it is updated.
1e543ea0   Nathanael Jourdane   Code clean-up
454
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
455
456
	 * @author N. Jourdane
	 */
eb483599   Nathanael Jourdane   Add missing Param...
457
	public static class DataProductTypeField extends ParamField {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
458

1e543ea0   Nathanael Jourdane   Code clean-up
459
460
461
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
462
		/** The comboBox used to select the data product type. */
77184f22   Nathanael Jourdane   Use enums for Dat...
463
464
		JComboBox<DataProductType> comboBox;

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
465

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
466
467
468
469
		/**
		 * An enumeration of all available data product types. Each values comes with an id because
		 * EPN-TAP table can possibly be filled with the id instead of the name, so the query have
		 * to ask for both of them.
1e543ea0   Nathanael Jourdane   Code clean-up
470
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
471
472
473
		 * @author N. Jourdane
		 */
		@SuppressWarnings("javadoc")
77184f22   Nathanael Jourdane   Use enums for Dat...
474
475
		enum DataProductType {
			// @noformat
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
476
477
478
479
			ALL("All", "all"),            IM("Image", "im"),         SP("Spectrum", "sp"),
			DS("Dynamic spectrum", "ds"), SC("Spectral cube", "sc"), PR("Profile", "pr"),
			VO("Volume", "vo"),           MO("Movie", "mo"),         CU("Cube", "cu"),
			TS("Time series", "ts"),      CA("Catalog", "ca"),       SV("Spatial vector", "sv");
77184f22   Nathanael Jourdane   Use enums for Dat...
480
481
			// @format

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
482
			/** The full name of the data product type, such as `Dynamic spectrum`. */
77184f22   Nathanael Jourdane   Use enums for Dat...
483
			private String name = "";
1e543ea0   Nathanael Jourdane   Code clean-up
484

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
485
			/** The id of the data product type, such as `ds`. */
77184f22   Nathanael Jourdane   Use enums for Dat...
486
487
			private String id = "";

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
488

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
489
490
			/**
			 * Method constructor for the enumeration.
1e543ea0   Nathanael Jourdane   Code clean-up
491
			 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
492
493
494
495
			 * @param name The full name of the data product type, such as `Dynamic spectrum`.
			 * @param id The id of the data product type, such as `ds`.
			 */
			DataProductType(String name, String id) {
77184f22   Nathanael Jourdane   Use enums for Dat...
496
				this.name = name;
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
497
				this.id = id;
77184f22   Nathanael Jourdane   Use enums for Dat...
498
499
			}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
500
501
502
503
504
			/**
			 * @return A list of two strings, containing the name (formated for the query) and the
			 *         id, used in the query. A list is used instead of a array because the getQuery
			 *         function ( @see Queries) needs to know the parameter type.
			 */
77184f22   Nathanael Jourdane   Use enums for Dat...
505
506
507
508
509
510
511
512
513
514
515
516
			public List<String> query() {
				List<String> item = new ArrayList<>();
				item.add(name.replace(" ", "-").toLowerCase());
				item.add(id);
				return item;
			}

			@Override
			public String toString() {
				return name;
			}
		}
667dd80c   Nathanael Jourdane   JTextField as Par...
517

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
518

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
519
520
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
521
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
522
523
524
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
525
526
		public DataProductTypeField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
77184f22   Nathanael Jourdane   Use enums for Dat...
527
528
			comboBox = new JComboBox<>(DataProductType.values());
			comboBox.setSelectedItem(DataProductType.ALL);
1e543ea0   Nathanael Jourdane   Code clean-up
529
530
			comboBox.setPreferredSize(
					new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
a99d92fa   Nathanael Jourdane   Add JComboBox for...
531
			comboBox.addActionListener(new ActionListener() {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
532

a99d92fa   Nathanael Jourdane   Add JComboBox for...
533
534
				@Override
				public void actionPerformed(ActionEvent e) {
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
535
					update();
a99d92fa   Nathanael Jourdane   Add JComboBox for...
536
537
538
539
540
				}
			});
			this.add(comboBox);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
541
542
543
544
		/**
		 * This method is called each time the field is modified.
		 */
		void update() {
77184f22   Nathanael Jourdane   Use enums for Dat...
545
546
			DataProductType item = (DataProductType) comboBox.getSelectedItem();
			if (DataProductType.ALL.equals(item)) {
4268557f   Nathanael Jourdane   Fix some Sonar is...
547
				mainView.event(Event.PARAMETER_REMOVED, paramName);
5af53be7   Nathanael Jourdane   Make the applicat...
548
			} else {
4268557f   Nathanael Jourdane   Fix some Sonar is...
549
				mainView.event(Event.PARAMETER_CHANGED, paramName, item.query());
5af53be7   Nathanael Jourdane   Make the applicat...
550
			}
eb483599   Nathanael Jourdane   Add missing Param...
551
552
553
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
554
555
556
557
558
559
	/**
	 * The target class field is used only for the `target_class` parameter. It is a ComboBox filled
	 * with a list of static target classes (see
	 * https://voparis-confluence.obspm.fr/display/VES/4+-+EPN-TAP+queries#id-4-EPN-TAPqueries-
	 * __RefHeading__39_312326667_Toc3037660464.2.6TargetClass). The parameter is sent to the
	 * controller each time it is updated.
1e543ea0   Nathanael Jourdane   Code clean-up
560
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
561
562
	 * @author N. Jourdane
	 */
eb483599   Nathanael Jourdane   Add missing Param...
563
	public static class TargetClassField extends ParamField {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
564

1e543ea0   Nathanael Jourdane   Code clean-up
565
566
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
567
568

		/** The comboBox used to select the target class. */
77184f22   Nathanael Jourdane   Use enums for Dat...
569
570
		JComboBox<TargetClass> comboBox;

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
571

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
572
573
		/**
		 * An enumeration of all available target classes.
1e543ea0   Nathanael Jourdane   Code clean-up
574
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
575
576
577
		 * @author N. Jourdane
		 */
		@SuppressWarnings("javadoc")
77184f22   Nathanael Jourdane   Use enums for Dat...
578
579
		enum TargetClass {
			// @noformat
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
580
581
582
			ALL("All"),        COMET("Comet"),   EXOPLANET("Exoplanet"),    RING("Ring"),
			SAMPLE("Sample"),  SKY("Sky"),       SPACECRAFT("Spacecraft"),  SPACEJUNK("Spacejunk"),
			STAR("Star"),      INTERPLANETARY_MEDIUM("Interplanetary medium");
77184f22   Nathanael Jourdane   Use enums for Dat...
583
584
			// @format

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
585
			/** The name of the target class. */
77184f22   Nathanael Jourdane   Use enums for Dat...
586
587
			String name;

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
588

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
589
590
			/**
			 * Method constructor for the enumeration.
1e543ea0   Nathanael Jourdane   Code clean-up
591
			 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
592
593
			 * @param name The name of the target class.
			 */
77184f22   Nathanael Jourdane   Use enums for Dat...
594
595
596
597
			TargetClass(String name) {
				this.name = name;
			}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
598
599
600
			/**
			 * @return The name formated for the query.
			 */
77184f22   Nathanael Jourdane   Use enums for Dat...
601
602
603
604
			String query() {
				return name.replace(" ", "_").toLowerCase();
			}
		}
667dd80c   Nathanael Jourdane   JTextField as Par...
605

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
606

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
607
608
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
609
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
610
611
612
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
613
614
		public TargetClassField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
77184f22   Nathanael Jourdane   Use enums for Dat...
615
			comboBox = new JComboBox<>(TargetClass.values());
1e543ea0   Nathanael Jourdane   Code clean-up
616
617
			comboBox.setPreferredSize(
					new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
a99d92fa   Nathanael Jourdane   Add JComboBox for...
618
			comboBox.addActionListener(new ActionListener() {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
619

a99d92fa   Nathanael Jourdane   Add JComboBox for...
620
621
				@Override
				public void actionPerformed(ActionEvent e) {
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
622
					update();
a99d92fa   Nathanael Jourdane   Add JComboBox for...
623
624
625
626
627
				}
			});
			this.add(comboBox);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
628
629
630
631
		/**
		 * This method is called each time the field is modified.
		 */
		void update() {
77184f22   Nathanael Jourdane   Use enums for Dat...
632
633
			TargetClass value = (TargetClass) comboBox.getSelectedItem();
			if (TargetClass.ALL.equals(value)) {
4268557f   Nathanael Jourdane   Fix some Sonar is...
634
				mainView.event(Event.PARAMETER_REMOVED, paramName);
5af53be7   Nathanael Jourdane   Make the applicat...
635
			} else {
4268557f   Nathanael Jourdane   Fix some Sonar is...
636
				mainView.event(Event.PARAMETER_CHANGED, paramName, value.query());
5af53be7   Nathanael Jourdane   Make the applicat...
637
			}
eb483599   Nathanael Jourdane   Add missing Param...
638
639
640
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
641
642
643
644
	/**
	 * The listener of text field, it aims to provide a simple way to listen a text field without to
	 * override removeUpdate(DocumentEvent de), insertUpdate(DocumentEvent de) and
	 * changedUpdate(DocumentEvent de) on each field to listen.
1e543ea0   Nathanael Jourdane   Code clean-up
645
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
646
647
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
648
	interface TextFieldListener {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
649

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
650
651
		/**
		 * When the content of the JTextField is updated.
1e543ea0   Nathanael Jourdane   Code clean-up
652
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
653
654
655
		 * @param field The JTextField. Is useful for classes containing several text fields, such
		 *            as DateRangeField, to know which one triggered the event.
		 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
656
657
		void update(JTextField field);
	}
eb483599   Nathanael Jourdane   Add missing Param...
658

aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
659

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
660
661
	/**
	 * To add the listener. @see TextFieldListener
1e543ea0   Nathanael Jourdane   Code clean-up
662
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
663
664
665
	 * @param changeListener The listener of text fields.
	 * @param field The field to listen.
	 */
42819b99   Nathanael Jourdane   Make EpnTAPClient...
666
	static void addChangeListener(final TextFieldListener changeListener, final JTextField field) {
e97b40e8   Nathanael Jourdane   Make ParamField c...
667
		field.getDocument().addDocumentListener(new DocumentListener() {
aa2a59ba   Nathanael Jourdane   [coding style] 2 ...
668

53d49e83   Nathanael Jourdane   Fix all Eclipse w...
669
			@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
670
671
			public void removeUpdate(DocumentEvent de) {
				changeListener.update(field);
eb483599   Nathanael Jourdane   Add missing Param...
672
673
			}

53d49e83   Nathanael Jourdane   Fix all Eclipse w...
674
			@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
675
676
			public void insertUpdate(DocumentEvent de) {
				changeListener.update(field);
eb483599   Nathanael Jourdane   Add missing Param...
677
678
			}

53d49e83   Nathanael Jourdane   Fix all Eclipse w...
679
			@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
680
681
			public void changedUpdate(DocumentEvent de) {
				changeListener.update(field);
eb483599   Nathanael Jourdane   Add missing Param...
682
			}
eb483599   Nathanael Jourdane   Add missing Param...
683
		});
eb483599   Nathanael Jourdane   Add missing Param...
684
685
	}
}