package jalview.gui; import jalview.bin.Cache; import jalview.util.MessageManager; import jalview.ws.WSDiscovererI; import jalview.ws.slivkaws.SlivkaWSDiscoverer; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.NoSuchElementException; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; @SuppressWarnings("serial") public class SlivkaPreferences extends JPanel { { setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); setPreferredSize(new Dimension(500, 450)); } WSDiscovererI discoverer; private final ArrayList urls = new ArrayList<>(); private final ArrayList statuses = new ArrayList<>(); private final AbstractTableModel urlTableModel = new AbstractTableModel() { final String[] columnNames = { "Service URL", "Status" }; @Override public String getColumnName(int col) { return columnNames[col]; } @Override public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { case 0: return urls.get(rowIndex); case 1: return statuses.get(rowIndex); default: throw new NoSuchElementException(); } } @Override public int getRowCount() { return urls.size(); } @Override public int getColumnCount() { return 2; } }; private class WSStatusCellRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setHorizontalAlignment(CENTER); super.getTableCellRendererComponent(table, "\u25CF", isSelected, hasFocus, row, column); switch ((Integer) value) { case WSDiscovererI.STATUS_NO_SERVICES: setForeground(Color.ORANGE); break; case WSDiscovererI.STATUS_OK: setForeground(Color.GREEN); break; case WSDiscovererI.STATUS_INVALID: setForeground(Color.RED); break; case WSDiscovererI.STATUS_UNKNOWN: default: setForeground(Color.LIGHT_GRAY); } return this; } } private JTable urlListTable = new JTable(urlTableModel); { urlListTable.getColumnModel().getColumn(1).setMaxWidth(60); urlListTable.getColumnModel().getColumn(1) .setCellRenderer(new WSStatusCellRenderer()); } // URL control panel buttons JButton newWsUrl = new JButton( MessageManager.getString("label.new_service_url")); JButton editWsUrl = new JButton( MessageManager.getString("label.edit_service_url")); JButton deleteWsUrl = new JButton( MessageManager.getString("label.delete_service_url")); JButton moveUrlUp = new JButton( MessageManager.getString("action.move_up")); JButton moveUrlDown = new JButton( MessageManager.getString("action.move_down")); private String showEditUrlDialog(String oldUrl) { String input = (String) JvOptionPane .showInternalInputDialog( this, MessageManager.getString("label.url:"), UIManager.getString("OptionPane.inputDialogTitle", MessageManager.getLocale()), JOptionPane.QUESTION_MESSAGE, null, null, oldUrl); if (input == null) { return null; } try { new URL(input); } catch (MalformedURLException ex) { JvOptionPane.showInternalMessageDialog(this, MessageManager.getString("label.invalid_url"), UIManager.getString("OptionPane.messageDialogTitle", MessageManager.getLocale()), JOptionPane.WARNING_MESSAGE); return null; } return input; } // Button Action Listeners private ActionListener newUrlAction = (ActionEvent e) -> { final String input = showEditUrlDialog(""); if (input != null) { urls.add(input); statuses.add(discoverer.getServerStatusFor(input)); urlTableModel.fireTableRowsInserted(urls.size(), urls.size()); discoverer.setServiceUrls(urls); } }; private ActionListener editUrlAction = (ActionEvent e) -> { final int i = urlListTable.getSelectedRow(); if (i >= 0) { final String input = showEditUrlDialog(urls.get(i)); if (input != null) { urls.set(i, input); statuses.set(i, discoverer.getServerStatusFor(input)); urlTableModel.fireTableRowsUpdated(i, i); discoverer.setServiceUrls(urls); } } }; private ActionListener deleteUrlAction = (ActionEvent e) -> { final int i = urlListTable.getSelectedRow(); if (i >= 0) { urls.remove(i); statuses.remove(i); urlTableModel.fireTableRowsDeleted(i, i); discoverer.setServiceUrls(urls); } }; private ActionListener moveUrlUpAction = (ActionEvent e) -> { final int i = urlListTable.getSelectedRow(); if (i > 0) { moveTableRow(i, i - 1); discoverer.setServiceUrls(urls); } }; private ActionListener moveUrlDownAction = (ActionEvent e) -> { final int i = urlListTable.getSelectedRow(); if (i >= 0 && i < urls.size() - 1) { moveTableRow(i, i + 1); discoverer.setServiceUrls(urls); } }; private MouseListener tableClickListener = new MouseAdapter() { final ActionEvent actionEvent = new ActionEvent(urlListTable, ActionEvent.ACTION_PERFORMED, "edit"); @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() > 1) { editUrlAction.actionPerformed(actionEvent); } } }; // Setting up URL list Pane { Font font = new Font("Verdana", Font.PLAIN, 10); JPanel urlPaneContainer = new JPanel(new BorderLayout(5, 5)); urlPaneContainer.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Slivka Web Services"), BorderFactory.createEmptyBorder(10, 5, 5, 5))); newWsUrl.setFont(font); editWsUrl.setFont(font); deleteWsUrl.setFont(font); moveUrlUp.setFont(font); moveUrlDown.setFont(font); JPanel editContainer = new JPanel(); editContainer.add(newWsUrl); editContainer.add(editWsUrl); editContainer.add(deleteWsUrl); urlPaneContainer.add(editContainer, BorderLayout.PAGE_END); JPanel moveContainer = new JPanel(); moveContainer .setLayout(new BoxLayout(moveContainer, BoxLayout.PAGE_AXIS)); moveContainer.add(moveUrlUp); moveContainer.add(Box.createRigidArea(new Dimension(0, 5))); moveContainer.add(moveUrlDown); urlPaneContainer.add(moveContainer, BorderLayout.LINE_START); urlPaneContainer.add(new JScrollPane(urlListTable), BorderLayout.CENTER); this.add(urlPaneContainer); // Connecting action listeners urlListTable.addMouseListener(tableClickListener); newWsUrl.addActionListener(newUrlAction); editWsUrl.addActionListener(editUrlAction); deleteWsUrl.addActionListener(deleteUrlAction); moveUrlUp.addActionListener(moveUrlUpAction); moveUrlDown.addActionListener(moveUrlDownAction); } private void moveTableRow(int fromIndex, int toIndex) { String url = urls.get(fromIndex); int status = statuses.get(fromIndex); urls.set(fromIndex, urls.get(toIndex)); statuses.set(fromIndex, statuses.get(toIndex)); urls.set(toIndex, url); statuses.set(toIndex, status); if (urlListTable.getSelectedRow() == fromIndex) { urlListTable.setRowSelectionInterval(toIndex, toIndex); } int firstRow = Math.min(toIndex, fromIndex); int lastRow = Math.max(fromIndex, toIndex); urlTableModel.fireTableRowsUpdated(firstRow, lastRow); } // Discoverer reloading buttons JButton refreshServices = new JButton( MessageManager.getString("action.refresh_services")); JButton resetServices = new JButton( MessageManager.getString("action.reset_services")); JProgressBar progressBar = new JProgressBar(); // Discoverer buttons action listeners private ActionListener refreshServicesAction = (ActionEvent e) -> { progressBar.setVisible(true); new Thread(() -> { Cache.log.info("Requesting service reload"); var task = discoverer.startDiscoverer(); try { task.get(); Cache.log.info("Reloading done"); } catch (Exception exc) { Cache.log.error("Reloading failed", exc); } finally { SwingUtilities.invokeLater(() -> progressBar.setVisible(false)); } }).start(); }; private ActionListener resetServicesAction = (ActionEvent e) -> { discoverer.setServiceUrls(null); urls.clear(); statuses.clear(); urls.addAll(discoverer.getServiceUrls()); for (String url : urls) { statuses.add(discoverer.getServerStatusFor(url)); } urlTableModel.fireTableDataChanged(); }; { Font font = new Font("Verdana", Font.PLAIN, 11); refreshServices.setFont(font); resetServices.setFont(font); JPanel container = new JPanel(); container.add(refreshServices); container.add(resetServices); this.add(container); // Connecting action listeners refreshServices.addActionListener(refreshServicesAction); resetServices.addActionListener(resetServicesAction); } { progressBar.setVisible(false); progressBar.setIndeterminate(true); add(progressBar); } SlivkaPreferences() { // Initial URLs loading discoverer = SlivkaWSDiscoverer.getInstance(); urls.addAll(discoverer.getServiceUrls()); for (String url : urls) { statuses.add(discoverer.getServerStatusFor(url)); } } }