3 import jalview.bin.Cache;
4 import jalview.bin.Console;
5 import jalview.util.MessageManager;
6 import jalview.ws2.client.api.WebServiceDiscovererI;
7 import jalview.ws2.client.slivka.SlivkaWSDiscoverer;
9 import java.awt.BorderLayout;
10 import java.awt.Color;
11 import java.awt.Component;
12 import java.awt.Dimension;
14 import java.awt.event.ActionEvent;
15 import java.awt.event.ActionListener;
16 import java.awt.event.MouseAdapter;
17 import java.awt.event.MouseEvent;
18 import java.awt.event.MouseListener;
19 import java.net.MalformedURLException;
21 import java.util.ArrayList;
22 import java.util.HashMap;
24 import java.util.NoSuchElementException;
25 import java.util.concurrent.CancellationException;
26 import java.util.concurrent.CompletableFuture;
28 import javax.swing.BorderFactory;
29 import javax.swing.Box;
30 import javax.swing.BoxLayout;
31 import javax.swing.JButton;
32 import javax.swing.JOptionPane;
33 import javax.swing.JPanel;
34 import javax.swing.JProgressBar;
35 import javax.swing.JScrollPane;
36 import javax.swing.JTable;
37 import javax.swing.SwingUtilities;
38 import javax.swing.UIManager;
39 import javax.swing.table.AbstractTableModel;
40 import javax.swing.table.DefaultTableCellRenderer;
43 @SuppressWarnings("serial")
44 public class SlivkaPreferences extends JPanel
47 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
48 setPreferredSize(new Dimension(500, 450));
51 WebServiceDiscovererI discoverer;
53 private final ArrayList<URL> urls = new ArrayList<>();
55 private final Map<URL, Integer> statuses = new HashMap<>();
57 private final AbstractTableModel urlTableModel = new AbstractTableModel()
59 final String[] columnNames = { "Service URL", "Status" };
62 public String getColumnName(int col)
64 return columnNames[col];
68 public Object getValueAt(int rowIndex, int columnIndex)
73 return urls.get(rowIndex).toString();
75 return statuses.getOrDefault(urls.get(rowIndex), WebServiceDiscovererI.STATUS_UNKNOWN);
77 throw new NoSuchElementException();
82 public int getRowCount()
88 public int getColumnCount()
94 private class WSStatusCellRenderer extends DefaultTableCellRenderer
97 public Component getTableCellRendererComponent(JTable table,
98 Object value, boolean isSelected, boolean hasFocus, int row,
101 setHorizontalAlignment(CENTER);
102 super.getTableCellRendererComponent(table, "\u25CF", isSelected,
103 hasFocus, row, column);
104 switch ((Integer) value)
106 case WebServiceDiscovererI.STATUS_NO_SERVICES:
107 setForeground(Color.ORANGE);
109 case WebServiceDiscovererI.STATUS_OK:
110 setForeground(Color.GREEN);
112 case WebServiceDiscovererI.STATUS_INVALID:
113 setForeground(Color.RED);
115 case WebServiceDiscovererI.STATUS_UNKNOWN:
117 setForeground(Color.LIGHT_GRAY);
123 private JTable urlListTable = new JTable(urlTableModel);
125 urlListTable.getColumnModel().getColumn(1).setMaxWidth(60);
126 urlListTable.getColumnModel().getColumn(1)
127 .setCellRenderer(new WSStatusCellRenderer());
130 // URL control panel buttons
131 JButton newWsUrl = new JButton(
132 MessageManager.getString("label.new_service_url"));
134 JButton editWsUrl = new JButton(
135 MessageManager.getString("label.edit_service_url"));
137 JButton deleteWsUrl = new JButton(
138 MessageManager.getString("label.delete_service_url"));
140 JButton moveUrlUp = new JButton(
141 MessageManager.getString("action.move_up"));
143 JButton moveUrlDown = new JButton(
144 MessageManager.getString("action.move_down"));
146 private URL showEditUrlDialog(String oldUrl)
148 String input = (String) JvOptionPane
149 .showInternalInputDialog(
151 MessageManager.getString("label.url:"),
152 UIManager.getString("OptionPane.inputDialogTitle", MessageManager.getLocale()),
153 JOptionPane.QUESTION_MESSAGE,
163 return new URL(input);
164 } catch (MalformedURLException ex)
166 JvOptionPane.showInternalMessageDialog(this,
167 MessageManager.getString("label.invalid_url"),
168 UIManager.getString("OptionPane.messageDialogTitle",
169 MessageManager.getLocale()),
170 JOptionPane.WARNING_MESSAGE);
175 // Button Action Listeners
176 private ActionListener newUrlAction = (ActionEvent e) -> {
177 final URL input = showEditUrlDialog("");
181 reloadStatusForUrl(input);
182 urlTableModel.fireTableRowsInserted(urls.size(), urls.size());
183 discoverer.setUrls(urls);
187 private ActionListener editUrlAction = (ActionEvent e) -> {
188 final int i = urlListTable.getSelectedRow();
191 final URL input = showEditUrlDialog(urls.get(i).toString());
195 statuses.remove(input);
196 reloadStatusForUrl(input);
197 urlTableModel.fireTableRowsUpdated(i, i);
198 discoverer.setUrls(urls);
203 private ActionListener deleteUrlAction = (ActionEvent e) -> {
204 final int i = urlListTable.getSelectedRow();
209 urlTableModel.fireTableRowsDeleted(i, i);
210 discoverer.setUrls(urls);
214 private ActionListener moveUrlUpAction = (ActionEvent e) -> {
215 final int i = urlListTable.getSelectedRow();
218 moveTableRow(i, i - 1);
219 discoverer.setUrls(urls);
223 private ActionListener moveUrlDownAction = (ActionEvent e) -> {
224 final int i = urlListTable.getSelectedRow();
225 if (i >= 0 && i < urls.size() - 1)
227 moveTableRow(i, i + 1);
228 discoverer.setUrls(urls);
232 private MouseListener tableClickListener = new MouseAdapter()
234 final ActionEvent actionEvent = new ActionEvent(urlListTable,
235 ActionEvent.ACTION_PERFORMED, "edit");
238 public void mouseClicked(MouseEvent e)
240 if (e.getClickCount() > 1)
242 editUrlAction.actionPerformed(actionEvent);
247 // Setting up URL list Pane
249 Font font = new Font("Verdana", Font.PLAIN, 10);
250 JPanel urlPaneContainer = new JPanel(new BorderLayout(5, 5));
251 urlPaneContainer.setBorder(BorderFactory.createCompoundBorder(
252 BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
253 "Slivka Web Services"),
254 BorderFactory.createEmptyBorder(10, 5, 5, 5)));
256 newWsUrl.setFont(font);
257 editWsUrl.setFont(font);
258 deleteWsUrl.setFont(font);
259 moveUrlUp.setFont(font);
260 moveUrlDown.setFont(font);
261 JPanel editContainer = new JPanel();
262 editContainer.add(newWsUrl);
263 editContainer.add(editWsUrl);
264 editContainer.add(deleteWsUrl);
265 urlPaneContainer.add(editContainer, BorderLayout.PAGE_END);
267 JPanel moveContainer = new JPanel();
269 .setLayout(new BoxLayout(moveContainer, BoxLayout.PAGE_AXIS));
270 moveContainer.add(moveUrlUp);
271 moveContainer.add(Box.createRigidArea(new Dimension(0, 5)));
272 moveContainer.add(moveUrlDown);
273 urlPaneContainer.add(moveContainer, BorderLayout.LINE_START);
275 urlPaneContainer.add(new JScrollPane(urlListTable),
276 BorderLayout.CENTER);
277 this.add(urlPaneContainer);
279 // Connecting action listeners
280 urlListTable.addMouseListener(tableClickListener);
281 newWsUrl.addActionListener(newUrlAction);
282 editWsUrl.addActionListener(editUrlAction);
283 deleteWsUrl.addActionListener(deleteUrlAction);
284 moveUrlUp.addActionListener(moveUrlUpAction);
285 moveUrlDown.addActionListener(moveUrlDownAction);
288 private void moveTableRow(int fromIndex, int toIndex)
290 URL url = urls.get(fromIndex);
291 int status = statuses.get(fromIndex);
292 urls.set(fromIndex, urls.get(toIndex));
293 urls.set(toIndex, url);
294 if (urlListTable.getSelectedRow() == fromIndex)
296 urlListTable.setRowSelectionInterval(toIndex, toIndex);
298 int firstRow = Math.min(toIndex, fromIndex);
299 int lastRow = Math.max(fromIndex, toIndex);
300 urlTableModel.fireTableRowsUpdated(firstRow, lastRow);
303 // Discoverer reloading buttons
304 JButton refreshServices = new JButton(
305 MessageManager.getString("action.refresh_services"));
307 JButton resetServices = new JButton(
308 MessageManager.getString("action.reset_services"));
310 JProgressBar progressBar = new JProgressBar();
312 // Discoverer buttons action listeners
313 private ActionListener refreshServicesAction = (ActionEvent e) -> {
314 progressBar.setVisible(true);
315 Console.info("Requesting service reload");
316 discoverer.startDiscoverer().handle((services, exception) -> {
317 if (exception == null)
319 Console.info("Reloading done");
321 else if (exception instanceof CancellationException)
323 Console.info("Reloading cancelled");
326 Console.error("Reloading failed", exception);
328 SwingUtilities.invokeLater(() -> progressBar.setVisible(false));
333 private ActionListener resetServicesAction = (ActionEvent e) -> {
334 discoverer.setUrls(null);
337 urls.addAll(discoverer.getUrls());
340 reloadStatusForUrl(url);
342 urlTableModel.fireTableDataChanged();
346 Font font = new Font("Verdana", Font.PLAIN, 11);
347 refreshServices.setFont(font);
348 resetServices.setFont(font);
349 JPanel container = new JPanel();
350 container.add(refreshServices);
351 container.add(resetServices);
354 // Connecting action listeners
355 refreshServices.addActionListener(refreshServicesAction);
356 resetServices.addActionListener(resetServicesAction);
360 progressBar.setVisible(false);
361 progressBar.setIndeterminate(true);
367 // Initial URLs loading
368 discoverer = SlivkaWSDiscoverer.getInstance();
369 urls.addAll(discoverer.getUrls());
372 reloadStatusForUrl(url);
376 private void reloadStatusForUrl(URL url)
378 CompletableFuture.supplyAsync(() -> discoverer.getStatusForUrl(url))
379 .thenAccept((status) -> {
380 statuses.put(url, status);
381 int row = urls.indexOf(url);
383 urlTableModel.fireTableCellUpdated(row, 1);