Blame view

src/main/java/eu/omp/irap/vespa/epntapclient/view/ParamField.java 21.8 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 {
1e543ea0   Nathanael Jourdane   Code clean-up
57
58
	/** The serial version UID. */
	private static final long serialVersionUID = 1L;
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
59

5d3c344e   Nathanael Jourdane   Use Java logging ...
60
	/** The logger for the class ParamField. */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
61
	static final Logger logger = Logger.getLogger(ParamField.class.getName());
eb483599   Nathanael Jourdane   Add missing Param...
62

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

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

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

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

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

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

a227a22d   Nathanael Jourdane   Add comments.
81
	/** The regex used to validate the Date fields */
eb483599   Nathanael Jourdane   Add missing Param...
82
	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
83

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

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

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

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
96
97
98
	/**
	 * 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
99
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
100
101
102
	 * @param mainView The main view of the application.
	 * @param paramName The name of the parameter.
	 */
5af53be7   Nathanael Jourdane   Make the applicat...
103
	public ParamField(EpnTapMainView mainView, String paramName) {
eb483599   Nathanael Jourdane   Add missing Param...
104
		super();
5af53be7   Nathanael Jourdane   Make the applicat...
105
106
107
108

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

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
118
119
120
	/**
	 * 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
121
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
122
123
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
124
	public static class StringField extends ParamField implements TextFieldListener {
1e543ea0   Nathanael Jourdane   Code clean-up
125
126
127
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

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

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

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
157
158
159
160
	/**
	 * 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
161
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
162
163
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
164
	public static class FloatField extends ParamField implements TextFieldListener {
1e543ea0   Nathanael Jourdane   Code clean-up
165
166
167
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

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

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

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
204
205
206
207
208
	/**
	 * 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
209
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
210
211
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
212
	public static class DateRangeField extends ParamField implements TextFieldListener {
1e543ea0   Nathanael Jourdane   Code clean-up
213
214
215
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

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

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
222
223
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
224
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
225
226
227
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
228
229
		public DateRangeField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
68ae1315   Nathanael Jourdane   Improve GUI appar...
230
			this.add(new JLabel("min "));
667dd80c   Nathanael Jourdane   JTextField as Par...
231
			fieldMin = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
232
233
234
235
			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...
236
237
			this.add(fieldMin);

68ae1315   Nathanael Jourdane   Improve GUI appar...
238
			this.add(new JLabel("max "));
667dd80c   Nathanael Jourdane   JTextField as Par...
239
			fieldMax = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
240
241
242
243
			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...
244
245
246
			this.add(fieldMax);
		}

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
272
273
274
275
	/**
	 * 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
276
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
277
278
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
279
	public static class FloatRangeField extends ParamField implements TextFieldListener {
1e543ea0   Nathanael Jourdane   Code clean-up
280
281
282
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

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

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
289
290
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
291
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
292
293
294
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
295
296
		public FloatRangeField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
41133475   Nathanael Jourdane   build floatRangeF...
297
			fieldMin = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
298
299
			fieldMin.setName(ParamField.MIN_SUFFIX);
			ParamField.addChangeListener(this, fieldMin);
eb483599   Nathanael Jourdane   Add missing Param...
300
301
			this.add(fieldMin);

41133475   Nathanael Jourdane   build floatRangeF...
302
			fieldMax = new JTextField();
1e543ea0   Nathanael Jourdane   Code clean-up
303
304
			fieldMax.setName(ParamField.MAX_SUFFIX);
			ParamField.addChangeListener(this, fieldMax);
eb483599   Nathanael Jourdane   Add missing Param...
305
306
			this.add(fieldMax);
		}
41133475   Nathanael Jourdane   build floatRangeF...
307

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
308
309
310
		/**
		 * This method is called each time the field is modified.
		 */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
311
		@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
312
		public void update(JTextField field) {
41133475   Nathanael Jourdane   build floatRangeF...
313
314
			if ("".equals(field.getText())) {
				field.setBackground(Color.WHITE);
4268557f   Nathanael Jourdane   Fix some Sonar is...
315
				mainView.event(Event.PARAMETER_REMOVED, paramName + field.getName());
41133475   Nathanael Jourdane   build floatRangeF...
316
317
			} else {
				try {
4268557f   Nathanael Jourdane   Fix some Sonar is...
318
					mainView.event(Event.PARAMETER_CHANGED, paramName + field.getName(),
e97b40e8   Nathanael Jourdane   Make ParamField c...
319
							Float.parseFloat(field.getText()));
41133475   Nathanael Jourdane   build floatRangeF...
320
					field.setBackground(Color.WHITE);
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
321
				} catch (@SuppressWarnings("unused") NumberFormatException e) {
41133475   Nathanael Jourdane   build floatRangeF...
322
323
324
325
					field.setBackground(Color.PINK);
				}
			}
		}
eb483599   Nathanael Jourdane   Add missing Param...
326
327
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
328
329
330
331
332
	/**
	 * 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
333
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
334
335
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
336
	public static class TargetNameField extends ParamField implements TextFieldListener {
1e543ea0   Nathanael Jourdane   Code clean-up
337
338
339
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

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

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
346
347
348
349
350
		/**
		 * 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...
351
		String lastContent;
667dd80c   Nathanael Jourdane   JTextField as Par...
352

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
353
		/**
4268557f   Nathanael Jourdane   Fix some Sonar is...
354
355
356
357
358
359
360
361
362
363
364
365
		 * 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() {
			@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
366
							for (String s : TargetNameField.getItems(content)) {
4268557f   Nathanael Jourdane   Fix some Sonar is...
367
368
369
								comboBox.addItem(s);
							}
						} catch (CantSendQueryException e) {
1e543ea0   Nathanael Jourdane   Code clean-up
370
371
							ParamField.logger.log(Level.WARNING,
									"Can't get table names for the resolver", e);
4268557f   Nathanael Jourdane   Fix some Sonar is...
372
373
374
375
376
377
378
379
380
381
382
383
384
						}
						comboBox.getEditor().setItem(content);
					}
					if ("".equals(content)) {
						mainView.event(Event.PARAMETER_REMOVED, paramName);
					} else {
						mainView.event(Event.PARAMETER_CHANGED, paramName, content);
					}
				}
			}
		};

		/**
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
385
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
386
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
387
388
389
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
390
391
		public TargetNameField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
392
			comboBox = new JComboBox<>();
1e543ea0   Nathanael Jourdane   Code clean-up
393
394
			comboBox.setPreferredSize(
					new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
68ae1315   Nathanael Jourdane   Improve GUI appar...
395

f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
396
397
			comboBox.setEditable(true);
			field = (JTextField) comboBox.getEditor().getEditorComponent();
1e543ea0   Nathanael Jourdane   Code clean-up
398
			ParamField.addChangeListener(this, field);
f00cb6bb   Nathanael Jourdane   Add a JComboBox f...
399
400
401
			this.add(comboBox);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
402
403
		/**
		 * The method used to get target names propositions by asking to the resolver.
1e543ea0   Nathanael Jourdane   Code clean-up
404
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
405
406
		 * @param begining The beginning of the target_name.
		 * @return An array of Strings corresponding to the target names got.
d3a65e87   Nathanael Jourdane   Improve Javadoc.
407
		 * @throws CantSendQueryException If the resolver do not work.
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
408
		 */
d3a65e87   Nathanael Jourdane   Improve Javadoc.
409
		static String[] getItems(String begining) throws CantSendQueryException {
4268557f   Nathanael Jourdane   Fix some Sonar is...
410
			StringBuilder resolverResult;
1e543ea0   Nathanael Jourdane   Code clean-up
411
412
			resolverResult = VOTableConnection.sendGet(ParamField.RESOLVER_URL,
					"q=\"" + begining + "\"");
05b140ed   Nathanael Jourdane   TargetNameField J...
413
414
415
416
417
418
419
420
421
			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...
422
			return targetNames;
eb483599   Nathanael Jourdane   Add missing Param...
423
424
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
425
		/**
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
426
427
		 * This method is called each time the field is modified.
		 */
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
428
429
		@Override
		public void update(JTextField textField) {
3d80f3c3   Nathanael Jourdane   bugFix: targetNam...
430
			SwingUtilities.invokeLater(updateComboBox);
eb483599   Nathanael Jourdane   Add missing Param...
431
432
433
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
434
435
436
437
438
439
	/**
	 * 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
440
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
441
442
	 * @author N. Jourdane
	 */
eb483599   Nathanael Jourdane   Add missing Param...
443
	public static class DataProductTypeField extends ParamField {
1e543ea0   Nathanael Jourdane   Code clean-up
444
445
446
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
450
451
452
453
		/**
		 * 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
454
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
455
456
457
		 * @author N. Jourdane
		 */
		@SuppressWarnings("javadoc")
77184f22   Nathanael Jourdane   Use enums for Dat...
458
459
		enum DataProductType {
			// @noformat
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
460
461
462
463
			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...
464
465
			// @format

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

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
472
473
			/**
			 * Method constructor for the enumeration.
1e543ea0   Nathanael Jourdane   Code clean-up
474
			 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
475
476
477
478
			 * @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...
479
				this.name = name;
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
480
				this.id = id;
77184f22   Nathanael Jourdane   Use enums for Dat...
481
482
			}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
483
484
485
486
487
			/**
			 * @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...
488
489
490
491
492
493
494
495
496
497
498
499
			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...
500

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
501
502
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
503
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
504
505
506
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
507
508
		public DataProductTypeField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
77184f22   Nathanael Jourdane   Use enums for Dat...
509
510
			comboBox = new JComboBox<>(DataProductType.values());
			comboBox.setSelectedItem(DataProductType.ALL);
1e543ea0   Nathanael Jourdane   Code clean-up
511
512
			comboBox.setPreferredSize(
					new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
a99d92fa   Nathanael Jourdane   Add JComboBox for...
513
514
515
			comboBox.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
516
					update();
a99d92fa   Nathanael Jourdane   Add JComboBox for...
517
518
519
520
521
				}
			});
			this.add(comboBox);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
522
523
524
525
		/**
		 * This method is called each time the field is modified.
		 */
		void update() {
77184f22   Nathanael Jourdane   Use enums for Dat...
526
527
			DataProductType item = (DataProductType) comboBox.getSelectedItem();
			if (DataProductType.ALL.equals(item)) {
4268557f   Nathanael Jourdane   Fix some Sonar is...
528
				mainView.event(Event.PARAMETER_REMOVED, paramName);
5af53be7   Nathanael Jourdane   Make the applicat...
529
			} else {
4268557f   Nathanael Jourdane   Fix some Sonar is...
530
				mainView.event(Event.PARAMETER_CHANGED, paramName, item.query());
5af53be7   Nathanael Jourdane   Make the applicat...
531
			}
eb483599   Nathanael Jourdane   Add missing Param...
532
533
534
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
535
536
537
538
539
540
	/**
	 * 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
541
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
542
543
	 * @author N. Jourdane
	 */
eb483599   Nathanael Jourdane   Add missing Param...
544
	public static class TargetClassField extends ParamField {
1e543ea0   Nathanael Jourdane   Code clean-up
545
546
		/** The serial version UID. */
		private static final long serialVersionUID = 1L;
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
547
548

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

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
551
552
		/**
		 * An enumeration of all available target classes.
1e543ea0   Nathanael Jourdane   Code clean-up
553
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
554
555
556
		 * @author N. Jourdane
		 */
		@SuppressWarnings("javadoc")
77184f22   Nathanael Jourdane   Use enums for Dat...
557
558
		enum TargetClass {
			// @noformat
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
559
560
561
			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...
562
563
			// @format

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
564
			/** The name of the target class. */
77184f22   Nathanael Jourdane   Use enums for Dat...
565
566
			String name;

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
567
568
			/**
			 * Method constructor for the enumeration.
1e543ea0   Nathanael Jourdane   Code clean-up
569
			 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
570
571
			 * @param name The name of the target class.
			 */
77184f22   Nathanael Jourdane   Use enums for Dat...
572
573
574
575
			TargetClass(String name) {
				this.name = name;
			}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
576
577
578
			/**
			 * @return The name formated for the query.
			 */
77184f22   Nathanael Jourdane   Use enums for Dat...
579
580
581
582
			String query() {
				return name.replace(" ", "_").toLowerCase();
			}
		}
667dd80c   Nathanael Jourdane   JTextField as Par...
583

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
584
585
		/**
		 * Method constructor
1e543ea0   Nathanael Jourdane   Code clean-up
586
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
587
588
589
		 * @param mainView The main view of the application.
		 * @param paramName The name of the parameter.
		 */
5af53be7   Nathanael Jourdane   Make the applicat...
590
591
		public TargetClassField(EpnTapMainView mainView, String paramName) {
			super(mainView, paramName);
77184f22   Nathanael Jourdane   Use enums for Dat...
592
			comboBox = new JComboBox<>(TargetClass.values());
1e543ea0   Nathanael Jourdane   Code clean-up
593
594
			comboBox.setPreferredSize(
					new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
a99d92fa   Nathanael Jourdane   Add JComboBox for...
595
596
597
			comboBox.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
598
					update();
a99d92fa   Nathanael Jourdane   Add JComboBox for...
599
600
601
602
603
				}
			});
			this.add(comboBox);
		}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
604
605
606
607
		/**
		 * This method is called each time the field is modified.
		 */
		void update() {
77184f22   Nathanael Jourdane   Use enums for Dat...
608
609
			TargetClass value = (TargetClass) comboBox.getSelectedItem();
			if (TargetClass.ALL.equals(value)) {
4268557f   Nathanael Jourdane   Fix some Sonar is...
610
				mainView.event(Event.PARAMETER_REMOVED, paramName);
5af53be7   Nathanael Jourdane   Make the applicat...
611
			} else {
4268557f   Nathanael Jourdane   Fix some Sonar is...
612
				mainView.event(Event.PARAMETER_CHANGED, paramName, value.query());
5af53be7   Nathanael Jourdane   Make the applicat...
613
			}
eb483599   Nathanael Jourdane   Add missing Param...
614
615
616
		}
	}

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
617
618
619
620
	/**
	 * 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
621
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
622
623
	 * @author N. Jourdane
	 */
e97b40e8   Nathanael Jourdane   Make ParamField c...
624
	interface TextFieldListener {
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
625
626
		/**
		 * When the content of the JTextField is updated.
1e543ea0   Nathanael Jourdane   Code clean-up
627
		 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
628
629
630
		 * @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...
631
632
		void update(JTextField field);
	}
eb483599   Nathanael Jourdane   Add missing Param...
633

b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
634
635
	/**
	 * To add the listener. @see TextFieldListener
1e543ea0   Nathanael Jourdane   Code clean-up
636
	 *
b6b4fb3e   Nathanael Jourdane   Add Javadoc for P...
637
638
639
	 * @param changeListener The listener of text fields.
	 * @param field The field to listen.
	 */
42819b99   Nathanael Jourdane   Make EpnTAPClient...
640
	static void addChangeListener(final TextFieldListener changeListener, final JTextField field) {
e97b40e8   Nathanael Jourdane   Make ParamField c...
641
		field.getDocument().addDocumentListener(new DocumentListener() {
53d49e83   Nathanael Jourdane   Fix all Eclipse w...
642
			@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
643
644
			public void removeUpdate(DocumentEvent de) {
				changeListener.update(field);
eb483599   Nathanael Jourdane   Add missing Param...
645
646
			}

53d49e83   Nathanael Jourdane   Fix all Eclipse w...
647
			@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
648
649
			public void insertUpdate(DocumentEvent de) {
				changeListener.update(field);
eb483599   Nathanael Jourdane   Add missing Param...
650
651
			}

53d49e83   Nathanael Jourdane   Fix all Eclipse w...
652
			@Override
e97b40e8   Nathanael Jourdane   Make ParamField c...
653
654
			public void changedUpdate(DocumentEvent de) {
				changeListener.update(field);
eb483599   Nathanael Jourdane   Add missing Param...
655
			}
eb483599   Nathanael Jourdane   Add missing Param...
656
		});
eb483599   Nathanael Jourdane   Add missing Param...
657
658
	}
}