3 import jalview.bin.Cache;
4 import jalview.bin.Console;
5 import jalview.util.MessageManager;
6 import jalview.ws.WSDiscovererI;
7 import jalview.ws.slivkaws.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.CompletableFuture;
27 import javax.swing.BorderFactory;
28 import javax.swing.Box;
29 import javax.swing.BoxLayout;
30 import javax.swing.JButton;
31 import javax.swing.JOptionPane;
32 import javax.swing.JPanel;
33 import javax.swing.JProgressBar;
34 import javax.swing.JScrollPane;
35 import javax.swing.JTable;
36 import javax.swing.SwingUtilities;
37 import javax.swing.UIManager;
38 import javax.swing.table.AbstractTableModel;
39 import javax.swing.table.DefaultTableCellRenderer;
41 @SuppressWarnings("serial")
42 public class SlivkaPreferences extends JPanel
45 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
46 setPreferredSize(new Dimension(500, 450));
49 WSDiscovererI discoverer;
51 private final ArrayList<String> urls = new ArrayList<>();
53 private final Map<String, Integer> statuses = new HashMap<>();
55 private final AbstractTableModel urlTableModel = new AbstractTableModel()
57 final String[] columnNames = { "Service URL", "Status" };
60 public String getColumnName(int col)
62 return columnNames[col];
66 public Object getValueAt(int rowIndex, int columnIndex)
71 return urls.get(rowIndex);
73 return statuses.getOrDefault(urls.get(rowIndex), WSDiscovererI.STATUS_UNKNOWN);
75 throw new NoSuchElementException();
80 public int getRowCount()
86 public int getColumnCount()
92 private class WSStatusCellRenderer extends DefaultTableCellRenderer
95 public Component getTableCellRendererComponent(JTable table,
96 Object value, boolean isSelected, boolean hasFocus, int row,
99 setHorizontalAlignment(CENTER);
100 super.getTableCellRendererComponent(table, "\u25CF", isSelected,
101 hasFocus, row, column);
102 switch ((Integer) value)
104 case WSDiscovererI.STATUS_NO_SERVICES:
105 setForeground(Color.ORANGE);
107 case WSDiscovererI.STATUS_OK:
108 setForeground(Color.GREEN);
110 case WSDiscovererI.STATUS_INVALID:
111 setForeground(Color.RED);
113 case WSDiscovererI.STATUS_UNKNOWN:
115 setForeground(Color.LIGHT_GRAY);
121 private JTable urlListTable = new JTable(urlTableModel);
123 urlListTable.getColumnModel().getColumn(1).setMaxWidth(60);
124 urlListTable.getColumnModel().getColumn(1)
125 .setCellRenderer(new WSStatusCellRenderer());
128 // URL control panel buttons
129 JButton newWsUrl = new JButton(
130 MessageManager.getString("label.new_service_url"));
132 JButton editWsUrl = new JButton(
133 MessageManager.getString("label.edit_service_url"));
135 JButton deleteWsUrl = new JButton(
136 MessageManager.getString("label.delete_service_url"));
138 JButton moveUrlUp = new JButton(
139 MessageManager.getString("action.move_up"));
141 JButton moveUrlDown = new JButton(
142 MessageManager.getString("action.move_down"));
144 private String showEditUrlDialog(String oldUrl)
146 String input = (String) JvOptionPane
147 .showInternalInputDialog(
149 MessageManager.getString("label.url:"),
150 UIManager.getString("OptionPane.inputDialogTitle", MessageManager.getLocale()),
151 JOptionPane.QUESTION_MESSAGE,
162 } catch (MalformedURLException ex)
164 JvOptionPane.showInternalMessageDialog(this,
165 MessageManager.getString("label.invalid_url"),
166 UIManager.getString("OptionPane.messageDialogTitle",
167 MessageManager.getLocale()),
168 JOptionPane.WARNING_MESSAGE);
174 // Button Action Listeners
175 private ActionListener newUrlAction = (ActionEvent e) -> {
176 final String input = showEditUrlDialog("");
180 reloadStatusForUrl(input);
181 urlTableModel.fireTableRowsInserted(urls.size(), urls.size());
182 discoverer.setServiceUrls(urls);
186 private ActionListener editUrlAction = (ActionEvent e) -> {
187 final int i = urlListTable.getSelectedRow();
190 final String input = showEditUrlDialog(urls.get(i));
194 statuses.remove(input);
195 reloadStatusForUrl(input);
196 urlTableModel.fireTableRowsUpdated(i, i);
197 discoverer.setServiceUrls(urls);
202 private ActionListener deleteUrlAction = (ActionEvent e) -> {
203 final int i = urlListTable.getSelectedRow();
208 urlTableModel.fireTableRowsDeleted(i, i);
209 discoverer.setServiceUrls(urls);
213 private ActionListener moveUrlUpAction = (ActionEvent e) -> {
214 final int i = urlListTable.getSelectedRow();
217 moveTableRow(i, i - 1);
218 discoverer.setServiceUrls(urls);
222 private ActionListener moveUrlDownAction = (ActionEvent e) -> {
223 final int i = urlListTable.getSelectedRow();
224 if (i >= 0 && i < urls.size() - 1)
226 moveTableRow(i, i + 1);
227 discoverer.setServiceUrls(urls);
231 private MouseListener tableClickListener = new MouseAdapter()
233 final ActionEvent actionEvent = new ActionEvent(urlListTable,
234 ActionEvent.ACTION_PERFORMED, "edit");
237 public void mouseClicked(MouseEvent e)
239 if (e.getClickCount() > 1)
241 editUrlAction.actionPerformed(actionEvent);
246 // Setting up URL list Pane
248 Font font = new Font("Verdana", Font.PLAIN, 10);
249 JPanel urlPaneContainer = new JPanel(new BorderLayout(5, 5));
250 urlPaneContainer.setBorder(BorderFactory.createCompoundBorder(
251 BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
252 "Slivka Web Services"),
253 BorderFactory.createEmptyBorder(10, 5, 5, 5)));
255 newWsUrl.setFont(font);
256 editWsUrl.setFont(font);
257 deleteWsUrl.setFont(font);
258 moveUrlUp.setFont(font);
259 moveUrlDown.setFont(font);
260 JPanel editContainer = new JPanel();
261 editContainer.add(newWsUrl);
262 editContainer.add(editWsUrl);
263 editContainer.add(deleteWsUrl);
264 urlPaneContainer.add(editContainer, BorderLayout.PAGE_END);
266 JPanel moveContainer = new JPanel();
268 .setLayout(new BoxLayout(moveContainer, BoxLayout.PAGE_AXIS));
269 moveContainer.add(moveUrlUp);
270 moveContainer.add(Box.createRigidArea(new Dimension(0, 5)));
271 moveContainer.add(moveUrlDown);
272 urlPaneContainer.add(moveContainer, BorderLayout.LINE_START);
274 urlPaneContainer.add(new JScrollPane(urlListTable),
275 BorderLayout.CENTER);
276 this.add(urlPaneContainer);
278 // Connecting action listeners
279 urlListTable.addMouseListener(tableClickListener);
280 newWsUrl.addActionListener(newUrlAction);
281 editWsUrl.addActionListener(editUrlAction);
282 deleteWsUrl.addActionListener(deleteUrlAction);
283 moveUrlUp.addActionListener(moveUrlUpAction);
284 moveUrlDown.addActionListener(moveUrlDownAction);
287 private void moveTableRow(int fromIndex, int toIndex)
289 String url = urls.get(fromIndex);
290 int status = statuses.get(fromIndex);
291 urls.set(fromIndex, urls.get(toIndex));
292 urls.set(toIndex, url);
293 if (urlListTable.getSelectedRow() == fromIndex)
295 urlListTable.setRowSelectionInterval(toIndex, toIndex);
297 int firstRow = Math.min(toIndex, fromIndex);
298 int lastRow = Math.max(fromIndex, toIndex);
299 urlTableModel.fireTableRowsUpdated(firstRow, lastRow);
302 // Discoverer reloading buttons
303 JButton refreshServices = new JButton(
304 MessageManager.getString("action.refresh_services"));
306 JButton resetServices = new JButton(
307 MessageManager.getString("action.reset_services"));
309 JProgressBar progressBar = new JProgressBar();
311 // Discoverer buttons action listeners
312 private ActionListener refreshServicesAction = (ActionEvent e) -> {
313 progressBar.setVisible(true);
314 Console.info("Requesting service reload");
315 discoverer.startDiscoverer().handle((_discoverer, exception) -> {
316 if (exception == null)
318 Console.info("Reloading done");
322 Console.error("Reloading failed", exception);
324 SwingUtilities.invokeLater(() -> progressBar.setVisible(false));
329 private ActionListener resetServicesAction = (ActionEvent e) -> {
330 discoverer.setServiceUrls(null);
333 urls.addAll(discoverer.getServiceUrls());
334 for (String url : urls)
336 reloadStatusForUrl(url);
338 urlTableModel.fireTableDataChanged();
342 Font font = new Font("Verdana", Font.PLAIN, 11);
343 refreshServices.setFont(font);
344 resetServices.setFont(font);
345 JPanel container = new JPanel();
346 container.add(refreshServices);
347 container.add(resetServices);
350 // Connecting action listeners
351 refreshServices.addActionListener(refreshServicesAction);
352 resetServices.addActionListener(resetServicesAction);
356 progressBar.setVisible(false);
357 progressBar.setIndeterminate(true);
363 // Initial URLs loading
364 discoverer = SlivkaWSDiscoverer.getInstance();
365 urls.addAll(discoverer.getServiceUrls());
366 for (String url : urls)
368 reloadStatusForUrl(url);
372 private void reloadStatusForUrl(String url)
374 CompletableFuture.supplyAsync(() -> discoverer.getServerStatusFor(url))
375 .thenAccept((status) -> {
376 statuses.put(url, status);
377 int row = urls.indexOf(url);
379 urlTableModel.fireTableCellUpdated(row, 1);