/* * LoginFrame.java * * Created on Jun 25, 2009, 11:19:43 AM */ package com.eas.client.login; import com.eas.client.settings.ConnectionSettings; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.Map; import java.util.ResourceBundle; import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JOptionPane; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; /** * * @author pk, mg refactoring */ public class ConnectionsSelector extends javax.swing.JDialog { public static final String SETTINGS_NODE = "/com/eas/client"; public static final String CONNECTIONS_SETTINGS_NODE = SETTINGS_NODE + "/connections"; public static final String DEFAULT_CONNECTION_INDEX_SETTING = "defaultConnectionIndex"; public static final String CONNECTION_TITLE_SETTING = "title"; public static final String CONNECTION_URL_SETTING = "url"; private static ConnectionSettings[] settings; private static ConnectionSettings defaultSettings; /** * A return status code - returned if Cancel button has been pressed */ public static final int RET_CANCEL = 0; /** * A return status code - returned if OK button has been pressed */ public static final ResourceBundle bundle = ResourceBundle.getBundle("com/eas/client/login/Bundle"); public static final int RET_OK = 1; private int returnStatus = RET_CANCEL; private final Action connectAction = new ConnectAction(); private final Action cancelAction = new CancelAction(); private final Action newConnectionAction = new NewConnectionAction(); private final Action modifyConnectionAction = new ModifyConnectionAction(); private final DeleteConnectionAction deleteConnectionAction = new DeleteConnectionAction(); private final ConnectionsSelectionListener connectionsSelectionListener = new ConnectionsSelectionListener(); private final ConnectionsListModel connectionsListModel; protected String defaultUrl; /** * User's login and connection selection dialog. * * @param aDefaultUrl preset URL * @throws Exception if login failed */ public ConnectionsSelector(String aDefaultUrl) throws Exception { super((java.awt.Frame) null, true); defaultUrl = aDefaultUrl; connectionsListModel = new ConnectionsListModel(); initComponents(); getRootPane().setDefaultButton(btnOk); lstConnections.setCellRenderer(connectionsListModel.getCellRenderer()); lstConnections.clearSelection(); lstConnections.addListSelectionListener(connectionsSelectionListener); if (defaultSettings != null) { lstConnections.setSelectedValue(defaultSettings, true); } lstConnections.requestFocus(); } private void doClose(int retStatus) { defaultUrl = null; returnStatus = retStatus; setVisible(false); dispose(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { pnlConnectionInfo = new javax.swing.JPanel(); scrollConnections = new javax.swing.JScrollPane(); lstConnections = new javax.swing.JList(); btnNewConnection = new javax.swing.JButton(); btnDeleteConnection = new javax.swing.JButton(); btnModifyConnection = new javax.swing.JButton(); pnlBottom = new javax.swing.JPanel(); btnOk = new javax.swing.JButton(); btnCancel = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle(bundle.getString("LoginDialog.title")); // NOI18N setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); setIconImage(new javax.swing.ImageIcon(getClass().getResource("/com/eas/client/login/socket.png")).getImage()); setLocationByPlatform(true); setName("loginFrame"); // NOI18N addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { formKeyTyped(evt); } }); lstConnections.setModel(connectionsListModel); lstConnections.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { lstConnectionsMouseClicked(evt); } }); scrollConnections.setViewportView(lstConnections); btnNewConnection.setAction(newConnectionAction); btnNewConnection.setText(bundle.getString("LoginDialog.btnNewConnection.text")); // NOI18N btnNewConnection.setMargin(new java.awt.Insets(2, 2, 2, 2)); btnDeleteConnection.setAction(deleteConnectionAction); btnDeleteConnection.setText(bundle.getString("LoginDialog.btnDeleteConnection.text")); // NOI18N btnDeleteConnection.setMargin(new java.awt.Insets(2, 2, 2, 2)); btnModifyConnection.setAction(modifyConnectionAction); btnModifyConnection.setText(bundle.getString("LoginDialog.btnModifyConnection.text")); // NOI18N btnModifyConnection.setMargin(new java.awt.Insets(2, 2, 2, 2)); javax.swing.GroupLayout pnlConnectionInfoLayout = new javax.swing.GroupLayout(pnlConnectionInfo); pnlConnectionInfo.setLayout(pnlConnectionInfoLayout); pnlConnectionInfoLayout.setHorizontalGroup( pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlConnectionInfoLayout.createSequentialGroup() .addContainerGap() .addComponent(scrollConnections, javax.swing.GroupLayout.DEFAULT_SIZE, 307, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(btnNewConnection, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnDeleteConnection, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(btnModifyConnection, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 86, Short.MAX_VALUE)) .addContainerGap()) ); pnlConnectionInfoLayout.setVerticalGroup( pnlConnectionInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnlConnectionInfoLayout.createSequentialGroup() .addGap(16, 16, 16) .addComponent(btnNewConnection) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnModifyConnection) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnDeleteConnection) .addContainerGap(140, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlConnectionInfoLayout.createSequentialGroup() .addContainerGap() .addComponent(scrollConnections)) ); getContentPane().add(pnlConnectionInfo, java.awt.BorderLayout.CENTER); btnOk.setAction(connectAction); btnOk.setText(bundle.getString("Dialog.OKButton.text")); // NOI18N btnCancel.setAction(cancelAction); btnCancel.setText(bundle.getString("Dialog.CancelButton.text")); // NOI18N javax.swing.GroupLayout pnlBottomLayout = new javax.swing.GroupLayout(pnlBottom); pnlBottom.setLayout(pnlBottomLayout); pnlBottomLayout.setHorizontalGroup( pnlBottomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlBottomLayout.createSequentialGroup() .addContainerGap(240, Short.MAX_VALUE) .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); pnlBottomLayout.setVerticalGroup( pnlBottomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pnlBottomLayout.createSequentialGroup() .addContainerGap() .addGroup(pnlBottomLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnCancel) .addComponent(btnOk)) .addContainerGap()) ); getContentPane().add(pnlBottom, java.awt.BorderLayout.SOUTH); pack(); }// </editor-fold>//GEN-END:initComponents private void formKeyTyped(java.awt.event.KeyEvent evt)//GEN-FIRST:event_formKeyTyped {//GEN-HEADEREND:event_formKeyTyped if (evt.getKeyCode() == KeyEvent.VK_ENTER) { connectAction.actionPerformed(new ActionEvent(this, 0, null)); } else if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) { cancelAction.actionPerformed(new ActionEvent(this, 0, null)); } }//GEN-LAST:event_formKeyTyped private void lstConnectionsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lstConnectionsMouseClicked if (evt.getClickCount() > 1) { connectAction.actionPerformed(null); } }//GEN-LAST:event_lstConnectionsMouseClicked // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnCancel; private javax.swing.JButton btnDeleteConnection; private javax.swing.JButton btnModifyConnection; private javax.swing.JButton btnNewConnection; private javax.swing.JButton btnOk; private javax.swing.JList lstConnections; private javax.swing.JPanel pnlBottom; private javax.swing.JPanel pnlConnectionInfo; private javax.swing.JScrollPane scrollConnections; // End of variables declaration//GEN-END:variables /** * @return the returnStatus */ public int getReturnStatus() { return returnStatus; } public void updateConnectionsPreferences() throws Exception { Preferences connectionsPref = Preferences.userRoot().node(CONNECTIONS_SETTINGS_NODE); connectionsPref.removeNode(); connectionsPref = Preferences.userRoot().node(CONNECTIONS_SETTINGS_NODE); int defaultSettingsIndex = -1; for (int i = 0; i < connectionsListModel.getSize(); i++) { ConnectionSettings currentSettings = (ConnectionSettings) connectionsListModel.getElementAt(i); if (currentSettings == getDefaultSettings()) { defaultSettingsIndex = i; } if (currentSettings.isEditable()) { String strIndex = String.valueOf(i); connectionsPref.node(strIndex).put(CONNECTION_TITLE_SETTING, currentSettings.getName() != null ? currentSettings.getName() : ""); connectionsPref.node(strIndex).put(CONNECTION_URL_SETTING, currentSettings.getUrl() != null ? currentSettings.getUrl() : ""); } } if (defaultSettingsIndex != -1) { Preferences.userRoot().node(SETTINGS_NODE).putInt(DEFAULT_CONNECTION_INDEX_SETTING, defaultSettingsIndex); } } public int getSelectedConnectionIndex() { return lstConnections.getSelectedIndex(); } public void applyDefaults() { if (getDefaultSettings() != null) { lstConnections.setSelectedValue(getDefaultSettings(), true); } } private class ConnectAction extends AbstractAction { public ConnectAction() { super(); setEnabled(false); } @Override public void actionPerformed(ActionEvent evt) { try { ConnectionSettings settings = (ConnectionSettings) lstConnections.getSelectedValue(); if (settings != null) { setDefaultSettings(settings); updateConnectionsPreferences(); doClose(RET_OK); } } catch (Exception ex) { Logger.getLogger(ConnectionsSelector.class.getName()).log(Level.SEVERE, "{0} ({1})", new Object[]{bundle.getString("ConnectionsSelector.CannotConnectMessage"), ex.getLocalizedMessage()}); JOptionPane.showMessageDialog(ConnectionsSelector.this, bundle.getString("ConnectionsSelector.CannotConnectMessage") + String.format(" (%s)", ex.getLocalizedMessage()), bundle.getString("LoginDialog.title"), JOptionPane.ERROR_MESSAGE); } } } private class CancelAction extends AbstractAction { @Override public void actionPerformed(ActionEvent e) { try { doClose(RET_CANCEL); } catch (Exception ex) { Logger.getLogger(ConnectionsSelector.class.getName()).log(Level.SEVERE, "{0} ({1})", new Object[]{bundle.getString("ConnectionsSelector.CannotConnectMessage"), ex.getLocalizedMessage()}); JOptionPane.showMessageDialog(ConnectionsSelector.this, bundle.getString("ConnectionsSelector.CannotConnectMessage") + String.format(" (%s)", ex.getLocalizedMessage()), bundle.getString("LoginDialog.title"), JOptionPane.ERROR_MESSAGE); } } } private class NewConnectionAction extends AbstractAction { @Override public void actionPerformed(ActionEvent e) { ConnectionSettingsEditor dlg = new ConnectionSettingsEditor(); dlg.setUrl("platypus://<host>:<port>"); dlg.setVisible(true); if (dlg.getReturnStatus() == ConnectionSettingsEditor.RET_OK) { try { int saveIndex = lstConnections.getSelectedIndex(); if (saveIndex < 0) { saveIndex = connectionsListModel.getSize(); } String url = dlg.getUrl(); String name = dlg.getConnectionName(); ConnectionSettings settings = new ConnectionSettings(); settings.setUrl(url); if (name != null && !name.isEmpty()) { settings.setName(name); } connectionsListModel.putElementAt(saveIndex, settings); lstConnections.setSelectedIndex(saveIndex); updateConnectionsPreferences(); lstConnections.requestFocus(); } catch (Exception ex) { Logger.getLogger(ConnectionsSelector.class.getName()).log(Level.SEVERE, null, ex); } } } } private class ModifyConnectionAction extends AbstractAction { public ModifyConnectionAction() { super(); setEnabled(false); } @Override public void actionPerformed(ActionEvent e) { int selectedIndex = lstConnections.getSelectedIndex(); if (selectedIndex >= 0) { ConnectionSettings settings = (ConnectionSettings) connectionsListModel.getElementAt(selectedIndex); ConnectionSettingsEditor dlg = new ConnectionSettingsEditor(); dlg.setUrl(settings.getUrl()); dlg.setConnectionName(settings.getName()); dlg.setVisible(true); int retVal = dlg.getReturnStatus(); if (retVal == ConnectionSettingsEditor.RET_OK) { try { settings.setUrl(dlg.getUrl()); settings.setName(dlg.getConnectionName()); connectionsListModel.fireContentsChanged(selectedIndex); updateConnectionsPreferences(); lstConnections.requestFocus(); } catch (Exception ex) { Logger.getLogger(ConnectionsSelector.class.getName()).log(Level.SEVERE, null, ex); } } } } } private class DeleteConnectionAction extends AbstractAction { public DeleteConnectionAction() { super(); setEnabled(false); } @Override public void actionPerformed(ActionEvent e) { int selectedIndex = lstConnections.getSelectedIndex(); assert selectedIndex >= 0; //we won't be enabled otherwise ConnectionSettings settings = (ConnectionSettings) connectionsListModel.getElementAt(selectedIndex); int choice = JOptionPane.showConfirmDialog(ConnectionsSelector.this, bundle.getString("LoginDialog.ConnectionDeletionConfirmationMessage") + settings.getUrl(), bundle.getString("LoginDialog.ConnectionDeletionConfirmationTitle"), JOptionPane.YES_NO_OPTION); if (choice == JOptionPane.YES_OPTION) { try { connectionsListModel.removeElementAt(selectedIndex); updateConnectionsPreferences(); lstConnections.setSelectedIndex(selectedIndex); lstConnections.requestFocus(); } catch (Exception ex) { Logger.getLogger(ConnectionsSelector.class.getName()).log(Level.SEVERE, null, ex); } } } } private class ConnectionsSelectionListener implements ListSelectionListener { @Override public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { ConnectionSettings selectedSettings = (ConnectionSettings) lstConnections.getSelectedValue(); boolean modificationsEnabled = selectedSettings != null && selectedSettings.isEditable(); modifyConnectionAction.setEnabled(modificationsEnabled); deleteConnectionAction.setEnabled(modificationsEnabled); connectAction.setEnabled(modificationsEnabled); lstConnections.requestFocus(); } } } public static ConnectionSettings[] getSettings() throws Exception { if (settings == null) { try { readSettings(); } catch (BackingStoreException ex) { Logger.getLogger(ConnectionsSelector.class.getName()).log(Level.SEVERE, null, ex); settings = null; } } return settings; } public static void setDefaultSettings(ConnectionSettings settings) { defaultSettings = settings; } public static ConnectionSettings getDefaultSettings() { return defaultSettings; } public static void reset() { settings = null; defaultSettings = null; } public static void readSettings() throws Exception { settings = null; defaultSettings = null; int defaultConnectionIndex = Preferences.userRoot().node(SETTINGS_NODE).getInt(DEFAULT_CONNECTION_INDEX_SETTING, 0); if (defaultConnectionIndex < 0) { defaultConnectionIndex = 0; } Map<Integer, ConnectionSettings> settingsMap = new TreeMap<>(); Preferences userConnectionsPrefs = Preferences.userRoot().node(CONNECTIONS_SETTINGS_NODE); settingsNodeToSettings(userConnectionsPrefs, settingsMap, true); if (settingsMap.isEmpty()) { Preferences defaultConnectionsPrefs = Preferences.systemRoot().node(CONNECTIONS_SETTINGS_NODE); try { settingsNodeToSettings(defaultConnectionsPrefs, settingsMap, false); } catch (Exception ex) { Logger.getLogger(ConnectionsSelector.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); } } settings = new ConnectionSettings[settingsMap.size()]; int i = 0; for (Integer connNodeName : settingsMap.keySet()) { settings[i++] = settingsMap.get(connNodeName); } if (settings.length > 0) { // check default index if (defaultConnectionIndex >= settings.length) { defaultConnectionIndex = settings.length - 1; } if (defaultConnectionIndex < 0) { defaultConnectionIndex = 0; } defaultSettings = settings[defaultConnectionIndex]; } else { defaultSettings = null; } } private static void settingsNodeToSettings(Preferences connectionsPrefs, Map<Integer, ConnectionSettings> settingsMap, boolean aEditable) throws Exception { String[] settingsNodesNames = connectionsPrefs.childrenNames(); for (String settingsNodesName : settingsNodesNames) { Preferences connectionPrefs = connectionsPrefs.node(settingsNodesName); String connUrl = connectionPrefs.get(CONNECTION_URL_SETTING, "jdbc"); connUrl = connUrl.replaceAll("[\\s\\r\\n\\t]", ""); ConnectionSettings connectionsettings = new ConnectionSettings(); settingsMap.put(Integer.valueOf(settingsNodesName), connectionsettings); connectionsettings.setUrl(connUrl); connectionsettings.setName(connectionPrefs.get(CONNECTION_TITLE_SETTING, "")); connectionsettings.setEditable(aEditable); } } /** * Reads default settings from backing store. * * @return EasSettings instance as part of settings array, that have been * read previously. * @throws java.lang.Exception */ public static ConnectionSettings readDefaultSettings() throws Exception { int defaultConnectionIndex = Preferences.userRoot().node(SETTINGS_NODE).getInt(DEFAULT_CONNECTION_INDEX_SETTING, 0); if (defaultConnectionIndex < 0) { defaultConnectionIndex = 0; } if (settings == null) { readSettings(); } return settings[defaultConnectionIndex]; } }