Clover icon

Coverage Report

  1. Project Clover database Wed Dec 3 2025 17:03:17 GMT
  2. Package jalview.gui

File SlivkaPreferences.java

 

Coverage histogram

../../img/srcFileCovDistChart4.png
49% of files have more coverage

Code metrics

8
142
15
2
384
333
26
0.18
9.47
7.5
1.73

Classes

Class Line # Actions
SlivkaPreferences 42 126 21
0.4459459544.6%
SlivkaPreferences.WSStatusCellRenderer 92 16 5
0.00%
 

Contributing tests

This file is covered by 2 tests. .

Source view

1    package jalview.gui;
2   
3    import java.awt.BorderLayout;
4    import java.awt.Color;
5    import java.awt.Component;
6    import java.awt.Dimension;
7    import java.awt.Font;
8    import java.awt.event.ActionEvent;
9    import java.awt.event.ActionListener;
10    import java.awt.event.MouseAdapter;
11    import java.awt.event.MouseEvent;
12    import java.awt.event.MouseListener;
13    import java.net.MalformedURLException;
14    import java.net.URL;
15    import java.util.ArrayList;
16    import java.util.HashMap;
17    import java.util.Map;
18    import java.util.NoSuchElementException;
19    import java.util.concurrent.CancellationException;
20    import java.util.concurrent.CompletableFuture;
21   
22    import javax.swing.BorderFactory;
23    import javax.swing.Box;
24    import javax.swing.BoxLayout;
25    import javax.swing.JButton;
26    import javax.swing.JOptionPane;
27    import javax.swing.JPanel;
28    import javax.swing.JProgressBar;
29    import javax.swing.JScrollPane;
30    import javax.swing.JTable;
31    import javax.swing.SwingUtilities;
32    import javax.swing.UIManager;
33    import javax.swing.table.AbstractTableModel;
34    import javax.swing.table.DefaultTableCellRenderer;
35   
36    import jalview.bin.Console;
37    import jalview.util.MessageManager;
38    import jalview.ws2.client.api.WebServiceDiscovererI;
39    import jalview.ws2.client.slivka.SlivkaWSDiscoverer;
40   
41    @SuppressWarnings("serial")
 
42    public class SlivkaPreferences extends JPanel
43    {
 
44  11 toggle {
45  11 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
46  11 setPreferredSize(new Dimension(500, 450));
47    }
48   
49    WebServiceDiscovererI discoverer;
50   
51    private final ArrayList<URL> urls = new ArrayList<>();
52   
53    private final Map<URL, Integer> statuses = new HashMap<>();
54   
55    private final AbstractTableModel urlTableModel = new AbstractTableModel()
56    {
57    final String[] columnNames = { "Service URL", "Status" };
58   
 
59  22 toggle @Override
60    public String getColumnName(int col)
61    {
62  22 return columnNames[col];
63    }
64   
 
65  0 toggle @Override
66    public Object getValueAt(int rowIndex, int columnIndex)
67    {
68  0 switch (columnIndex)
69    {
70  0 case 0:
71  0 return urls.get(rowIndex).toString();
72  0 case 1:
73  0 return statuses.getOrDefault(urls.get(rowIndex), WebServiceDiscovererI.STATUS_UNKNOWN);
74  0 default:
75  0 throw new NoSuchElementException();
76    }
77    }
78   
 
79  6 toggle @Override
80    public int getRowCount()
81    {
82  6 return urls.size();
83    }
84   
 
85  33 toggle @Override
86    public int getColumnCount()
87    {
88  33 return 2;
89    }
90    };
91   
 
92    private class WSStatusCellRenderer extends DefaultTableCellRenderer
93    {
 
94  0 toggle @Override
95    public Component getTableCellRendererComponent(JTable table,
96    Object value, boolean isSelected, boolean hasFocus, int row,
97    int column)
98    {
99  0 setHorizontalAlignment(CENTER);
100  0 super.getTableCellRendererComponent(table, "\u25CF", isSelected,
101    hasFocus, row, column);
102  0 switch ((Integer) value)
103    {
104  0 case WebServiceDiscovererI.STATUS_NO_SERVICES:
105  0 setForeground(Color.ORANGE);
106  0 break;
107  0 case WebServiceDiscovererI.STATUS_OK:
108  0 setForeground(Color.GREEN);
109  0 break;
110  0 case WebServiceDiscovererI.STATUS_INVALID:
111  0 setForeground(Color.RED);
112  0 break;
113  0 case WebServiceDiscovererI.STATUS_UNKNOWN:
114  0 default:
115  0 setForeground(Color.LIGHT_GRAY);
116    }
117  0 return this;
118    }
119    }
120   
121    private JTable urlListTable = new JTable(urlTableModel);
 
122  11 toggle {
123  11 urlListTable.getColumnModel().getColumn(1).setMaxWidth(60);
124  11 urlListTable.getColumnModel().getColumn(1)
125    .setCellRenderer(new WSStatusCellRenderer());
126    }
127   
128    // URL control panel buttons
129    JButton newWsUrl = new JButton(
130    MessageManager.getString("label.new_service_url"));
131   
132    JButton editWsUrl = new JButton(
133    MessageManager.getString("label.edit_service_url"));
134   
135    JButton deleteWsUrl = new JButton(
136    MessageManager.getString("label.delete_service_url"));
137   
138    JButton moveUrlUp = new JButton(
139    MessageManager.getString("action.move_up"));
140   
141    JButton moveUrlDown = new JButton(
142    MessageManager.getString("action.move_down"));
143   
 
144  0 toggle private URL showEditUrlDialog(String oldUrl)
145    {
146  0 String input = (String) JvOptionPane
147    .showInternalInputDialog(
148    this,
149    MessageManager.getString("label.url:"),
150    UIManager.getString("OptionPane.inputDialogTitle", MessageManager.getLocale()),
151    JOptionPane.QUESTION_MESSAGE,
152    null,
153    null,
154    oldUrl);
155  0 if (input == null)
156    {
157  0 return null;
158    }
159  0 try
160    {
161  0 return new URL(input);
162    } catch (MalformedURLException ex)
163    {
164  0 JvOptionPane.showInternalMessageDialog(this,
165    MessageManager.getString("label.invalid_url"),
166    UIManager.getString("OptionPane.messageDialogTitle",
167    MessageManager.getLocale()),
168    JOptionPane.WARNING_MESSAGE);
169  0 return null;
170    }
171    }
172   
173    // Button Action Listeners
174    private ActionListener newUrlAction = (ActionEvent e) -> {
175  0 final URL input = showEditUrlDialog("");
176  0 if (input != null)
177    {
178  0 urls.add(input);
179  0 reloadStatusForUrl(input);
180  0 urlTableModel.fireTableRowsInserted(urls.size(), urls.size());
181  0 discoverer.setUrls(urls);
182    }
183    };
184   
185    private ActionListener editUrlAction = (ActionEvent e) -> {
186  0 final int i = urlListTable.getSelectedRow();
187  0 if (i >= 0)
188    {
189  0 final URL input = showEditUrlDialog(urls.get(i).toString());
190  0 if (input != null)
191    {
192  0 urls.set(i, input);
193  0 statuses.remove(input);
194  0 reloadStatusForUrl(input);
195  0 urlTableModel.fireTableRowsUpdated(i, i);
196  0 discoverer.setUrls(urls);
197    }
198    }
199    };
200   
201    private ActionListener deleteUrlAction = (ActionEvent e) -> {
202  0 final int i = urlListTable.getSelectedRow();
203  0 if (i >= 0)
204    {
205  0 urls.remove(i);
206  0 statuses.remove(i);
207  0 urlTableModel.fireTableRowsDeleted(i, i);
208  0 discoverer.setUrls(urls);
209    }
210    };
211   
212    private ActionListener moveUrlUpAction = (ActionEvent e) -> {
213  0 final int i = urlListTable.getSelectedRow();
214  0 if (i > 0)
215    {
216  0 moveTableRow(i, i - 1);
217  0 discoverer.setUrls(urls);
218    }
219    };
220   
221    private ActionListener moveUrlDownAction = (ActionEvent e) -> {
222  0 final int i = urlListTable.getSelectedRow();
223  0 if (i >= 0 && i < urls.size() - 1)
224    {
225  0 moveTableRow(i, i + 1);
226  0 discoverer.setUrls(urls);
227    }
228    };
229   
230    private MouseListener tableClickListener = new MouseAdapter()
231    {
232    final ActionEvent actionEvent = new ActionEvent(urlListTable,
233    ActionEvent.ACTION_PERFORMED, "edit");
234   
 
235  0 toggle @Override
236    public void mouseClicked(MouseEvent e)
237    {
238  0 if (e.getClickCount() > 1)
239    {
240  0 editUrlAction.actionPerformed(actionEvent);
241    }
242    }
243    };
244   
245    // Setting up URL list Pane
 
246  11 toggle {
247  11 Font font = new Font("Verdana", Font.PLAIN, 10);
248  11 JPanel urlPaneContainer = new JPanel(new BorderLayout(5, 5));
249  11 urlPaneContainer.setBorder(BorderFactory.createCompoundBorder(
250    BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
251    "Slivka Web Services"),
252    BorderFactory.createEmptyBorder(10, 5, 5, 5)));
253   
254  11 newWsUrl.setFont(font);
255  11 editWsUrl.setFont(font);
256  11 deleteWsUrl.setFont(font);
257  11 moveUrlUp.setFont(font);
258  11 moveUrlDown.setFont(font);
259  11 JPanel editContainer = new JPanel();
260  11 editContainer.add(newWsUrl);
261  11 editContainer.add(editWsUrl);
262  11 editContainer.add(deleteWsUrl);
263  11 urlPaneContainer.add(editContainer, BorderLayout.PAGE_END);
264   
265  11 JPanel moveContainer = new JPanel();
266  11 moveContainer
267    .setLayout(new BoxLayout(moveContainer, BoxLayout.PAGE_AXIS));
268  11 moveContainer.add(moveUrlUp);
269  11 moveContainer.add(Box.createRigidArea(new Dimension(0, 5)));
270  11 moveContainer.add(moveUrlDown);
271  11 urlPaneContainer.add(moveContainer, BorderLayout.LINE_START);
272   
273  11 urlPaneContainer.add(new JScrollPane(urlListTable),
274    BorderLayout.CENTER);
275  11 this.add(urlPaneContainer);
276   
277    // Connecting action listeners
278  11 urlListTable.addMouseListener(tableClickListener);
279  11 newWsUrl.addActionListener(newUrlAction);
280  11 editWsUrl.addActionListener(editUrlAction);
281  11 deleteWsUrl.addActionListener(deleteUrlAction);
282  11 moveUrlUp.addActionListener(moveUrlUpAction);
283  11 moveUrlDown.addActionListener(moveUrlDownAction);
284    }
285   
 
286  0 toggle private void moveTableRow(int fromIndex, int toIndex)
287    {
288  0 URL url = urls.get(fromIndex);
289  0 int status = statuses.get(fromIndex);
290  0 urls.set(fromIndex, urls.get(toIndex));
291  0 urls.set(toIndex, url);
292  0 if (urlListTable.getSelectedRow() == fromIndex)
293    {
294  0 urlListTable.setRowSelectionInterval(toIndex, toIndex);
295    }
296  0 int firstRow = Math.min(toIndex, fromIndex);
297  0 int lastRow = Math.max(fromIndex, toIndex);
298  0 urlTableModel.fireTableRowsUpdated(firstRow, lastRow);
299    }
300   
301    // Discoverer reloading buttons
302    JButton refreshServices = new JButton(
303    MessageManager.getString("action.refresh_services"));
304   
305    JButton resetServices = new JButton(
306    MessageManager.getString("action.reset_services"));
307   
308    JProgressBar progressBar = new JProgressBar();
309   
310    // Discoverer buttons action listeners
311    private ActionListener refreshServicesAction = (ActionEvent e) -> {
312  0 progressBar.setVisible(true);
313  0 Console.info("Requesting service reload");
314  0 discoverer.startDiscoverer().handle((services, exception) -> {
315  0 if (exception == null)
316    {
317  0 Console.info("Reloading done");
318    }
319  0 else if (exception instanceof CancellationException)
320    {
321  0 Console.info("Reloading cancelled");
322    }
323    else {
324  0 Console.error("Reloading failed", exception);
325    }
326  0 SwingUtilities.invokeLater(() -> progressBar.setVisible(false));
327  0 return null;
328    });
329    };
330   
331    private ActionListener resetServicesAction = (ActionEvent e) -> {
332  0 discoverer.setUrls(null);
333  0 urls.clear();
334  0 statuses.clear();
335  0 urls.addAll(discoverer.getUrls());
336  0 for (URL url : urls)
337    {
338  0 reloadStatusForUrl(url);
339    }
340  0 urlTableModel.fireTableDataChanged();
341    };
342   
 
343  11 toggle {
344  11 Font font = new Font("Verdana", Font.PLAIN, 11);
345  11 refreshServices.setFont(font);
346  11 resetServices.setFont(font);
347  11 JPanel container = new JPanel();
348  11 container.add(refreshServices);
349  11 container.add(resetServices);
350  11 this.add(container);
351   
352    // Connecting action listeners
353  11 refreshServices.addActionListener(refreshServicesAction);
354  11 resetServices.addActionListener(resetServicesAction);
355    }
356   
 
357  11 toggle {
358  11 progressBar.setVisible(false);
359  11 progressBar.setIndeterminate(true);
360  11 add(progressBar);
361    }
362   
 
363  11 toggle SlivkaPreferences()
364    {
365    // Initial URLs loading
366  11 discoverer = SlivkaWSDiscoverer.getInstance();
367  11 urls.addAll(discoverer.getUrls());
368  11 for (URL url : urls)
369    {
370  11 reloadStatusForUrl(url);
371    }
372    }
373   
 
374  11 toggle private void reloadStatusForUrl(URL url)
375    {
376  11 CompletableFuture.supplyAsync(() -> discoverer.getStatusForUrl(url))
377    .thenAccept((status) -> {
378  6 statuses.put(url, status);
379  6 int row = urls.indexOf(url);
380  6 if (row >= 0)
381  6 urlTableModel.fireTableCellUpdated(row, 1);
382    });
383    }
384    }