diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/EpnTapMainApp.java b/src/main/java/eu/omp/irap/vespa/epntapclient/EpnTapMainApp.java
index cd9931e..a1d05fe 100644
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/EpnTapMainApp.java
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/EpnTapMainApp.java
@@ -23,8 +23,8 @@ import javax.swing.SwingUtilities;
import com.google.gson.Gson;
-import eu.omp.irap.vespa.epntapclient.gui.EpnTapMainView;
-import eu.omp.irap.vespa.epntapclient.gui.GUIController;
+import eu.omp.irap.vespa.epntapclient.gui.mainPanel.MainPanelView;
+import eu.omp.irap.vespa.epntapclient.gui.mainPanel.MainPanelController;
/**
* Simple class to have a main function to launch the EPNTap client.
@@ -55,12 +55,12 @@ public class EpnTapMainApp {
return;
}
- GUIController guiCtrl = new GUIController();
+ MainPanelController guiCtrl = new MainPanelController();
guiCtrl.readServices();
SwingUtilities.invokeLater(EpnTapMainApp.run(guiCtrl.getView(), "EPN-TAP client"));
}
- private static Runnable run(final EpnTapMainView voTableView, final String title) {
+ private static Runnable run(final MainPanelView voTableView, final String title) {
return new Runnable() {
@Override
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/EpnTapMainView.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/EpnTapMainView.java
deleted file mode 100644
index aa94ba1..0000000
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/EpnTapMainView.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.
- *
- * 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
- * .
- */
-
-package eu.omp.irap.vespa.epntapclient.gui;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JSplitPane;
-
-import eu.omp.irap.vespa.epntapclient.gui.panels.RequestPanel;
-import eu.omp.irap.vespa.epntapclient.gui.panels.ResultsPanel;
-import eu.omp.irap.vespa.epntapclient.gui.panels.ServicesPanel;
-
-/**
- * The main view of the application, which manage all the other views.
- *
- * @author N. Jourdane
- */
-public class EpnTapMainView extends JPanel {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The JPanel where the VOTable results is displayed. */
- private ResultsPanel resultsPanel;
-
- /** The JPanel where the list of services is displayed. */
- private ServicesPanel servicesPanel;
-
- /** The JPanel where the user build the query. */
- private RequestPanel requestPanel;
-
-
- /**
- * The main view constructor, which create all the panels.
- *
- * @param voTableServicesView The view to put in the services panel, built by ServicesController
- * @param voTableResultsView The view to put in the results panel, built by ResultsController.
- */
-
- public EpnTapMainView(ViewListener viewListener) {
- servicesPanel = new ServicesPanel(viewListener);
- resultsPanel = new ResultsPanel(viewListener);
- requestPanel = new RequestPanel(viewListener);
- buildMainView();
- }
-
- /**
- * Build and fill the GUI.
- */
- private void buildMainView() {
- setLayout(new BorderLayout());
-
- JSplitPane northPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, servicesPanel,
- requestPanel);
- JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, northPanel, resultsPanel);
-
- add(mainPanel, BorderLayout.CENTER);
-
- setSizes();
- }
-
- private void setSizes() {
- servicesPanel.setPreferredSize(
- new Dimension(GUIDim.LEFT_PANEL_WIDTH, GUIDim.TOP_PANEL_HEIGHT));
- servicesPanel.setMinimumSize(
- new Dimension(GUIDim.LEFT_PANEL_MIN_WIDTH, GUIDim.TOP_PANEL_MIN_HEIGHT));
-
- requestPanel.setPreferredSize(
- new Dimension(GUIDim.RIGHT_PANEL_WIDTH, GUIDim.TOP_PANEL_HEIGHT));
- requestPanel.setMinimumSize(
- new Dimension(GUIDim.RIGHT_PANEL_MIN_WIDTH, GUIDim.TOP_PANEL_MIN_HEIGHT));
-
- resultsPanel.setPreferredSize(
- new Dimension(GUIDim.LEFT_PANEL_MIN_WIDTH + GUIDim.RIGHT_PANEL_MIN_WIDTH,
- GUIDim.BOTTOM_PANEL_HEIGHT));
- resultsPanel.setMinimumSize(
- new Dimension(GUIDim.LEFT_PANEL_MIN_WIDTH + GUIDim.RIGHT_PANEL_MIN_WIDTH,
- GUIDim.BOTTOM_PANEL_MIN_HEIGHT));
- }
-
- /**
- * @return The JPanel where the VOTable result is displayed.
- */
- public ResultsPanel getResultsPanel() {
- return resultsPanel;
- }
-
- /**
- * @return The JPanel containing the GUI elements to build the query.
- */
- public RequestPanel getRequestPanel() {
- return requestPanel;
- }
-
- /**
- * @return The JPanel where the list of services is displayed.
- */
- public ServicesPanel getServicesPanel() {
- return servicesPanel;
- }
-
- /**
- * Display an error message. Usually used each time an error happens.
- *
- * @param title The title of the error.
- * @param message The message of the error.
- */
- public void displayError(String title, String message) {
- JOptionPane.showMessageDialog(this, message, title,
- JOptionPane.ERROR_MESSAGE);
- }
-
-}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/GUIController.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/GUIController.java
deleted file mode 100644
index 976d276..0000000
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/GUIController.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.
- *
- * 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
- * .
- */
-
-package eu.omp.irap.vespa.epntapclient.gui;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.JOptionPane;
-
-import eu.omp.irap.vespa.epntapclient.EpnTapController;
-import eu.omp.irap.vespa.epntapclient.service.Queries;
-import eu.omp.irap.vespa.votable.controller.CantGetVOTableException;
-
-/**
- * @author N. Jourdane
- */
-public class GUIController extends EpnTapController implements ViewListener {
-
- /** The logger for the class GUIController. */
- private static final Logger logger = Logger.getLogger(GUIController.class.getName());
-
- private EpnTapMainView mainView;
-
- private String voTablePath;
-
- /** The name of the table selected by the user on the table list panel. */
- private String selectedTableName;
-
- /** The URL of the service corresponding to the selected table. */
- private String selectedTableServiceURL;
-
-
- public GUIController() {
- super();
- mainView = new EpnTapMainView(this);
- }
-
- @Override
- public void readServices() {
- try {
- servicesCtrl.readTable();
- } catch (CantGetVOTableException e) {
- displayError("Can not get services.", e);
- }
- mainView.getServicesPanel().fillTable(servicesCtrl.getVOTableData());
- }
-
- public EpnTapMainView getView() {
- return mainView;
- }
-
- /** Update the row selected by the user on the Services Panel. */
- @Override
- public void onServiceSelected(int selectedServiceRow) {
- String url = mainView.getServicesPanel().getServiceURL(selectedServiceRow);
- String tableName = mainView.getServicesPanel().getTableName(selectedServiceRow);
- updateService(url, tableName);
- }
-
- /** Send the specified query on selectedTableServiceURL */
- @Override
- public void onSendButtonClicked(String query) {
- GUIController.logger.info("Sending query: " + query + " on " + selectedTableServiceURL);
- try {
- voTablePath = sendQuery(query, selectedTableServiceURL);
- } catch (CantGetVOTableException e) {
- displayError("Can not send the query.", e);
- GUIController.logger.log(Level.WARNING, "Can not send query.", e);
- }
-
- mainView.getResultsPanel().fillTable(resultsCtrl.getVOTableData());
- }
-
- @Override
- public void displayError(String message, Exception e) {
- logger.log(Level.SEVERE, message, e);
- JOptionPane.showMessageDialog(mainView, e.getMessage(), message, JOptionPane.ERROR_MESSAGE);
- }
-
- /** Copy the VOTable to a specified location. */
- @Override
- public void onDownloadButtonClicked(File outputFile) {
- try {
- Files.copy(Paths.get(voTablePath), Paths.get(outputFile.getAbsolutePath()));
- } catch (IOException e) {
- // TODO create exception
- mainView.displayError("Can not save the file.",
- "Check that you can write on the specified directory.");
- GUIController.logger.log(Level.WARNING, "Can not save the file.", e);
- }
- }
-
- /** Update a query parameter in the parameter list. */
- @Override
- public void onParameterChanged(String paramName, Object paramValue) {
- updateParameter(paramName, paramValue);
- updateQueryArea();
- GUIController.logger.info("uploaded " + paramName + ": " + paramValue);
- }
-
- /** Remove a query parameter from the parameters list. */
- @Override
- public void onParameterRemoved(String paramName) {
- removeParameter(paramName);
- updateQueryArea();
- GUIController.logger.info("removed " + paramName);
- }
-
- /**
- * Update the query area with a working ADQL query, based on the parameters list.
- */
- private void updateQueryArea() {
- String query = Queries.getQuery(selectedTableName, paramValues, 10);
- mainView.getRequestPanel().updateQueryArea(query);
- }
-
- public void updateService(String serviceURL, String tableName) {
- if (!tableName.equals(selectedTableName)) {
- selectedTableServiceURL = serviceURL;
- selectedTableName = tableName;
- updateQueryArea();
- GUIController.logger.info("Selected table: " + selectedTableName + " - service: "
- + selectedTableServiceURL);
- }
- }
-
-}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/GUIDim.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/GUIDim.java
deleted file mode 100644
index 4823552..0000000
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/GUIDim.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.
- *
- * 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
- * .
- */
-
-package eu.omp.irap.vespa.epntapclient.gui;
-
-/**
- * A simple class containing GUI panel and elements dimensions.
- *
- * @author N. Jourdane
- */
-public class GUIDim {
-
- /** The width of the left panel (services view). */
- public static final int LEFT_PANEL_WIDTH = 550;
-
- /** The minimum width of the left panel (services view). */
- public static final int LEFT_PANEL_MIN_WIDTH = 300;
-
- /** The width of the right panel (request view). */
- public static final int RIGHT_PANEL_WIDTH = 450;
-
- /** The minimum width of the right panel (request view). */
- public static final int RIGHT_PANEL_MIN_WIDTH = 220;
-
- /** The height of the top panel (request view and services view). */
- public static final int TOP_PANEL_HEIGHT = 400;
-
- /** The minimum height of the top panel (request view and services view). */
- public static final int TOP_PANEL_MIN_HEIGHT = 100;
-
- /** The height of the bottom panel (result view). */
- public static final int BOTTOM_PANEL_HEIGHT = 150;
-
- /** The minimum height of the bottom panel (result view). */
- public static final int BOTTOM_PANEL_MIN_HEIGHT = 100;
-
-
- /** Private constructor to hide the implicit public one. */
- private GUIDim() {
- }
-}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/ParamField.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/ParamField.java
deleted file mode 100644
index 58cd18b..0000000
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/ParamField.java
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- * 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.
- *
- * 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
- * .
- */
-
-package eu.omp.irap.vespa.epntapclient.gui;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.BoxLayout;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import javax.swing.SwingUtilities;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-
-import eu.omp.irap.vespa.epntapclient.EpnTapGet;
-import eu.omp.irap.vespa.votable.utils.CantSendQueryException;
-
-/**
- * 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.
- *
- * @author N. Jourdane
- */
-public abstract class ParamField extends JPanel {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The logger for the class ParamField. */
- protected static final Logger logger = Logger.getLogger(ParamField.class.getName());
-
- /** The minimum width of the field. */
- private static final int MIN_FIELD_WIDTH = 30;
-
- /** The preferred field height. */
- private static final int FIELD_HEIGHT = 20;
-
- /** The maximum width of the field. */
- private static final int MAX_FIELD_WIDTH = 400;
-
- /** The preferred label width. */
- private static final int LABEL_WIDTH = 140;
-
- /** The date format used in the DateRange field */
- private static final String DATE_FORMAT = "dd/MM/yyyy";
-
- /** The regex used to validate the Date fields */
- 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)$)";
-
- /** The suffix used in REG-TAP parameters names, indicating that it's a beginning of a range. */
- private static final String MIN_SUFFIX = "min";
-
- /** The suffix used in REG-TAP parameters names, indicating that it is a end of a range. */
- private static final String MAX_SUFFIX = "max";
-
- /** The main view of the application. */
- protected ViewListener viewListener;
-
- /** The parameter name of the field */
- protected String paramName;
-
-
- /**
- * 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.
- *
- * @param mainView The main view of the application.
- * @param paramName The name of the parameter.
- */
- public ParamField(ViewListener viewListener, String paramName) {
- super();
-
- this.viewListener = viewListener;
- this.paramName = paramName;
-
- buildParamField();
- }
-
- private void buildParamField() {
- setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
-
- setMaximumSize(new Dimension(ParamField.MAX_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
-
- String strLabel = paramName.replaceAll("_", " ").trim();
- JLabel label = new JLabel(strLabel.substring(0, 1).toUpperCase() + strLabel.substring(1));
- label.setPreferredSize(new Dimension(ParamField.LABEL_WIDTH, ParamField.FIELD_HEIGHT));
-
- this.add(label);
- }
-
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- public static class StringField extends ParamField implements TextFieldListener {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The JTextField used to put the parameter value. */
- JTextField field;
-
-
- /**
- * Method constructor for the string field.
- *
- * @param mainView The main view of the application.
- * @param paramName The name of the parameter.
- */
- public StringField(ViewListener viewListener, String paramName) {
- super(viewListener, paramName);
- field = new JTextField();
- ParamField.addChangeListener(this, field);
- this.add(field);
- }
-
- /**
- * This method is called each time the field is modified.
- */
- @Override
- public void update(JTextField textField) {
- if (textField.getText().isEmpty()) {
- viewListener.onParameterChanged(paramName, null);
- } else {
- viewListener.onParameterChanged(paramName, textField.getText());
- }
- }
- }
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- public static class FloatField extends ParamField implements TextFieldListener {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The JTextField used to put the parameter value. */
- JTextField field;
-
-
- /**
- * Method constructor
- *
- * @param mainView The main view of the application.
- * @param paramName The name of the parameter.
- */
- public FloatField(ViewListener viewListener, String paramName) {
- super(viewListener, paramName);
- field = new JTextField();
- ParamField.addChangeListener(this, field);
- this.add(field);
- }
-
- /**
- * This method is called each time the field is modified.
- */
- @Override
- public void update(JTextField textField) {
- if (textField.getText().isEmpty()) {
- textField.setBackground(Color.WHITE);
- viewListener.onParameterRemoved(paramName);
- } else {
- try {
- float value = Float.parseFloat(textField.getText());
- viewListener.onParameterChanged(paramName, value);
- textField.setBackground(Color.WHITE);
- } catch (@SuppressWarnings("unused") NumberFormatException e) {
- textField.setBackground(Color.PINK);
- }
- }
- }
- }
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- public static class DateRangeField extends ParamField implements TextFieldListener {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The JTextField used to put the parameter minimum value of the range. */
- JTextField fieldMin;
-
- /** The JTextField used to put the parameter maximum value of the range. */
- JTextField fieldMax;
-
-
- /**
- * Method constructor
- *
- * @param mainView The main view of the application.
- * @param paramName The name of the parameter.
- */
- public DateRangeField(ViewListener viewListener, String paramName) {
- super(viewListener, paramName);
- this.add(new JLabel("min "));
- fieldMin = new JTextField();
- fieldMin.setName(ParamField.MIN_SUFFIX);
- fieldMin.setPreferredSize(
- new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
- ParamField.addChangeListener(this, fieldMin);
- this.add(fieldMin);
-
- this.add(new JLabel("max "));
- fieldMax = new JTextField();
- fieldMax.setName(ParamField.MAX_SUFFIX);
- fieldMax.setPreferredSize(
- new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
- ParamField.addChangeListener(this, fieldMin);
- this.add(fieldMax);
- }
-
- /**
- * This method is called each time the field is modified.
- */
- @Override
- public void update(JTextField field) {
- DateFormat df = new SimpleDateFormat(ParamField.DATE_FORMAT, Locale.ENGLISH);
- if (field.getText().isEmpty()) {
- field.setBackground(Color.WHITE);
- viewListener.onParameterRemoved(paramName + field.getName());
- } else if (field.getText().matches(ParamField.DATE_REGEX)) {
- try {
- long date = df.parse(field.getText()).getTime();
- date = Math.round(date / 86400000.0 + 2440587.5); // to JD
- viewListener.onParameterChanged(paramName + field.getName(),
- date);
- field.setBackground(Color.WHITE);
- } catch (@SuppressWarnings("unused") ParseException e) {
- field.setBackground(Color.PINK);
- }
- // TODO: check if date min < date max
- } else {
- field.setBackground(Color.PINK);
- }
- }
- }
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- public static class FloatRangeField extends ParamField implements TextFieldListener {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The JTextField used to put the parameter minimum value of the range. */
- JTextField fieldMin;
-
- /** The JTextField used to put the parameter maximum value of the range. */
- JTextField fieldMax;
-
-
- /**
- * Method constructor
- *
- * @param mainView The main view of the application.
- * @param paramName The name of the parameter.
- */
- public FloatRangeField(ViewListener viewListener, String paramName) {
- super(viewListener, paramName);
- fieldMin = new JTextField();
- fieldMin.setName(ParamField.MIN_SUFFIX);
- ParamField.addChangeListener(this, fieldMin);
- this.add(fieldMin);
-
- fieldMax = new JTextField();
- fieldMax.setName(ParamField.MAX_SUFFIX);
- ParamField.addChangeListener(this, fieldMax);
- this.add(fieldMax);
- }
-
- /**
- * This method is called each time the field is modified.
- */
- @Override
- public void update(JTextField field) {
- if (field.getText().isEmpty()) {
- field.setBackground(Color.WHITE);
- viewListener.onParameterRemoved(paramName + field.getName());
- } else {
- try {
- viewListener.onParameterChanged(paramName + field.getName(),
- Float.parseFloat(field.getText()));
- field.setBackground(Color.WHITE);
- } catch (@SuppressWarnings("unused") NumberFormatException e) {
- field.setBackground(Color.PINK);
- }
- }
- }
- }
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- public static class TargetNameField extends ParamField implements TextFieldListener {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The comboBox to enter the target_name and display target name propositions. */
- JComboBox comboBox;
-
- /** The JTextField related to the ComboBox, allowing to listen for text content update. */
- JTextField field;
-
- /**
- * 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.
- */
- String lastContent;
-
- /**
- * 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 {
- for (String s : EpnTapGet.getTargetNames(content)) {
- comboBox.addItem(s);
- }
- } catch (CantSendQueryException e) {
- ParamField.logger.log(Level.WARNING,
- "Can't get table names for the resolver", e);
- }
- comboBox.getEditor().setItem(content);
- comboBox.showPopup();
- }
- if (content.isEmpty()) {
- viewListener.onParameterRemoved(paramName);
- } else {
- viewListener.onParameterChanged(paramName, content);
- }
- }
- }
- };
-
-
- /**
- * Method constructor
- *
- * @param mainView The main view of the application.
- * @param paramName The name of the parameter.
- */
- public TargetNameField(ViewListener viewListener, String paramName) {
- super(viewListener, paramName);
- comboBox = new JComboBox<>();
- comboBox.setPreferredSize(
- new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
-
- comboBox.setEditable(true);
- field = (JTextField) comboBox.getEditor().getEditorComponent();
- ParamField.addChangeListener(this, field);
- this.add(comboBox);
- }
-
- /**
- * This method is called each time the field is modified.
- */
- @Override
- public void update(JTextField textField) {
- SwingUtilities.invokeLater(updateComboBox);
- }
- }
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- public static class DataProductTypeField extends ParamField {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The comboBox used to select the data product type. */
- JComboBox comboBox;
-
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- @SuppressWarnings("javadoc")
- enum DataProductType {
- // @noformat
- 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");
- // @format
-
- /** The full name of the data product type, such as `Dynamic spectrum`. */
- private String name = "";
-
- /** The id of the data product type, such as `ds`. */
- private String id = "";
-
-
- /**
- * Method constructor for the enumeration.
- *
- * @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) {
- this.name = name;
- this.id = id;
- }
-
- /**
- * @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.
- */
- public List query() {
- List item = new ArrayList<>();
- item.add(name.replace(" ", "-").toLowerCase());
- item.add(id);
- return item;
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
-
- /**
- * Method constructor
- *
- * @param mainView The main view of the application.
- * @param paramName The name of the parameter.
- */
- public DataProductTypeField(ViewListener viewListener, String paramName) {
- super(viewListener, paramName);
- comboBox = new JComboBox<>(DataProductType.values());
- comboBox.setSelectedItem(DataProductType.ALL);
- comboBox.setPreferredSize(
- new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
- comboBox.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- update();
- }
- });
- this.add(comboBox);
- }
-
- /**
- * This method is called each time the field is modified.
- */
- void update() {
- DataProductType item = (DataProductType) comboBox.getSelectedItem();
- if (DataProductType.ALL.equals(item)) {
- viewListener.onParameterRemoved(paramName);
- } else {
- viewListener.onParameterChanged(paramName, item.query());
- }
- }
- }
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- public static class TargetClassField extends ParamField {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The comboBox used to select the target class. */
- JComboBox comboBox;
-
-
- /**
- * An enumeration of all available target classes.
- *
- * @author N. Jourdane
- */
- @SuppressWarnings("javadoc")
- enum TargetClass {
- // @noformat
- ALL("All"), COMET("Comet"), EXOPLANET("Exoplanet"), RING("Ring"),
- SAMPLE("Sample"), SKY("Sky"), SPACECRAFT("Spacecraft"), SPACEJUNK("Spacejunk"),
- STAR("Star"), INTERPLANETARY_MEDIUM("Interplanetary medium");
- // @format
-
- /** The name of the target class. */
- String name;
-
-
- /**
- * Method constructor for the enumeration.
- *
- * @param name The name of the target class.
- */
- TargetClass(String name) {
- this.name = name;
- }
-
- /**
- * @return The name formated for the query.
- */
- String query() {
- return name.replace(" ", "_").toLowerCase();
- }
- }
-
-
- /**
- * Method constructor
- *
- * @param mainView The main view of the application.
- * @param paramName The name of the parameter.
- */
- public TargetClassField(ViewListener viewListener, String paramName) {
- super(viewListener, paramName);
- comboBox = new JComboBox<>(TargetClass.values());
- comboBox.setPreferredSize(
- new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
- comboBox.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- update();
- }
- });
- this.add(comboBox);
- }
-
- /**
- * This method is called each time the field is modified.
- */
- void update() {
- TargetClass value = (TargetClass) comboBox.getSelectedItem();
- if (TargetClass.ALL.equals(value)) {
- viewListener.onParameterRemoved(paramName);
- } else {
- viewListener.onParameterChanged(paramName, value.query());
- }
- }
- }
-
- /**
- * 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.
- *
- * @author N. Jourdane
- */
- interface TextFieldListener {
-
- /**
- * When the content of the JTextField is updated.
- *
- * @param field The JTextField. Is useful for classes containing several text fields, such
- * as DateRangeField, to know which one triggered the event.
- */
- void update(JTextField field);
- }
-
-
- /**
- * To add the listener. @see TextFieldListener
- *
- * @param changeListener The listener of text fields.
- * @param field The field to listen.
- */
- static void addChangeListener(final TextFieldListener changeListener, final JTextField field) {
- field.getDocument().addDocumentListener(new DocumentListener() {
-
- @Override
- public void removeUpdate(DocumentEvent de) {
- changeListener.update(field);
- }
-
- @Override
- public void insertUpdate(DocumentEvent de) {
- changeListener.update(field);
- }
-
- @Override
- public void changedUpdate(DocumentEvent de) {
- changeListener.update(field);
- }
- });
- }
-}
\ No newline at end of file
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/ViewListener.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/ViewListener.java
deleted file mode 100644
index c4775c8..0000000
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/ViewListener.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.
- *
- * 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
- * .
- */
-
-package eu.omp.irap.vespa.epntapclient.gui;
-
-import java.io.File;
-
-/**
- * The interface for the main view listener, which listen for GUI events in the view, implemented by
- * the controller.
- *
- * @author N. Jourdane
- */
-public interface ViewListener {
-
- /**
- * When a service is selected on the service panel.
- *
- * @param selectedService The row number selected in the service panel.
- */
- void onServiceSelected(int selectedService);
-
- /**
- * When the `Send query` button is clicked.
- *
- * @param query The query to send.
- */
- void onSendButtonClicked(String query);
-
- /**
- * When the `Download VOTable` button is clicked.
- *
- * @param outputFile The file to copy the VOTable.
- */
- void onDownloadButtonClicked(File outputFile);
-
- /**
- * When a parameter is removed on the parameter panel.
- *
- * @param paramName The name of the parameter as described in REG-TAP specifications.
- * @param paramValue The value of the parameter to update.
- */
- void onParameterChanged(String paramName, Object paramValue);
-
- /**
- * When a parameter is updated to a valid value on the parameter panel.
- *
- * @param paramName The name of the parameter as described in REG-TAP specifications.
- */
- void onParameterRemoved(String paramName);
-}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/GUIDim.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/GUIDim.java
new file mode 100644
index 0000000..137fa1c
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/GUIDim.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.mainPanel;
+
+/**
+ * A simple class containing GUI panel and elements dimensions.
+ *
+ * @author N. Jourdane
+ */
+public class GUIDim {
+
+ /** The width of the left panel (services view). */
+ public static final int LEFT_PANEL_WIDTH = 550;
+
+ /** The minimum width of the left panel (services view). */
+ public static final int LEFT_PANEL_MIN_WIDTH = 300;
+
+ /** The width of the right panel (request view). */
+ public static final int RIGHT_PANEL_WIDTH = 450;
+
+ /** The minimum width of the right panel (request view). */
+ public static final int RIGHT_PANEL_MIN_WIDTH = 220;
+
+ /** The height of the top panel (request view and services view). */
+ public static final int TOP_PANEL_HEIGHT = 400;
+
+ /** The minimum height of the top panel (request view and services view). */
+ public static final int TOP_PANEL_MIN_HEIGHT = 100;
+
+ /** The height of the bottom panel (result view). */
+ public static final int BOTTOM_PANEL_HEIGHT = 150;
+
+ /** The minimum height of the bottom panel (result view). */
+ public static final int BOTTOM_PANEL_MIN_HEIGHT = 100;
+
+
+ /** Private constructor to hide the implicit public one. */
+ private GUIDim() {
+ }
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/MainPanelController.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/MainPanelController.java
new file mode 100644
index 0000000..93a6eaf
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/MainPanelController.java
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.mainPanel;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.JOptionPane;
+
+import eu.omp.irap.vespa.epntapclient.EpnTapController;
+import eu.omp.irap.vespa.epntapclient.service.Queries;
+import eu.omp.irap.vespa.votable.controller.CantGetVOTableException;
+
+/**
+ * @author N. Jourdane
+ */
+public class MainPanelController extends EpnTapController implements ViewListener {
+
+ /** The logger for the class GUIController. */
+ private static final Logger logger = Logger.getLogger(MainPanelController.class.getName());
+
+ private MainPanelView mainView;
+
+ private String voTablePath;
+
+ /** The name of the table selected by the user on the table list panel. */
+ private String selectedTableName;
+
+ /** The URL of the service corresponding to the selected table. */
+ private String selectedTableServiceURL;
+
+
+ public MainPanelController() {
+ super();
+ mainView = new MainPanelView(this);
+ }
+
+ @Override
+ public void readServices() {
+ try {
+ servicesCtrl.readTable();
+ } catch (CantGetVOTableException e) {
+ displayError("Can not get services.", e);
+ }
+ mainView.getServicesPanel().fillTable(servicesCtrl.getVOTableData());
+ }
+
+ public MainPanelView getView() {
+ return mainView;
+ }
+
+ /** Update the row selected by the user on the Services Panel. */
+ @Override
+ public void onServiceSelected(int selectedServiceRow) {
+ String url = mainView.getServicesPanel().getServiceURL(selectedServiceRow);
+ String tableName = mainView.getServicesPanel().getTableName(selectedServiceRow);
+ updateService(url, tableName);
+ }
+
+ /** Send the specified query on selectedTableServiceURL */
+ @Override
+ public void onSendButtonClicked(String query) {
+ MainPanelController.logger.info("Sending query: " + query + " on " + selectedTableServiceURL);
+ try {
+ voTablePath = sendQuery(query, selectedTableServiceURL);
+ } catch (CantGetVOTableException e) {
+ displayError("Can not send the query.", e);
+ MainPanelController.logger.log(Level.WARNING, "Can not send query.", e);
+ }
+
+ mainView.getResultsPanel().fillTable(resultsCtrl.getVOTableData());
+ }
+
+ @Override
+ public void displayError(String message, Exception e) {
+ logger.log(Level.SEVERE, message, e);
+ JOptionPane.showMessageDialog(mainView, e.getMessage(), message, JOptionPane.ERROR_MESSAGE);
+ }
+
+ /** Copy the VOTable to a specified location. */
+ @Override
+ public void onDownloadButtonClicked(File outputFile) {
+ try {
+ Files.copy(Paths.get(voTablePath), Paths.get(outputFile.getAbsolutePath()));
+ } catch (IOException e) {
+ // TODO create exception
+ mainView.displayError("Can not save the file.",
+ "Check that you can write on the specified directory.");
+ MainPanelController.logger.log(Level.WARNING, "Can not save the file.", e);
+ }
+ }
+
+ /** Update a query parameter in the parameter list. */
+ @Override
+ public void onParameterChanged(String paramName, Object paramValue) {
+ updateParameter(paramName, paramValue);
+ updateQueryArea();
+ MainPanelController.logger.info("uploaded " + paramName + ": " + paramValue);
+ }
+
+ /** Remove a query parameter from the parameters list. */
+ @Override
+ public void onParameterRemoved(String paramName) {
+ removeParameter(paramName);
+ updateQueryArea();
+ MainPanelController.logger.info("removed " + paramName);
+ }
+
+ /**
+ * Update the query area with a working ADQL query, based on the parameters list.
+ */
+ private void updateQueryArea() {
+ String query = Queries.getQuery(selectedTableName, paramValues, 10);
+ mainView.getRequestPanel().updateQueryArea(query);
+ }
+
+ public void updateService(String serviceURL, String tableName) {
+ if (!tableName.equals(selectedTableName)) {
+ selectedTableServiceURL = serviceURL;
+ selectedTableName = tableName;
+ updateQueryArea();
+ MainPanelController.logger.info("Selected table: " + selectedTableName + " - service: "
+ + selectedTableServiceURL);
+ }
+ }
+
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/MainPanelView.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/MainPanelView.java
new file mode 100644
index 0000000..ecd8ff6
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/MainPanelView.java
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.mainPanel;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JSplitPane;
+
+import eu.omp.irap.vespa.epntapclient.gui.requestpanel.RequestPanelView;
+import eu.omp.irap.vespa.epntapclient.gui.resultpanel.ResultPanelView;
+import eu.omp.irap.vespa.epntapclient.gui.servicespanel.ServicesPanelView;
+
+/**
+ * The main view of the application, which manage all the other views.
+ *
+ * @author N. Jourdane
+ */
+public class MainPanelView extends JPanel {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The JPanel where the VOTable results is displayed. */
+ private ResultPanelView resultsPanel;
+
+ /** The JPanel where the list of services is displayed. */
+ private ServicesPanelView servicesPanel;
+
+ /** The JPanel where the user build the query. */
+ private RequestPanelView requestPanel;
+
+
+ /**
+ * The main view constructor, which create all the panels.
+ *
+ * @param voTableServicesView The view to put in the services panel, built by ServicesController
+ * @param voTableResultsView The view to put in the results panel, built by ResultsController.
+ */
+
+ public MainPanelView(ViewListener viewListener) {
+ servicesPanel = new ServicesPanelView(viewListener);
+ resultsPanel = new ResultPanelView(viewListener);
+ requestPanel = new RequestPanelView(viewListener);
+ buildMainView();
+ }
+
+ /**
+ * Build and fill the GUI.
+ */
+ private void buildMainView() {
+ setLayout(new BorderLayout());
+
+ JSplitPane northPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, servicesPanel,
+ requestPanel);
+ JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, northPanel, resultsPanel);
+
+ add(mainPanel, BorderLayout.CENTER);
+
+ revalidate();
+ setSizes();
+ }
+
+ private void setSizes() {
+ servicesPanel.setPreferredSize(
+ new Dimension(GUIDim.LEFT_PANEL_WIDTH, GUIDim.TOP_PANEL_HEIGHT));
+ servicesPanel.setMinimumSize(
+ new Dimension(GUIDim.LEFT_PANEL_MIN_WIDTH, GUIDim.TOP_PANEL_MIN_HEIGHT));
+
+ requestPanel.setPreferredSize(
+ new Dimension(GUIDim.RIGHT_PANEL_WIDTH, GUIDim.TOP_PANEL_HEIGHT));
+ requestPanel.setMinimumSize(
+ new Dimension(GUIDim.RIGHT_PANEL_MIN_WIDTH, GUIDim.TOP_PANEL_MIN_HEIGHT));
+
+ resultsPanel.setPreferredSize(
+ new Dimension(GUIDim.LEFT_PANEL_MIN_WIDTH + GUIDim.RIGHT_PANEL_MIN_WIDTH,
+ GUIDim.BOTTOM_PANEL_HEIGHT));
+ resultsPanel.setMinimumSize(
+ new Dimension(GUIDim.LEFT_PANEL_MIN_WIDTH + GUIDim.RIGHT_PANEL_MIN_WIDTH,
+ GUIDim.BOTTOM_PANEL_MIN_HEIGHT));
+ }
+
+ /**
+ * @return The JPanel where the VOTable result is displayed.
+ */
+ public ResultPanelView getResultsPanel() {
+ return resultsPanel;
+ }
+
+ /**
+ * @return The JPanel containing the GUI elements to build the query.
+ */
+ public RequestPanelView getRequestPanel() {
+ return requestPanel;
+ }
+
+ /**
+ * @return The JPanel where the list of services is displayed.
+ */
+ public ServicesPanelView getServicesPanel() {
+ return servicesPanel;
+ }
+
+ /**
+ * Display an error message. Usually used each time an error happens.
+ *
+ * @param title The title of the error.
+ * @param message The message of the error.
+ */
+ public void displayError(String title, String message) {
+ JOptionPane.showMessageDialog(this, message, title,
+ JOptionPane.ERROR_MESSAGE);
+ }
+
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/ViewListener.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/ViewListener.java
new file mode 100644
index 0000000..6222ca2
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainPanel/ViewListener.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.mainPanel;
+
+import java.io.File;
+
+/**
+ * The interface for the main view listener, which listen for GUI events in the view, implemented by
+ * the controller.
+ *
+ * @author N. Jourdane
+ */
+public interface ViewListener {
+
+ /**
+ * When a service is selected on the service panel.
+ *
+ * @param selectedService The row number selected in the service panel.
+ */
+ void onServiceSelected(int selectedService);
+
+ /**
+ * When the `Send query` button is clicked.
+ *
+ * @param query The query to send.
+ */
+ void onSendButtonClicked(String query);
+
+ /**
+ * When the `Download VOTable` button is clicked.
+ *
+ * @param outputFile The file to copy the VOTable.
+ */
+ void onDownloadButtonClicked(File outputFile);
+
+ /**
+ * When a parameter is removed on the parameter panel.
+ *
+ * @param paramName The name of the parameter as described in REG-TAP specifications.
+ * @param paramValue The value of the parameter to update.
+ */
+ void onParameterChanged(String paramName, Object paramValue);
+
+ /**
+ * When a parameter is updated to a valid value on the parameter panel.
+ *
+ * @param paramName The name of the parameter as described in REG-TAP specifications.
+ */
+ void onParameterRemoved(String paramName);
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/RequestPanel.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/RequestPanel.java
deleted file mode 100644
index 73ccbc6..0000000
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/RequestPanel.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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.
- *
- * 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
- * .
- */
-
-package eu.omp.irap.vespa.epntapclient.gui.panels;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.BorderFactory;
-import javax.swing.BoxLayout;
-import javax.swing.JButton;
-import javax.swing.JPanel;
-import javax.swing.JTextArea;
-
-import eu.omp.irap.vespa.epntapclient.gui.ParamField;
-import eu.omp.irap.vespa.epntapclient.gui.ParamField.DataProductTypeField;
-import eu.omp.irap.vespa.epntapclient.gui.ParamField.DateRangeField;
-import eu.omp.irap.vespa.epntapclient.gui.ParamField.FloatRangeField;
-import eu.omp.irap.vespa.epntapclient.gui.ParamField.TargetNameField;
-import eu.omp.irap.vespa.epntapclient.gui.ViewListener;
-
-/**
- * The view of the panel where the user builds the query.
- *
- * @author N. Jourdane
- */
-public class RequestPanel extends JPanel {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- /** The main view of the application. */
- protected ViewListener viewListener;
-
- /** The text area where the user write the query. */
- protected JTextArea queryArea;
-
- /**
- * The parameters fields for the request.
- */
- private List paramFields;
-
- /** The height of the buttons panel. */
- private static final int BUTTON_PANEL_HEIGHT = 20;
-
-
- /**
- * Method constructor
- *
- * @param mainView The EPN-TAP main view.
- */
- public RequestPanel(ViewListener viewListener) {
- this.viewListener = viewListener;
- buildRequestPanel();
- }
-
- private void buildRequestPanel() {
- setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
-
- this.add(buildParamPanel(), this);
- this.add(buildQueryPanel(), this);
- this.add(buildButtonPanel(), this);
- }
-
- /**
- * Build a JPanel containing graphical elements to build the query user-friendly.
- *
- * @return The JPanel.
- */
- private JPanel buildParamPanel() {
- paramFields = new ArrayList<>();
- paramFields.add(new TargetNameField(viewListener, "target_name"));
- paramFields.add(new DateRangeField(viewListener, "time_"));
- paramFields.add(new FloatRangeField(viewListener, "spectral_range_"));
- paramFields.add(new DataProductTypeField(viewListener, "dataproduct_type"));
- JPanel paramPanel = new JPanel();
- paramPanel.setLayout(new BoxLayout(paramPanel, BoxLayout.Y_AXIS));
- paramPanel.setBorder(BorderFactory.createTitledBorder("Query parameters"));
-
- for (ParamField field : paramFields) {
- paramPanel.add(field);
- }
-
- return paramPanel;
- }
-
- /**
- * Build a JPanel containing a text-area where the query is displayed.
- *
- * @return The JPanel.
- */
- private JPanel buildQueryPanel() {
- JPanel queryPanel = new JPanel();
- queryPanel.setBorder(BorderFactory.createTitledBorder("Query for the selected service(s)"));
- queryArea = new JTextArea("");
- queryArea.setToolTipText("The query sent to the service(s).");
- queryArea.setLineWrap(true);
- queryPanel.setLayout(new BorderLayout());
- queryPanel.add(queryArea, BorderLayout.CENTER);
-
- return queryPanel;
- }
-
- /**
- * Update the query JTextArea.
- *
- * @param query The string literal to put in the text-area, which will override the old content.
- */
- public void updateQueryArea(String query) {
- queryArea.setText(query);
- }
-
- /**
- * Build a JPanel containing the button(s), particularly the `Send` button.
- *
- * @return The JPanel .
- */
- private JPanel buildButtonPanel() {
- JPanel buttonPanel = new JPanel();
- JButton btnSend = new JButton("Send query");
- btnSend.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- viewListener.onSendButtonClicked(queryArea.getText());
- }
- });
- buttonPanel.add(btnSend);
- buttonPanel.setMaximumSize(new Dimension(1000, RequestPanel.BUTTON_PANEL_HEIGHT));
-
- return buttonPanel;
- }
-}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/ResultsPanel.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/ResultsPanel.java
deleted file mode 100644
index 2ae20a3..0000000
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/ResultsPanel.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.
- *
- * 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
- * .
- */
-
-package eu.omp.irap.vespa.epntapclient.gui.panels;
-
-import java.awt.BorderLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.JButton;
-import javax.swing.JFileChooser;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-import eu.omp.irap.vespa.epntapclient.gui.ViewListener;
-import eu.omp.irap.vespa.votable.view.VOTableView;
-
-/**
- * @author N. Jourdane
- */
-public class ResultsPanel extends VOTableView {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- ViewListener viewListener;
-
- /** A label to display several informations (aka. status bar). */
- private JLabel infoLabel;
-
- private JButton fileButton;
-
-
- /**
- * Method constructor which customize the result panel, but don't build it from scratch since
- * VOTableView is already created by ResultController.
- *
- * @param mainView The main view of the application.
- * @param voTableView The generic view of the VOTable panel.
- */
- public ResultsPanel(ViewListener viewListener) {
- super();
- this.viewListener = viewListener;
- buildResultPanel();
- }
-
- public void buildResultPanel() {
- add(buildBottomBar(), BorderLayout.SOUTH);
- }
-
- private JPanel buildBottomBar() {
- JPanel statusBar = new JPanel();
- statusBar.setLayout(new BorderLayout());
- statusBar.add(getInfoLabel());
- statusBar.add(getFileButton(), BorderLayout.EAST);
-
- return statusBar;
- }
-
- public JLabel getInfoLabel() {
- return infoLabel == null ? new JLabel() : infoLabel;
- }
-
- /**
- * @param infoText The text to display in the status-bar, which will override the old one.
- */
- public void setInfoText(String infoText) {
- infoLabel.setText(infoText);
- }
-
- public JButton getFileButton() {
- if (fileButton == null) {
- fileButton = new JButton("Get File");
- fileButton.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- final JFileChooser fc = new JFileChooser();
- fc.showOpenDialog(ResultsPanel.this);
- viewListener.onDownloadButtonClicked(fc.getSelectedFile());
- }
- });
- }
- return fileButton;
- }
-
-}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/ServicesPanel.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/ServicesPanel.java
deleted file mode 100644
index 7b12483..0000000
--- a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/panels/ServicesPanel.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.
- *
- * 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
- * .
- */
-
-package eu.omp.irap.vespa.epntapclient.gui.panels;
-
-import java.awt.BorderLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.JButton;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-
-import eu.omp.irap.vespa.epntapclient.gui.ViewListener;
-import eu.omp.irap.vespa.votable.view.VOTableView;
-
-/**
- * @author N. Jourdane
- */
-public class ServicesPanel extends VOTableView {
-
- /** The serial version UID. */
- private static final long serialVersionUID = 1L;
-
- private ViewListener viewListener;
-
- private JButton serviceButton;
-
- private JTextField serviceUrlTextField;
-
- private JTextField tableNameTextField;
-
-
- /**
- * Method constructor which customize the services panel, but don't build it from scratch since
- * VOTableView is already created by ServicesController. Add also the JTable listener.
- *
- * @param mainView The main view of the application.
- * @param voTableView The generic view of the VOTable panel.
- */
- public ServicesPanel(final ViewListener viewListener) {
- super();
- this.viewListener = viewListener;
- buildServicesPanel();
- }
-
- private void buildServicesPanel() {
- getTable().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
-
- @Override
- public void valueChanged(ListSelectionEvent evt) {
- viewListener.onServiceSelected(getTable().getSelectedRow());
- }
- });
-
- add(buildAddServicePanel(), BorderLayout.SOUTH);
- }
-
- private JPanel buildAddServicePanel() {
- JPanel addServicePanel = new JPanel();
- addServicePanel.add(new JLabel("Service URL"));
- addServicePanel.add(getServiceUrlTextField());
- addServicePanel.add(new JLabel("Table name"));
- addServicePanel.add(getTableNameTextField());
- addServicePanel.add(getServiceButton());
-
- return addServicePanel;
- }
-
- private JTextField getTableNameTextField() {
- return tableNameTextField == null ? new JTextField(10) : tableNameTextField;
- }
-
- private JTextField getServiceUrlTextField() {
- return serviceUrlTextField == null ? new JTextField(10) : serviceUrlTextField;
- }
-
- private JButton getServiceButton() {
- if (serviceButton == null) {
- serviceButton = new JButton("Set service");
-
- serviceButton.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- viewListener.onServiceSelected(-1);
- }
- });
- }
- return serviceButton;
- }
-
- /**
- * @param row The row index in the JTable element.
- * @return The URL of the service corresponding to the row.
- */
- public String getServiceURL(int row) {
- if (row == -1) {
- return serviceUrlTextField.getText();
- }
- return (String) getValueAt(5, row);
- }
-
- /**
- * @param row The row index in the JTable element.
- * @return The table name of the service corresponding to the row.
- */
- public String getTableName(int row) {
- if (row == -1) {
- return tableNameTextField.getText();
- }
- return (String) getValueAt(2, row);
- }
-}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/ParamField.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/ParamField.java
new file mode 100644
index 0000000..a3c6e58
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/ParamField.java
@@ -0,0 +1,664 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.requestpanel;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.BoxLayout;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import eu.omp.irap.vespa.epntapclient.EpnTapGet;
+import eu.omp.irap.vespa.epntapclient.gui.mainPanel.ViewListener;
+import eu.omp.irap.vespa.votable.utils.CantSendQueryException;
+
+/**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+public abstract class ParamField extends JPanel {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The logger for the class ParamField. */
+ protected static final Logger logger = Logger.getLogger(ParamField.class.getName());
+
+ /** The minimum width of the field. */
+ private static final int MIN_FIELD_WIDTH = 30;
+
+ /** The preferred field height. */
+ private static final int FIELD_HEIGHT = 20;
+
+ /** The maximum width of the field. */
+ private static final int MAX_FIELD_WIDTH = 400;
+
+ /** The preferred label width. */
+ private static final int LABEL_WIDTH = 140;
+
+ /** The date format used in the DateRange field */
+ private static final String DATE_FORMAT = "dd/MM/yyyy";
+
+ /** The regex used to validate the Date fields */
+ 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)$)";
+
+ /** The suffix used in REG-TAP parameters names, indicating that it's a beginning of a range. */
+ private static final String MIN_SUFFIX = "min";
+
+ /** The suffix used in REG-TAP parameters names, indicating that it is a end of a range. */
+ private static final String MAX_SUFFIX = "max";
+
+ /** The main view of the application. */
+ protected ViewListener viewListener;
+
+ /** The parameter name of the field */
+ protected String paramName;
+
+
+ /**
+ * 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.
+ *
+ * @param mainView The main view of the application.
+ * @param paramName The name of the parameter.
+ */
+ public ParamField(ViewListener viewListener, String paramName) {
+ super();
+
+ this.viewListener = viewListener;
+ this.paramName = paramName;
+
+ buildParamField();
+ }
+
+ private void buildParamField() {
+ setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+
+ setMaximumSize(new Dimension(ParamField.MAX_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
+
+ String strLabel = paramName.replaceAll("_", " ").trim();
+ JLabel label = new JLabel(strLabel.substring(0, 1).toUpperCase() + strLabel.substring(1));
+ label.setPreferredSize(new Dimension(ParamField.LABEL_WIDTH, ParamField.FIELD_HEIGHT));
+
+ this.add(label);
+ }
+
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ public static class StringField extends ParamField implements TextFieldListener {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The JTextField used to put the parameter value. */
+ JTextField field;
+
+
+ /**
+ * Method constructor for the string field.
+ *
+ * @param mainView The main view of the application.
+ * @param paramName The name of the parameter.
+ */
+ public StringField(ViewListener viewListener, String paramName) {
+ super(viewListener, paramName);
+ field = new JTextField();
+ ParamField.addChangeListener(this, field);
+ this.add(field);
+ }
+
+ /**
+ * This method is called each time the field is modified.
+ */
+ @Override
+ public void update(JTextField textField) {
+ if (textField.getText().isEmpty()) {
+ viewListener.onParameterChanged(paramName, null);
+ } else {
+ viewListener.onParameterChanged(paramName, textField.getText());
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ public static class FloatField extends ParamField implements TextFieldListener {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The JTextField used to put the parameter value. */
+ JTextField field;
+
+
+ /**
+ * Method constructor
+ *
+ * @param mainView The main view of the application.
+ * @param paramName The name of the parameter.
+ */
+ public FloatField(ViewListener viewListener, String paramName) {
+ super(viewListener, paramName);
+ field = new JTextField();
+ ParamField.addChangeListener(this, field);
+ this.add(field);
+ }
+
+ /**
+ * This method is called each time the field is modified.
+ */
+ @Override
+ public void update(JTextField textField) {
+ if (textField.getText().isEmpty()) {
+ textField.setBackground(Color.WHITE);
+ viewListener.onParameterRemoved(paramName);
+ } else {
+ try {
+ float value = Float.parseFloat(textField.getText());
+ viewListener.onParameterChanged(paramName, value);
+ textField.setBackground(Color.WHITE);
+ } catch (@SuppressWarnings("unused") NumberFormatException e) {
+ textField.setBackground(Color.PINK);
+ }
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ public static class DateRangeField extends ParamField implements TextFieldListener {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The JTextField used to put the parameter minimum value of the range. */
+ JTextField fieldMin;
+
+ /** The JTextField used to put the parameter maximum value of the range. */
+ JTextField fieldMax;
+
+
+ /**
+ * Method constructor
+ *
+ * @param mainView The main view of the application.
+ * @param paramName The name of the parameter.
+ */
+ public DateRangeField(ViewListener viewListener, String paramName) {
+ super(viewListener, paramName);
+ this.add(new JLabel("min "));
+ fieldMin = new JTextField();
+ fieldMin.setName(ParamField.MIN_SUFFIX);
+ fieldMin.setPreferredSize(
+ new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
+ ParamField.addChangeListener(this, fieldMin);
+ this.add(fieldMin);
+
+ this.add(new JLabel("max "));
+ fieldMax = new JTextField();
+ fieldMax.setName(ParamField.MAX_SUFFIX);
+ fieldMax.setPreferredSize(
+ new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
+ ParamField.addChangeListener(this, fieldMin);
+ this.add(fieldMax);
+ }
+
+ /**
+ * This method is called each time the field is modified.
+ */
+ @Override
+ public void update(JTextField field) {
+ DateFormat df = new SimpleDateFormat(ParamField.DATE_FORMAT, Locale.ENGLISH);
+ if (field.getText().isEmpty()) {
+ field.setBackground(Color.WHITE);
+ viewListener.onParameterRemoved(paramName + field.getName());
+ } else if (field.getText().matches(ParamField.DATE_REGEX)) {
+ try {
+ long date = df.parse(field.getText()).getTime();
+ date = Math.round(date / 86400000.0 + 2440587.5); // to JD
+ viewListener.onParameterChanged(paramName + field.getName(),
+ date);
+ field.setBackground(Color.WHITE);
+ } catch (@SuppressWarnings("unused") ParseException e) {
+ field.setBackground(Color.PINK);
+ }
+ // TODO: check if date min < date max
+ } else {
+ field.setBackground(Color.PINK);
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ public static class FloatRangeField extends ParamField implements TextFieldListener {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The JTextField used to put the parameter minimum value of the range. */
+ JTextField fieldMin;
+
+ /** The JTextField used to put the parameter maximum value of the range. */
+ JTextField fieldMax;
+
+
+ /**
+ * Method constructor
+ *
+ * @param mainView The main view of the application.
+ * @param paramName The name of the parameter.
+ */
+ public FloatRangeField(ViewListener viewListener, String paramName) {
+ super(viewListener, paramName);
+ fieldMin = new JTextField();
+ fieldMin.setName(ParamField.MIN_SUFFIX);
+ ParamField.addChangeListener(this, fieldMin);
+ this.add(fieldMin);
+
+ fieldMax = new JTextField();
+ fieldMax.setName(ParamField.MAX_SUFFIX);
+ ParamField.addChangeListener(this, fieldMax);
+ this.add(fieldMax);
+ }
+
+ /**
+ * This method is called each time the field is modified.
+ */
+ @Override
+ public void update(JTextField field) {
+ if (field.getText().isEmpty()) {
+ field.setBackground(Color.WHITE);
+ viewListener.onParameterRemoved(paramName + field.getName());
+ } else {
+ try {
+ viewListener.onParameterChanged(paramName + field.getName(),
+ Float.parseFloat(field.getText()));
+ field.setBackground(Color.WHITE);
+ } catch (@SuppressWarnings("unused") NumberFormatException e) {
+ field.setBackground(Color.PINK);
+ }
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ public static class TargetNameField extends ParamField implements TextFieldListener {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The comboBox to enter the target_name and display target name propositions. */
+ JComboBox comboBox;
+
+ /** The JTextField related to the ComboBox, allowing to listen for text content update. */
+ JTextField field;
+
+ /**
+ * 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.
+ */
+ String lastContent;
+
+ /**
+ * 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 {
+ for (String s : EpnTapGet.getTargetNames(content)) {
+ comboBox.addItem(s);
+ }
+ } catch (CantSendQueryException e) {
+ ParamField.logger.log(Level.WARNING,
+ "Can't get table names for the resolver", e);
+ }
+ comboBox.getEditor().setItem(content);
+ comboBox.showPopup();
+ }
+ if (content.isEmpty()) {
+ viewListener.onParameterRemoved(paramName);
+ } else {
+ viewListener.onParameterChanged(paramName, content);
+ }
+ }
+ }
+ };
+
+
+ /**
+ * Method constructor
+ *
+ * @param mainView The main view of the application.
+ * @param paramName The name of the parameter.
+ */
+ public TargetNameField(ViewListener viewListener, String paramName) {
+ super(viewListener, paramName);
+ comboBox = new JComboBox<>();
+ comboBox.setPreferredSize(
+ new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
+
+ comboBox.setEditable(true);
+ field = (JTextField) comboBox.getEditor().getEditorComponent();
+ ParamField.addChangeListener(this, field);
+ this.add(comboBox);
+ }
+
+ /**
+ * This method is called each time the field is modified.
+ */
+ @Override
+ public void update(JTextField textField) {
+ SwingUtilities.invokeLater(updateComboBox);
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ public static class DataProductTypeField extends ParamField {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The comboBox used to select the data product type. */
+ JComboBox comboBox;
+
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ @SuppressWarnings("javadoc")
+ enum DataProductType {
+ // @noformat
+ 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");
+ // @format
+
+ /** The full name of the data product type, such as `Dynamic spectrum`. */
+ private String name = "";
+
+ /** The id of the data product type, such as `ds`. */
+ private String id = "";
+
+
+ /**
+ * Method constructor for the enumeration.
+ *
+ * @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) {
+ this.name = name;
+ this.id = id;
+ }
+
+ /**
+ * @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.
+ */
+ public List query() {
+ List item = new ArrayList<>();
+ item.add(name.replace(" ", "-").toLowerCase());
+ item.add(id);
+ return item;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+
+ /**
+ * Method constructor
+ *
+ * @param mainView The main view of the application.
+ * @param paramName The name of the parameter.
+ */
+ public DataProductTypeField(ViewListener viewListener, String paramName) {
+ super(viewListener, paramName);
+ comboBox = new JComboBox<>(DataProductType.values());
+ comboBox.setSelectedItem(DataProductType.ALL);
+ comboBox.setPreferredSize(
+ new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
+ comboBox.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ update();
+ }
+ });
+ this.add(comboBox);
+ }
+
+ /**
+ * This method is called each time the field is modified.
+ */
+ void update() {
+ DataProductType item = (DataProductType) comboBox.getSelectedItem();
+ if (DataProductType.ALL.equals(item)) {
+ viewListener.onParameterRemoved(paramName);
+ } else {
+ viewListener.onParameterChanged(paramName, item.query());
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ public static class TargetClassField extends ParamField {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The comboBox used to select the target class. */
+ JComboBox comboBox;
+
+
+ /**
+ * An enumeration of all available target classes.
+ *
+ * @author N. Jourdane
+ */
+ @SuppressWarnings("javadoc")
+ enum TargetClass {
+ // @noformat
+ ALL("All"), COMET("Comet"), EXOPLANET("Exoplanet"), RING("Ring"),
+ SAMPLE("Sample"), SKY("Sky"), SPACECRAFT("Spacecraft"), SPACEJUNK("Spacejunk"),
+ STAR("Star"), INTERPLANETARY_MEDIUM("Interplanetary medium");
+ // @format
+
+ /** The name of the target class. */
+ String name;
+
+
+ /**
+ * Method constructor for the enumeration.
+ *
+ * @param name The name of the target class.
+ */
+ TargetClass(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return The name formated for the query.
+ */
+ String query() {
+ return name.replace(" ", "_").toLowerCase();
+ }
+ }
+
+
+ /**
+ * Method constructor
+ *
+ * @param mainView The main view of the application.
+ * @param paramName The name of the parameter.
+ */
+ public TargetClassField(ViewListener viewListener, String paramName) {
+ super(viewListener, paramName);
+ comboBox = new JComboBox<>(TargetClass.values());
+ comboBox.setPreferredSize(
+ new Dimension(ParamField.MIN_FIELD_WIDTH, ParamField.FIELD_HEIGHT));
+ comboBox.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ update();
+ }
+ });
+ this.add(comboBox);
+ }
+
+ /**
+ * This method is called each time the field is modified.
+ */
+ void update() {
+ TargetClass value = (TargetClass) comboBox.getSelectedItem();
+ if (TargetClass.ALL.equals(value)) {
+ viewListener.onParameterRemoved(paramName);
+ } else {
+ viewListener.onParameterChanged(paramName, value.query());
+ }
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @author N. Jourdane
+ */
+ interface TextFieldListener {
+
+ /**
+ * When the content of the JTextField is updated.
+ *
+ * @param field The JTextField. Is useful for classes containing several text fields, such
+ * as DateRangeField, to know which one triggered the event.
+ */
+ void update(JTextField field);
+ }
+
+
+ /**
+ * To add the listener. @see TextFieldListener
+ *
+ * @param changeListener The listener of text fields.
+ * @param field The field to listen.
+ */
+ static void addChangeListener(final TextFieldListener changeListener, final JTextField field) {
+ field.getDocument().addDocumentListener(new DocumentListener() {
+
+ @Override
+ public void removeUpdate(DocumentEvent de) {
+ changeListener.update(field);
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent de) {
+ changeListener.update(field);
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent de) {
+ changeListener.update(field);
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelCtrl.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelCtrl.java
new file mode 100644
index 0000000..05ad91b
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelCtrl.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.requestpanel;
+
+import java.util.logging.Logger;
+
+/**
+ * @author N. Jourdane
+ */
+public class RequestPanelCtrl {
+
+ /** The logger for the class RequestPanelCtrl. */
+ private static final Logger logger = Logger.getLogger(RequestPanelCtrl.class.getName());
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelView.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelView.java
new file mode 100644
index 0000000..43f937e
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelView.java
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.requestpanel;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+
+import eu.omp.irap.vespa.epntapclient.gui.mainPanel.ViewListener;
+import eu.omp.irap.vespa.epntapclient.gui.requestpanel.ParamField.DataProductTypeField;
+import eu.omp.irap.vespa.epntapclient.gui.requestpanel.ParamField.DateRangeField;
+import eu.omp.irap.vespa.epntapclient.gui.requestpanel.ParamField.FloatRangeField;
+import eu.omp.irap.vespa.epntapclient.gui.requestpanel.ParamField.TargetNameField;
+
+/**
+ * The view of the panel where the user builds the query.
+ *
+ * @author N. Jourdane
+ */
+public class RequestPanelView extends JPanel {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ /** The main view of the application. */
+ protected ViewListener viewListener;
+
+ /** The text area where the user write the query. */
+ protected JTextArea queryArea;
+
+ /**
+ * The parameters fields for the request.
+ */
+ private List paramFields;
+
+ /** The height of the buttons panel. */
+ private static final int BUTTON_PANEL_HEIGHT = 20;
+
+
+ /**
+ * Method constructor
+ *
+ * @param mainView The EPN-TAP main view.
+ */
+ public RequestPanelView(ViewListener viewListener) {
+ this.viewListener = viewListener;
+ buildRequestPanel();
+ }
+
+ private void buildRequestPanel() {
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+ this.add(buildParamPanel(), this);
+ this.add(buildQueryPanel(), this);
+ this.add(buildButtonPanel(), this);
+ }
+
+ /**
+ * Build a JPanel containing graphical elements to build the query user-friendly.
+ *
+ * @return The JPanel.
+ */
+ private JPanel buildParamPanel() {
+ paramFields = new ArrayList<>();
+ paramFields.add(new TargetNameField(viewListener, "target_name"));
+ paramFields.add(new DateRangeField(viewListener, "time_"));
+ paramFields.add(new FloatRangeField(viewListener, "spectral_range_"));
+ paramFields.add(new DataProductTypeField(viewListener, "dataproduct_type"));
+ JPanel paramPanel = new JPanel();
+ paramPanel.setLayout(new BoxLayout(paramPanel, BoxLayout.Y_AXIS));
+ paramPanel.setBorder(BorderFactory.createTitledBorder("Query parameters"));
+
+ for (ParamField field : paramFields) {
+ paramPanel.add(field);
+ }
+
+ return paramPanel;
+ }
+
+ /**
+ * Build a JPanel containing a text-area where the query is displayed.
+ *
+ * @return The JPanel.
+ */
+ private JPanel buildQueryPanel() {
+ JPanel queryPanel = new JPanel();
+ queryPanel.setBorder(BorderFactory.createTitledBorder("Query for the selected service(s)"));
+ queryArea = new JTextArea("");
+ queryArea.setToolTipText("The query sent to the service(s).");
+ queryArea.setLineWrap(true);
+ queryPanel.setLayout(new BorderLayout());
+ queryPanel.add(queryArea, BorderLayout.CENTER);
+
+ return queryPanel;
+ }
+
+ /**
+ * Update the query JTextArea.
+ *
+ * @param query The string literal to put in the text-area, which will override the old content.
+ */
+ public void updateQueryArea(String query) {
+ queryArea.setText(query);
+ }
+
+ /**
+ * Build a JPanel containing the button(s), particularly the `Send` button.
+ *
+ * @return The JPanel .
+ */
+ private JPanel buildButtonPanel() {
+ JPanel buttonPanel = new JPanel();
+ JButton btnSend = new JButton("Send query");
+ btnSend.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ viewListener.onSendButtonClicked(queryArea.getText());
+ }
+ });
+ buttonPanel.add(btnSend);
+ buttonPanel.setMaximumSize(new Dimension(1000, RequestPanelView.BUTTON_PANEL_HEIGHT));
+
+ return buttonPanel;
+ }
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelCtrl.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelCtrl.java
new file mode 100644
index 0000000..86c2e0d
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelCtrl.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.resultpanel;
+
+import java.util.logging.Logger;
+
+/**
+ * @author N. Jourdane
+ */
+public class ResultPanelCtrl {
+
+ /** The logger for the class ResultPanelCtrl. */
+ private static final Logger logger = Logger.getLogger(ResultPanelCtrl.class.getName());
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelView.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelView.java
new file mode 100644
index 0000000..c9e1ab9
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelView.java
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.resultpanel;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import eu.omp.irap.vespa.epntapclient.gui.mainPanel.ViewListener;
+import eu.omp.irap.vespa.votable.view.VOTableView;
+
+/**
+ * @author N. Jourdane
+ */
+public class ResultPanelView extends VOTableView {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ ViewListener viewListener;
+
+ /** A label to display several informations (aka. status bar). */
+ private JLabel infoLabel;
+
+ private JButton fileButton;
+
+
+ /**
+ * Method constructor which customize the result panel, but don't build it from scratch since
+ * VOTableView is already created by ResultController.
+ *
+ * @param mainView The main view of the application.
+ * @param voTableView The generic view of the VOTable panel.
+ */
+ public ResultPanelView(ViewListener viewListener) {
+ super();
+ this.viewListener = viewListener;
+ buildResultPanel();
+ }
+
+ public void buildResultPanel() {
+ add(buildBottomBar(), BorderLayout.SOUTH);
+ }
+
+ private JPanel buildBottomBar() {
+ JPanel statusBar = new JPanel();
+ statusBar.setLayout(new BorderLayout());
+ statusBar.add(getInfoLabel());
+ statusBar.add(getFileButton(), BorderLayout.EAST);
+
+ return statusBar;
+ }
+
+ public JLabel getInfoLabel() {
+ return infoLabel == null ? new JLabel() : infoLabel;
+ }
+
+ /**
+ * @param infoText The text to display in the status-bar, which will override the old one.
+ */
+ public void setInfoText(String infoText) {
+ infoLabel.setText(infoText);
+ }
+
+ public JButton getFileButton() {
+ if (fileButton == null) {
+ fileButton = new JButton("Get File");
+ fileButton.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ final JFileChooser fc = new JFileChooser();
+ fc.showOpenDialog(ResultPanelView.this);
+ viewListener.onDownloadButtonClicked(fc.getSelectedFile());
+ }
+ });
+ }
+ return fileButton;
+ }
+
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/servicespanel/ServicesPanelCtrl.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/servicespanel/ServicesPanelCtrl.java
new file mode 100644
index 0000000..586edc8
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/servicespanel/ServicesPanelCtrl.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.servicespanel;
+
+import java.util.logging.Logger;
+
+/**
+ * @author N. Jourdane
+ */
+public class ServicesPanelCtrl {
+
+ /** The logger for the class ServicesPanelCtrl. */
+ private static final Logger logger = Logger.getLogger(ServicesPanelCtrl.class.getName());
+}
diff --git a/src/main/java/eu/omp/irap/vespa/epntapclient/gui/servicespanel/ServicesPanelView.java b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/servicespanel/ServicesPanelView.java
new file mode 100644
index 0000000..10b0cdf
--- /dev/null
+++ b/src/main/java/eu/omp/irap/vespa/epntapclient/gui/servicespanel/ServicesPanelView.java
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ *
+ * 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
+ * .
+ */
+
+package eu.omp.irap.vespa.epntapclient.gui.servicespanel;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import eu.omp.irap.vespa.epntapclient.gui.mainPanel.ViewListener;
+import eu.omp.irap.vespa.votable.view.VOTableView;
+
+/**
+ * @author N. Jourdane
+ */
+public class ServicesPanelView extends VOTableView {
+
+ /** The serial version UID. */
+ private static final long serialVersionUID = 1L;
+
+ private ViewListener viewListener;
+
+ private JButton serviceButton;
+
+ private JTextField serviceUrlTextField;
+
+ private JTextField tableNameTextField;
+
+
+ /**
+ * Method constructor which customize the services panel, but don't build it from scratch since
+ * VOTableView is already created by ServicesController. Add also the JTable listener.
+ *
+ * @param mainView The main view of the application.
+ * @param voTableView The generic view of the VOTable panel.
+ */
+ public ServicesPanelView(final ViewListener viewListener) {
+ super();
+ this.viewListener = viewListener;
+ buildServicesPanel();
+ }
+
+ private void buildServicesPanel() {
+ getTable().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+
+ @Override
+ public void valueChanged(ListSelectionEvent evt) {
+ viewListener.onServiceSelected(getTable().getSelectedRow());
+ }
+ });
+
+ add(buildAddServicePanel(), BorderLayout.SOUTH);
+ }
+
+ private JPanel buildAddServicePanel() {
+ JPanel addServicePanel = new JPanel();
+ addServicePanel.add(new JLabel("Service URL"));
+ addServicePanel.add(getServiceUrlTextField());
+ addServicePanel.add(new JLabel("Table name"));
+ addServicePanel.add(getTableNameTextField());
+ addServicePanel.add(getServiceButton());
+
+ return addServicePanel;
+ }
+
+ private JTextField getTableNameTextField() {
+ return tableNameTextField == null ? new JTextField(10) : tableNameTextField;
+ }
+
+ private JTextField getServiceUrlTextField() {
+ return serviceUrlTextField == null ? new JTextField(10) : serviceUrlTextField;
+ }
+
+ private JButton getServiceButton() {
+ if (serviceButton == null) {
+ serviceButton = new JButton("Set service");
+
+ serviceButton.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ viewListener.onServiceSelected(-1);
+ }
+ });
+ }
+ return serviceButton;
+ }
+
+ /**
+ * @param row The row index in the JTable element.
+ * @return The URL of the service corresponding to the row.
+ */
+ public String getServiceURL(int row) {
+ if (row == -1) {
+ return serviceUrlTextField.getText();
+ }
+ return (String) getValueAt(5, row);
+ }
+
+ /**
+ * @param row The row index in the JTable element.
+ * @return The table name of the service corresponding to the row.
+ */
+ public String getTableName(int row) {
+ if (row == -1) {
+ return tableNameTextField.getText();
+ }
+ return (String) getValueAt(2, row);
+ }
+}
--
libgit2 0.21.2