Commit 84b3dbfc8f6fd5fb6645fc9148cded8de3c3cfd6

Authored by Nathanael Jourdane
1 parent d349949e
Exists in master

Use SwingWorkers to avoid EDT violations.

src/main/java/eu/omp/irap/vespa/epntapclient/EpnTapConnection.java
... ... @@ -125,7 +125,7 @@ public class EpnTapConnection implements EpnTapInterface {
125 125 @Override
126 126 public List<Granule> sendADQLQuery(String tapURL, String adqlQuery) throws VOTableException {
127 127 VOTableCtrl voTableCtrl = new VOTableCtrl();
128   - voTableCtrl.newVOTable(tapURL, adqlQuery);
  128 + voTableCtrl.acquireVOTable(tapURL, adqlQuery, false);
129 129 VOTableData data = voTableCtrl.getVOTableData();
130 130  
131 131 List<Granule> granules;
... ... @@ -139,7 +139,7 @@ public class EpnTapConnection implements EpnTapInterface {
139 139 throws VOTableException {
140 140 String query = String.format(enumeratedQuery.toString(), schemaName);
141 141 VOTableCtrl voTableCtrl = new VOTableCtrl();
142   - voTableCtrl.newVOTable(tapURL, query);
  142 + voTableCtrl.acquireVOTable(tapURL, query, false);
143 143 VOTableData data = voTableCtrl.getVOTableData();
144 144 Debug.writeObject("data", data);
145 145  
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/EpnTapMainApp.java
... ... @@ -18,6 +18,9 @@ package eu.omp.irap.vespa.epntapclient;
18 18  
19 19 import java.util.logging.Logger;
20 20  
  21 +import javax.swing.JFrame;
  22 +import javax.swing.SwingUtilities;
  23 +
21 24 import com.google.gson.Gson;
22 25  
23 26 import eu.omp.irap.vespa.epntapclient.gui.mainpanel.MainPanelCtrl;
... ... @@ -46,12 +49,27 @@ public class EpnTapMainApp {
46 49 * @param args The program arguments (not used).
47 50 */
48 51 public static void main(final String[] args) {
  52 + // RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
49 53 LOGGER.info("Lauching EPNTAP app with arguments: " + new Gson().toJson(args));
50 54 if (args.length != 0) {
51 55 System.console().writer().println(WRONG_COMMAND);
52 56 return;
53 57 }
54   - MainPanelCtrl guiCtrl = new MainPanelCtrl();
55   - guiCtrl.readServices();
  58 +
  59 + SwingUtilities.invokeLater(new Runnable() {
  60 +
  61 + @Override
  62 + public void run() {
  63 + MainPanelCtrl guiCtrl = new MainPanelCtrl();
  64 + guiCtrl.acquireServices();
  65 + JFrame frame = new JFrame("EpnTAP client");
  66 + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  67 + frame.setContentPane(guiCtrl.getView());
  68 + frame.setVisible(true);
  69 + frame.setSize(800, 600);
  70 + frame.setLocationRelativeTo(null);
  71 +
  72 + }
  73 + });
56 74 }
57 75 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/epntap/EpnTapController.java
... ... @@ -55,6 +55,17 @@ public abstract class EpnTapController {
55 55  
56 56  
57 57 /**
  58 + * Get the services from the XML path or the targetURL / query.
  59 + *
  60 + * @throws VOTableException Can not read the services.
  61 + */
  62 + public void acquireServices() throws VOTableException {
  63 + String query = String.format(Queries.SELECT_ALL_TAP_SERVICES_WHERE_CORE,
  64 + ServiceCore.EPNCORE);
  65 + getServicesCtrl().acquireVOTable(Consts.DEFAULT_REGISTRY_URL, query, true);
  66 + }
  67 +
  68 + /**
58 69 * @return The request controller.
59 70 */
60 71 public RequestCtrl getRequestCtrl() {
... ... @@ -83,37 +94,16 @@ public abstract class EpnTapController {
83 94 }
84 95  
85 96 /**
86   - * Get the services from the XML path or the targetURL / query.
87   - *
88   - * @throws VOTableException Can not read the services.
89   - */
90   - public void readServices() throws VOTableException {
91   - // Here getServicesCtrl() is used instead of class field servicesCtrl to get the
92   - // subclass field, since subclasses overrides getServicesCtrl().
93   - String query = String.format(Queries.SELECT_ALL_TAP_SERVICES_WHERE_CORE,
94   - ServiceCore.EPNCORE);
95   - getServicesCtrl().newVOTable(Consts.DEFAULT_REGISTRY_URL, query);
96   - }
97   -
98   - /**
99   - * ...
  97 + * Send all the queries.
100 98 *
101 99 * @param services The services to send the queries.
102   - * @throws VOTableException Can not update the VOTable.
103 100 */
104   - public void sendQueries(ServicesList services) throws VOTableException {
105   - // Here getRequestCtrl() and getResultsCtrl() are used instead of class fields requestCtrl
106   - // and resultCtrl to get the subclass field, since subclasses overrides getRequestCtrl() and
107   - // getResultsCtrl().
  101 + public void sendQueries(ServicesList services) {
108 102 List<String> servicesUrls = services.getTargetUrls();
109   - LOGGER.info("Sending query(ies) on " + StringJoiner.join(servicesUrls));
  103 + LOGGER.info("Sending query(ies) at " + StringJoiner.join(servicesUrls));
110 104 for (int i = 0; i < servicesUrls.size(); i++) {
111 105 String query = getRequestCtrl().getQuery(services.getTableNames().get(i));
112   - if (i == 0) {
113   - getResultsCtrl().newVOTable(servicesUrls.get(i), query);
114   - } else {
115   - getResultsCtrl().appendVOTable(servicesUrls.get(i), query);
116   - }
  106 + getResultsCtrl().acquireVOTable(servicesUrls.get(i), query, i != 0);
117 107 }
118 108  
119 109 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/epntap/service/ServiceCtrl.java
... ... @@ -152,7 +152,7 @@ public class ServiceCtrl {
152 152 */
153 153 public static VOTABLE getVoTable(String query) throws VOTableException {
154 154 VOTableCtrl voTableCtrl = new VOTableCtrl();
155   - voTableCtrl.newVOTable(Consts.DEFAULT_REGISTRY_URL, query);
  155 + voTableCtrl.acquireVOTable(Consts.DEFAULT_REGISTRY_URL, query, false);
156 156 return voTableCtrl.getVOTable();
157 157 }
158 158  
... ... @@ -173,10 +173,10 @@ public class ServiceCtrl {
173 173 * @throws VOTableException Can not get the VOTable.
174 174 */
175 175 public static VOTableData getVoTableData(VOTABLE voTable) throws VOTableException {
176   - VOTableCtrl.checkVOTable(voTable);
177   -
  176 + VOTableCtrl ctrl = new VOTableCtrl();
  177 + ctrl.acquireVOTable(voTable, false);
178 178 Table table = (Table) voTable.getRESOURCE().get(0).getLINKAndTABLEOrRESOURCE().get(0);
179   - VOTableDataParser dataParser = new VOTableDataParser(table);
  179 + VOTableDataParser dataParser = new VOTableDataParser("Services list", table);
180 180 dataParser.parseData();
181 181 return dataParser.getData();
182 182 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainpanel/MainPanelCtrl.java
... ... @@ -16,21 +16,19 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.gui.mainpanel;
18 18  
19   -import java.awt.Cursor;
20 19 import java.io.File;
  20 +import java.io.IOException;
  21 +import java.nio.file.Files;
  22 +import java.nio.file.Paths;
21 23 import java.util.logging.Level;
22 24 import java.util.logging.Logger;
23 25  
24   -import javax.swing.JFrame;
25 26 import javax.swing.JOptionPane;
26   -import javax.swing.SwingUtilities;
27   -import javax.swing.SwingWorker;
28 27  
29 28 import eu.omp.irap.vespa.epntapclient.epntap.EpnTapController;
30 29 import eu.omp.irap.vespa.epntapclient.gui.requestpanel.RequestPanelCtrl;
31 30 import eu.omp.irap.vespa.epntapclient.gui.resultpanel.ResultPanelCtrl;
32 31 import eu.omp.irap.vespa.epntapclient.gui.servicespanel.ServicesPanelCtrl;
33   -import eu.omp.irap.vespa.votable.votable.VOTableException;
34 32  
35 33 /**
36 34 * @author N. Jourdane
... ... @@ -40,9 +38,6 @@ public class MainPanelCtrl extends EpnTapController implements MainPanelListener
40 38 /** The logger for the class MainPanelCtrl. */
41 39 private static final Logger LOGGER = Logger.getLogger(MainPanelCtrl.class.getName());
42 40  
43   - /** The swing worker for doing a send query. */
44   - private SwingWorker<Void, Void> sw;
45   -
46 41 /** The controller of the request panel. */
47 42 RequestPanelCtrl requestPanelCtrl;
48 43  
... ... @@ -64,40 +59,27 @@ public class MainPanelCtrl extends EpnTapController implements MainPanelListener
64 59 resultsPanelCtrl = new ResultPanelCtrl(this);
65 60 requestPanelCtrl = new RequestPanelCtrl(this);
66 61 view = new MainPanelView(this);
67   - SwingUtilities.invokeLater(run("EPN-TAP client", view));
68 62 }
69 63  
70   - /**
71   - * Creates runnable used to run the application GUI.
72   - *
73   - * @param title The title of the application window.
74   - * @param view The view of the VOTable, created by the VOTableController.
75   - * @return The runnable.
76   - */
77   - private static Runnable run(final String title, final MainPanelView view) {
78   - return new Runnable() {
79   -
80   - @Override
81   - public void run() {
82   - JFrame frame = new JFrame(title);
83   - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
84   - frame.setContentPane(view);
85   - frame.setVisible(true);
86   - frame.pack();
87   - frame.setLocationRelativeTo(null);
88   - }
89   - };
  64 + @Override
  65 + public void acquireServices() {
  66 + servicesPanelCtrl.acquire();
90 67 }
91 68  
92 69 @Override
93   - public void displayError(String message, Exception e) {
94   - LOGGER.log(Level.SEVERE, message, e);
95   - JOptionPane.showMessageDialog(view, e.getMessage(), message, JOptionPane.ERROR_MESSAGE);
  70 + public void displayError(String message, Exception error) {
  71 + LOGGER.log(Level.SEVERE, message, error);
  72 + JOptionPane.showMessageDialog(view, error.getMessage(), message, JOptionPane.ERROR_MESSAGE);
96 73 }
97 74  
98 75 @Override
99   - public void displayInfo(String message) {
100   - view.getResultsPanel().setStatusBarText(message);
  76 + public void displayInfo(String shortMessage, String detailledMessage) {
  77 + if (detailledMessage == null) {
  78 + LOGGER.info(shortMessage);
  79 + } else {
  80 + LOGGER.info(shortMessage + ": " + detailledMessage);
  81 + }
  82 + view.getStatusBarPanelView().setStatusBarText(shortMessage);
101 83 }
102 84  
103 85 /**
... ... @@ -132,57 +114,22 @@ public class MainPanelCtrl extends EpnTapController implements MainPanelListener
132 114 }
133 115  
134 116 @Override
135   - public void readServices() {
  117 + public void saveCurrentVOTable(File file) {
136 118 try {
137   - super.readServices();
138   - } catch (VOTableException e) {
139   - displayError("Can not read services.", e);
  119 + Files.copy(Paths.get(resultsPanelCtrl.getVOTablePath()),
  120 + Paths.get(file.getAbsolutePath()));
  121 + } catch (IOException e) {
  122 + displayError("Can not save the VOTable file.", e);
140 123 }
141   - view.getServicesPanel().fillTable(servicesPanelCtrl.getVOTableData());
142 124 }
143 125  
144 126 @Override
145   - public void sendQuery() {
146   - // Avoid multiple queries at the same time: stop the current first, then launch a new one.
147   - if (sw != null && !sw.isDone()) {
148   - sw.cancel(true);
149   - }
150   - sw = createNewWorker();
151   - view.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
152   - sw.execute();
  127 + public void sendQueries() {
  128 + sendQueries(servicesPanelCtrl.getServices());
153 129 }
154 130  
155 131 @Override
156 132 public void updateQuery() {
157 133 requestPanelCtrl.updateQuery();
158 134 }
159   -
160   - /**
161   - * Create a new {@link SwingWorker} for doing a send query.
162   - *
163   - * @return The created {@link SwingWorker}.
164   - */
165   - private SwingWorker<Void, Void> createNewWorker() {
166   - return new SwingWorker<Void, Void>() {
167   -
168   - @Override
169   - protected Void doInBackground() throws Exception {
170   - try {
171   - sendQueries(servicesPanelCtrl.getServices());
172   - } catch (VOTableException e) {
173   - displayError("Can not update the VOTable.", e);
174   - }
175   - return null;
176   - }
177   -
178   - @Override
179   - protected void done() {
180   - if (!isCancelled()) {
181   - String fName = new File(resultsPanelCtrl.getVOTablePath()).getName();
182   - resultsPanelCtrl.getView().addTable(fName, resultsPanelCtrl.getVOTableData());
183   - }
184   - view.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
185   - }
186   - };
187   - }
188 135 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainpanel/MainPanelListener.java
... ... @@ -16,33 +16,39 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.gui.mainpanel;
18 18  
  19 +import java.io.File;
  20 +
19 21 /**
20 22 * @author N. Jourdane
21 23 */
22 24 public interface MainPanelListener {
23 25  
24 26 /**
25   - * Ask the main panel to open a pop-up and display the specified error.
  27 + * Display an error message to the user.
26 28 *
27   - * @param message A short message describing the error, which will be the pop-up title.
28   - * @param e The error itself.
  29 + * @param message A short version of the message.
  30 + * @param error The exception related to the error.
29 31 */
30   - void displayError(String message, Exception e);
  32 + void displayError(String message, Exception error);
31 33  
32 34 /**
33   - * Display an informative message in the status bar.
  35 + * Display an informative message to the user.
34 36 *
35   - * @param message The message to display.
  37 + * @param shortMessage A short version of the message.
  38 + * @param detailledMessage The full message to display (optional, can be null).
36 39 */
37   - void displayInfo(String message);
  40 + void displayInfo(String shortMessage, String detailledMessage);
38 41  
39 42 /**
40   - * Ask the main panel to send the query.
  43 + * Ask the main panel to save the VOTable displayed in the focused tab on the result panel.
  44 + *
  45 + * @param file The file specified by the user on the FileChooser popup.
41 46 */
42   - void sendQuery();
  47 + void saveCurrentVOTable(File file);
43 48  
44   - /**
45   - * Ask the main panel to update the query.
46   - */
  49 + /** Ask the main panel to send the query. */
  50 + void sendQueries();
  51 +
  52 + /** Ask the main panel to update the query. */
47 53 void updateQuery();
48 54 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/mainpanel/MainPanelView.java
... ... @@ -26,6 +26,7 @@ import javax.swing.JSplitPane;
26 26 import eu.omp.irap.vespa.epntapclient.gui.requestpanel.RequestPanelView;
27 27 import eu.omp.irap.vespa.epntapclient.gui.resultpanel.ResultPanelView;
28 28 import eu.omp.irap.vespa.epntapclient.gui.servicespanel.ServicesPanelView;
  29 +import eu.omp.irap.vespa.epntapclient.gui.statusbarpanel.StatusBarPanelView;
29 30  
30 31 /**
31 32 * The main view of the application, which manage all the other views.
... ... @@ -34,7 +35,7 @@ import eu.omp.irap.vespa.epntapclient.gui.servicespanel.ServicesPanelView;
34 35 */
35 36 public class MainPanelView extends JPanel {
36 37  
37   - /** The serial version UID. */
  38 + /** The default serial version UID. */
38 39 private static final long serialVersionUID = 1L;
39 40  
40 41 /** The JPanel where the user build the query. */
... ... @@ -46,6 +47,9 @@ public class MainPanelView extends JPanel {
46 47 /** The JPanel where the list of services is displayed. */
47 48 private ServicesPanelView servicesPanel;
48 49  
  50 + /** The JPanel where the list of services is displayed. */
  51 + private StatusBarPanelView statusBarPanel;
  52 +
49 53  
50 54 /**
51 55 * The main view constructor, which create all the panels.
... ... @@ -57,6 +61,7 @@ public class MainPanelView extends JPanel {
57 61 servicesPanel = mainPanelCtrl.getServicesCtrl().getView();
58 62 resultPanel = mainPanelCtrl.getResultsCtrl().getView();
59 63 requestPanel = mainPanelCtrl.getRequestCtrl().getView();
  64 + statusBarPanel = new StatusBarPanelView();
60 65 buildMainView();
61 66 }
62 67  
... ... @@ -67,8 +72,7 @@ public class MainPanelView extends JPanel {
67 72 * @param message The message of the error.
68 73 */
69 74 public void displayError(String title, String message) {
70   - JOptionPane.showMessageDialog(this, message, title,
71   - JOptionPane.ERROR_MESSAGE);
  75 + JOptionPane.showMessageDialog(this, message, title, JOptionPane.ERROR_MESSAGE);
72 76 }
73 77  
74 78 /**
... ... @@ -93,6 +97,13 @@ public class MainPanelView extends JPanel {
93 97 }
94 98  
95 99 /**
  100 + * @return The view of the status bar panel.
  101 + */
  102 + public StatusBarPanelView getStatusBarPanelView() {
  103 + return statusBarPanel;
  104 + }
  105 +
  106 + /**
96 107 * Build the panel and add GUI elements on it.
97 108 */
98 109 private void buildMainView() {
... ... @@ -102,6 +113,7 @@ public class MainPanelView extends JPanel {
102 113 requestPanel);
103 114 JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, northPanel, resultPanel);
104 115 add(mainPanel, BorderLayout.CENTER);
  116 + add(statusBarPanel, BorderLayout.SOUTH);
105 117  
106 118 setSizes();
107 119 revalidate();
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelCtrl.java
... ... @@ -16,6 +16,8 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.gui.requestpanel;
18 18  
  19 +import java.io.File;
  20 +
19 21 import eu.omp.irap.vespa.epntapclient.epntap.request.RequestCtrl;
20 22 import eu.omp.irap.vespa.epntapclient.gui.mainpanel.MainPanelListener;
21 23  
... ... @@ -62,9 +64,14 @@ public class RequestPanelCtrl extends RequestCtrl implements RequestPanelListene
62 64 }
63 65  
64 66 @Override
  67 + public void onSaveButtonClicked(File file) {
  68 + listener.saveCurrentVOTable(file);
  69 + }
  70 +
  71 + @Override
65 72 public void onSendButtonClicked() {
66 73 setQuery(view.getQueryArea().getText());
67   - listener.sendQuery();
  74 + listener.sendQueries();
68 75 }
69 76  
70 77 /**
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelListener.java
... ... @@ -16,20 +16,23 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.gui.requestpanel;
18 18  
  19 +import java.io.File;
  20 +
19 21 /**
20 22 * @author N. Jourdane
21 23 */
22 24 public interface RequestPanelListener {
23 25  
24 26 /**
25   - * Method called when the user remove a parameter with a parameter field.
  27 + * This method is called when the user remove a parameter with a parameter field.
26 28 *
27 29 * @param paramName The name of the removed parameter
28 30 */
29 31 void onParameterRemoved(String paramName);
30 32  
31 33 /**
32   - * Method called when the user change a parameter (add or update) with a parameter field.
  34 + * This method is called when the user change a parameter (add or update) with a parameter
  35 + * field.
33 36 *
34 37 * @param paramName The name of the changed parameter.
35 38 * @param paramValue The new value of the parameter.
... ... @@ -37,7 +40,15 @@ public interface RequestPanelListener {
37 40 void onParameterUpdated(String paramName, Object paramValue);
38 41  
39 42 /**
40   - * Method called when the used click on the 'Send query' button.
  43 + * This method is called when the user clicks on the download button.
  44 + *
  45 + * @param file The file selected by the user in the FileChooser pop-up, corresponding to the
  46 + * place where save the VOTable.
  47 + */
  48 + void onSaveButtonClicked(File file);
  49 +
  50 + /**
  51 + * This method is called when the used click on the 'Send query' button.
41 52 */
42 53 void onSendButtonClicked();
43 54 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/RequestPanelView.java
... ... @@ -26,6 +26,7 @@ import java.util.List;
26 26 import javax.swing.BorderFactory;
27 27 import javax.swing.BoxLayout;
28 28 import javax.swing.JButton;
  29 +import javax.swing.JFileChooser;
29 30 import javax.swing.JPanel;
30 31 import javax.swing.JTextArea;
31 32  
... ... @@ -45,9 +46,12 @@ public class RequestPanelView extends JPanel {
45 46 /** The height of the buttons panel. */
46 47 private static final int BUTTON_PANEL_HEIGHT = 20;
47 48  
48   - /** The serial version UID. */
  49 + /** The default serial version UID. */
49 50 private static final long serialVersionUID = 1L;
50 51  
  52 + /** The GUI element of the button to move the file in the specified location. */
  53 + private JButton buttonSave;
  54 +
51 55 /** The GUI element of the button to send the query. */
52 56 private JButton buttonSend;
53 57  
... ... @@ -86,7 +90,7 @@ public class RequestPanelView extends JPanel {
86 90 /**
87 91 * Get the GUI element of the send button. If it doesn't exist, create it.
88 92 *
89   - * @return The button.
  93 + * @return The button to download and parse the VOTable.
90 94 */
91 95 public JButton getButtonSend() {
92 96 if (buttonSend == null) {
... ... @@ -160,9 +164,9 @@ public class RequestPanelView extends JPanel {
160 164 }
161 165  
162 166 /**
163   - * Get the GUI element of the target name field. If it doesn't exist, create it.
  167 + * Get the field where the user enter the target name. If it doesn't exist, create it.
164 168 *
165   - * @return The target name field.
  169 + * @return The TargetNameField object of the field.
166 170 */
167 171 public TargetNameField getTargetNameField() {
168 172 if (targetNameField == null) {
... ... @@ -186,6 +190,27 @@ public class RequestPanelView extends JPanel {
186 190 }
187 191  
188 192 /**
  193 + * Get the button to save the VOTable in the specified location. If it doesn't exist, create it.
  194 + *
  195 + * @return The JButton object.
  196 + */
  197 + public JButton saveFileButton() {
  198 + if (buttonSave == null) {
  199 + buttonSave = new JButton("Save File");
  200 + buttonSave.addActionListener(new ActionListener() {
  201 +
  202 + @Override
  203 + public void actionPerformed(ActionEvent evt) {
  204 + final JFileChooser fc = new JFileChooser();
  205 + fc.showOpenDialog(RequestPanelView.this);
  206 + listener.onSaveButtonClicked(fc.getSelectedFile());
  207 + }
  208 + });
  209 + }
  210 + return buttonSave;
  211 + }
  212 +
  213 + /**
189 214 * Update the query in the JTextArea.
190 215 *
191 216 * @param query The string literal to put in the text-area, which will override the old content.
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/requestpanel/paramfield/TargetNameField.java
... ... @@ -17,6 +17,7 @@
17 17 package eu.omp.irap.vespa.epntapclient.gui.requestpanel.paramfield;
18 18  
19 19 import java.awt.Dimension;
  20 +import java.io.File;
20 21 import java.util.logging.Level;
21 22 import java.util.logging.Logger;
22 23  
... ... @@ -93,6 +94,11 @@ public class TargetNameField extends ParamField implements TextFieldListener {
93 94 }
94 95  
95 96 @Override
  97 + public void onSaveButtonClicked(File file) {
  98 + /** No SaveButtonClicked event, we just want the field itself. */
  99 + }
  100 +
  101 + @Override
96 102 public void onSendButtonClicked() {
97 103 /** No SendButtonClicked event, we just want the field itself. */
98 104 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelCtrl.java
... ... @@ -16,16 +16,12 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.gui.resultpanel;
18 18  
19   -import java.io.File;
20   -import java.io.IOException;
21   -import java.nio.file.Files;
22   -import java.nio.file.Paths;
  19 +import java.awt.Cursor;
23 20 import java.util.logging.Logger;
24 21  
25 22 import eu.omp.irap.vespa.epntapclient.gui.mainpanel.MainPanelListener;
26 23 import eu.omp.irap.vespa.votable.utils.StringJoiner;
27 24 import eu.omp.irap.vespa.votable.votable.VOTableCtrl;
28   -import eu.omp.irap.vespa.votable.votable.VOTableException;
29 25  
30 26 /**
31 27 * @author N. Jourdane
... ... @@ -52,41 +48,38 @@ public class ResultPanelCtrl extends VOTableCtrl implements ResultPanelListener
52 48 view = new ResultPanelView(this);
53 49 }
54 50  
55   - /** Download and parse a VOTable, then add the result to the current tab in the result panel. */
56 51 @Override
57   - public void appendVOTable(String newTargetURL, String newQuery) {
58   - try {
59   - super.appendVOTable(newTargetURL, newQuery);
60   - } catch (VOTableException e) {
61   - listener.displayError("Can not update the VOTable.", e);
62   - }
63   - view.updateTable(voTableData);
  52 + public void displayError(String message, Exception error) {
  53 + listener.displayError(message, error);
64 54 }
65 55  
66 56 @Override
67 57 public void displayInfo(String shortMessage, String detailledMessage) {
68   - super.displayInfo(shortMessage, detailledMessage);
69   - listener.displayInfo(shortMessage);
  58 + listener.displayInfo(shortMessage, detailledMessage);
  59 + }
  60 +
  61 + @Override
  62 + public void fillTable() {
  63 + view.addTable(voTableData);
70 64 }
71 65  
72 66 /**
73   - * @return The view of the result panel. Used in MainPanelCtrl to add panels in the main window.
  67 + * @return The result panel view.
74 68 */
75 69 public ResultPanelView getView() {
76 70 return view;
77 71 }
78 72  
79 73 @Override
80   - public void onDownloadButtonClicked(File file) {
81   - try {
82   - Files.copy(Paths.get(voTablePath), Paths.get(file.getAbsolutePath()));
83   - } catch (IOException e) {
84   - listener.displayError("Can not save the VOTable file.", e);
  74 + public void onRowsSelected() {
  75 + if (view.getSelectedIndex() != -1) {
  76 + LOGGER.info("Selected row(s): " + StringJoiner.join(view.getSelectedRows()));
85 77 }
86 78 }
87 79  
88 80 @Override
89   - public void onRowsSelected() {
90   - LOGGER.info("Selected row: " + StringJoiner.join(view.getSelectedRows()));
  81 + public void setWaitCursor(boolean enableWaitcursor) {
  82 + int cursor = enableWaitcursor ? Cursor.WAIT_CURSOR : Cursor.DEFAULT_CURSOR;
  83 + view.setCursor(Cursor.getPredefinedCursor(cursor));
91 84 }
92 85 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelListener.java
... ... @@ -16,8 +16,6 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.gui.resultpanel;
18 18  
19   -import java.io.File;
20   -
21 19 import eu.omp.irap.vespa.votable.gui.VOTablePanelListener;
22 20  
23 21 /**
... ... @@ -25,11 +23,4 @@ import eu.omp.irap.vespa.votable.gui.VOTablePanelListener;
25 23 */
26 24 public interface ResultPanelListener extends VOTablePanelListener {
27 25  
28   - /**
29   - * This method is called when the user clicks on the download button.
30   - *
31   - * @param file The file selected by the user in the FileChooser pop-up, corresponding to the
32   - * place where save the VOTable.
33   - */
34   - public void onDownloadButtonClicked(File file);
35 26 }
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/resultpanel/ResultPanelView.java
... ... @@ -16,43 +16,21 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.gui.resultpanel;
18 18  
19   -import java.awt.BorderLayout;
20   -import java.awt.event.ActionEvent;
21   -import java.awt.event.ActionListener;
22   -import java.util.ArrayList;
23 19 import java.util.List;
24 20  
25   -import javax.swing.JButton;
26   -import javax.swing.JFileChooser;
27   -import javax.swing.JLabel;
28   -import javax.swing.JPanel;
29 21 import javax.swing.JTabbedPane;
30 22  
31   -import eu.omp.irap.vespa.votable.gui.VOTablePanelListener;
32 23 import eu.omp.irap.vespa.votable.gui.VOTablePanelView;
33 24 import eu.omp.irap.vespa.votable.votabledata.VOTableData;
34 25  
35 26 /**
36 27 * @author N. Jourdane
37 28 */
38   -public class ResultPanelView extends JPanel implements VOTablePanelListener {
  29 +public class ResultPanelView extends JTabbedPane {
39 30  
40   - /** The serial version UID. */
  31 + /** The default serial version UID. */
41 32 private static final long serialVersionUID = 1L;
42 33  
43   - /** The JPanel containing the buttons. */
44   - private JPanel buttonsPanel;
45   -
46   - /** The GUI element of the button to save the result of the query. */
47   - private JButton fileButton;
48   -
49   - /** A status bar, to display several informative messages. */
50   - private JLabel statusBar;
51   -
52   - private JTabbedPane tabbedPane;
53   -
54   - private List<VOTablePanelView> tablePanels;
55   -
56 34 /** The listener of the result panel. */
57 35 ResultPanelListener listener;
58 36  
... ... @@ -65,7 +43,6 @@ public class ResultPanelView extends JPanel implements VOTablePanelListener {
65 43 */
66 44 public ResultPanelView(ResultPanelListener listener) {
67 45 this.listener = listener;
68   - tablePanels = new ArrayList<>();
69 46 buildResultPanel();
70 47 }
71 48  
... ... @@ -74,63 +51,24 @@ public class ResultPanelView extends JPanel implements VOTablePanelListener {
74 51 *
75 52 * @param voTableData The VOTable data to add in a new tab.
76 53 */
77   - public void addTable(String title, VOTableData voTableData) {
78   - VOTablePanelView voTablePanel = new VOTablePanelView(this);
  54 + public void addTable(VOTableData voTableData) {
  55 + VOTablePanelView voTablePanel = new VOTablePanelView(listener);
79 56 voTablePanel.fillTable(voTableData);
80   - tablePanels.add(voTablePanel);
81   - tabbedPane.add(title, voTablePanel);
  57 + addTab(voTableData.getTitle(), voTablePanel);
82 58 }
83 59  
84 60 /**
85 61 * Build the panel and add graphical elements to it.
86 62 */
87 63 public void buildResultPanel() {
88   - tabbedPane = new JTabbedPane();
89   - JPanel bottomBar = new JPanel();
90   - bottomBar.setLayout(new BorderLayout());
91   - bottomBar.add(getStatusBar(), BorderLayout.CENTER);
92   - bottomBar.add(getButtonsPanel(), BorderLayout.EAST);
93   -
94   - add(tabbedPane, BorderLayout.CENTER);
95   - add(bottomBar, BorderLayout.SOUTH);
  64 + // setLayout(new BorderLayout());
96 65 }
97 66  
98 67 /**
99   - * Create if necessary the buttons panel, then return it.
100   - *
101   - * @return the buttons panel.
  68 + * @return The panel inside the current active tab.
102 69 */
103   - public JPanel getButtonsPanel() {
104   - if (buttonsPanel == null) {
105   - buttonsPanel = new JPanel();
106   - buttonsPanel.add(getFileButton());
107   - }
108   - return buttonsPanel;
109   - }
110   -
111 70 public VOTablePanelView getCurrentTablePanel() {
112   - return tablePanels.get(getSelectedTab());
113   - }
114   -
115   - /**
116   - * Returns the button to save the VOTable, create it if doesn't exist.
117   - *
118   - * @return The button to save the VOTable.
119   - */
120   - public JButton getFileButton() {
121   - if (fileButton == null) {
122   - fileButton = new JButton("Get File");
123   - fileButton.addActionListener(new ActionListener() {
124   -
125   - @Override
126   - public void actionPerformed(ActionEvent evt) {
127   - final JFileChooser fc = new JFileChooser();
128   - fc.showOpenDialog(ResultPanelView.this);
129   - listener.onDownloadButtonClicked(fc.getSelectedFile());
130   - }
131   - });
132   - }
133   - return fileButton;
  71 + return (VOTablePanelView) getComponentAt(getSelectedTab());
134 72 }
135 73  
136 74 /**
... ... @@ -144,31 +82,7 @@ public class ResultPanelView extends JPanel implements VOTablePanelListener {
144 82 * @return The index of the selected tab.
145 83 */
146 84 public int getSelectedTab() {
147   - return tabbedPane.getSelectedIndex();
148   - }
149   -
150   - /**
151   - * Returns the status bar, create it if doesn't exist.
152   - *
153   - * @return The status bar.
154   - */
155   - public JLabel getStatusBar() {
156   - if (statusBar == null) {
157   - statusBar = new JLabel("");
158   - }
159   - return statusBar;
160   - }
161   -
162   - @Override
163   - public void onRowsSelected() {
164   - // Do nothing yet when a row is selected.
165   - }
166   -
167   - /**
168   - * @param infoText The text to display in the status-bar, which will override the old one.
169   - */
170   - public void setStatusBarText(String infoText) {
171   - getStatusBar().setText(infoText);
  85 + return getSelectedIndex();
172 86 }
173 87  
174 88 /**
... ...
src/main/java/eu/omp/irap/vespa/epntapclient/gui/servicespanel/ServicesPanelCtrl.java
... ... @@ -16,6 +16,7 @@
16 16  
17 17 package eu.omp.irap.vespa.epntapclient.gui.servicespanel;
18 18  
  19 +import java.awt.Cursor;
19 20 import java.util.ArrayList;
20 21 import java.util.Arrays;
21 22 import java.util.List;
... ... @@ -53,15 +54,31 @@ public class ServicesPanelCtrl extends VOTableCtrl implements ServicesPanelListe
53 54 public ServicesPanelCtrl(MainPanelListener listener) {
54 55 this.listener = listener;
55 56 services = new ServicesList();
56   - targetUrl = Consts.DEFAULT_REGISTRY_URL;
57   - query = String.format(Queries.SELECT_ALL_TAP_SERVICES_WHERE_CORE, ServiceCore.EPNCORE);
58 57 view = new ServicesPanelView(this);
59 58 }
60 59  
  60 + /**
  61 + * Download and parse the list of services.
  62 + */
  63 + public void acquire() {
  64 + String getServicesQuery = String.format(Queries.SELECT_ALL_TAP_SERVICES_WHERE_CORE,
  65 + ServiceCore.EPNCORE);
  66 + acquireVOTable(Consts.DEFAULT_REGISTRY_URL, getServicesQuery, false);
  67 + }
  68 +
  69 + @Override
  70 + public void displayError(String message, Exception error) {
  71 + listener.displayError(message, error);
  72 + }
  73 +
61 74 @Override
62 75 public void displayInfo(String shortMessage, String detailledMessage) {
63   - super.displayInfo(shortMessage, detailledMessage);
64   - listener.displayInfo(shortMessage);
  76 + listener.displayInfo(shortMessage, detailledMessage);
  77 + }
  78 +
  79 + @Override
  80 + public void fillTable() {
  81 + view.fillTable(voTableData);
65 82 }
66 83  
67 84 /**
... ... @@ -99,8 +116,10 @@ public class ServicesPanelCtrl extends VOTableCtrl implements ServicesPanelListe
99 116 public void onServiceListUpdated() {
100 117 String newTableName = view.getTableNameTextField().getText();
101 118 String newTargetUrl = view.getServiceUrlTextField().getText();
102   - List<String> customTableNames = Arrays.asList(newTableName.split(CUSTOM_SERVICES_SEPARATOR));
103   - List<String> customServicesUrls = Arrays.asList(newTargetUrl.split(CUSTOM_SERVICES_SEPARATOR));
  119 + List<String> customTableNames = Arrays
  120 + .asList(newTableName.split(CUSTOM_SERVICES_SEPARATOR));
  121 + List<String> customServicesUrls = Arrays
  122 + .asList(newTargetUrl.split(CUSTOM_SERVICES_SEPARATOR));
104 123  
105 124 if (!newTableName.isEmpty() && !newTargetUrl.isEmpty()
106 125 && customTableNames.size() == customServicesUrls.size()) {
... ... @@ -108,4 +127,10 @@ public class ServicesPanelCtrl extends VOTableCtrl implements ServicesPanelListe
108 127 }
109 128 listener.updateQuery();
110 129 }
  130 +
  131 + @Override
  132 + public void setWaitCursor(boolean enableWaitcursor) {
  133 + int cursor = enableWaitcursor ? Cursor.WAIT_CURSOR : Cursor.DEFAULT_CURSOR;
  134 + view.setCursor(Cursor.getPredefinedCursor(cursor));
  135 + }
111 136 }
... ...