package games.strategy.engine.lobby.client.login; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Window; import java.awt.event.KeyEvent; import java.util.logging.Logger; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; import javax.swing.Action; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import games.strategy.engine.lobby.server.userDB.DBUserController; import games.strategy.ui.SwingAction; import games.strategy.ui.Util; public class LoginPanel extends JPanel { private static final long serialVersionUID = -1115199161238394717L; private static final Logger s_logger = Logger.getLogger(LoginPanel.class.getName()); public static enum ReturnValue { CANCEL, LOGON, CREATE_ACCOUNT } public static final String LAST_LOGIN_NAME_PREF = "LAST_LOGIN_NAME_PREF"; public static final String ANONYMOUS_LOGIN_PREF = "ANONYMOUS_LOGIN_PREF"; private JDialog m_dialog; private JPasswordField m_password; private JTextField m_userName; private JCheckBox m_anonymous; private JButton m_createAccount; private ReturnValue m_returnValue; private JButton m_logon; private JButton m_cancel; public LoginPanel() { createComponents(); layoutComponents(); setupListeners(); readDefaults(); setWidgetActivation(); } private void readDefaults() { final Preferences prefs = Preferences.userNodeForPackage(this.getClass()); final String name = prefs.get(LAST_LOGIN_NAME_PREF, System.getProperty("user.name")); final boolean anonymous = prefs.getBoolean(ANONYMOUS_LOGIN_PREF, true); m_anonymous.setSelected(anonymous); m_userName.setText(name); SwingUtilities.invokeLater(() -> { if (!m_anonymous.isSelected()) { m_password.requestFocusInWindow(); } else { m_userName.requestFocusInWindow(); } }); } private void createComponents() { m_password = new JPasswordField(); m_userName = new JTextField(); m_anonymous = new JCheckBox("Login Anonymously?"); m_createAccount = new JButton("Create Account..."); m_logon = new JButton("Login"); m_cancel = new JButton("Cancel"); } private void layoutComponents() { final JLabel label = new JLabel(new ImageIcon(Util.getBanner("Login"))); setLayout(new BorderLayout()); add(label, BorderLayout.NORTH); final JPanel main = new JPanel(); add(main, BorderLayout.CENTER); main.setLayout(new GridBagLayout()); main.add(new JLabel("Username:"), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(10, 20, 0, 0), 0, 0)); main.add(m_userName, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.BOTH, new Insets(10, 5, 0, 40), 0, 0)); main.add(new JLabel("Password:"), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 20, 0, 0), 0, 0)); main.add(m_password, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.BOTH, new Insets(5, 5, 0, 40), 0, 0)); main.add(m_anonymous, new GridBagConstraints(0, 2, 2, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 20, 0, 0), 0, 0)); main.add(m_createAccount, new GridBagConstraints(0, 3, 2, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 20, 0, 0), 0, 0)); final JPanel buttons = new JPanel(); buttons.setLayout(new FlowLayout(FlowLayout.RIGHT)); buttons.add(m_logon); buttons.add(m_cancel); add(buttons, BorderLayout.SOUTH); } private void setupListeners() { m_logon.addActionListener(e -> logonPressed()); m_createAccount.addActionListener(e -> { m_returnValue = ReturnValue.CREATE_ACCOUNT; m_dialog.setVisible(false); }); m_cancel.addActionListener(e -> m_dialog.setVisible(false)); m_anonymous.addActionListener(e -> setWidgetActivation()); // close when hitting the escape key final Action enterAction = SwingAction.of(e -> logonPressed()); final String key = "logon.through.enter.key"; getActionMap().put(key, enterAction); getActionMap().put(key, enterAction); getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), key); } private void logonPressed() { final String userName = m_userName.getText(); final boolean anonymous = m_anonymous.isSelected(); if (DBUserController.validateUserName(userName) != null) { JOptionPane.showMessageDialog(this, DBUserController.validateUserName(userName), "Invalid Username", JOptionPane.ERROR_MESSAGE); return; } else if (m_password.getPassword().length == 0 && !anonymous) { JOptionPane.showMessageDialog(LoginPanel.this, "You must enter a password", "No Password", JOptionPane.ERROR_MESSAGE); return; } else if (m_password.getPassword().length < 3 && !anonymous) { JOptionPane.showMessageDialog(LoginPanel.this, "Passwords must be at least three characters long", "Invalid password", JOptionPane.ERROR_MESSAGE); return; } m_returnValue = ReturnValue.LOGON; m_dialog.setVisible(false); } public static void storePrefs(final String userName, final boolean anonymous) { final Preferences prefs = Preferences.userNodeForPackage(LoginPanel.class); prefs.put(LAST_LOGIN_NAME_PREF, userName); prefs.putBoolean(ANONYMOUS_LOGIN_PREF, anonymous); try { prefs.flush(); } catch (final BackingStoreException e) { // not a big deal s_logger.warning(e.getMessage()); } } private void setWidgetActivation() { if (!m_anonymous.isSelected()) { m_password.setEnabled(true); m_password.setBackground(m_userName.getBackground()); } else { m_password.setEnabled(false); m_password.setBackground(this.getBackground()); } } public boolean isAnonymous() { return m_anonymous.isSelected(); } public String getUserName() { return m_userName.getText(); } public String getPassword() { return new String(m_password.getPassword()); } public ReturnValue show(final Window parent) { m_dialog = new JDialog(JOptionPane.getFrameForComponent(parent), "Login", true); m_dialog.getContentPane().add(this); m_dialog.pack(); m_dialog.setLocationRelativeTo(parent); m_dialog.setVisible(true); m_dialog.dispose(); m_dialog = null; if (m_returnValue == null) { return ReturnValue.CANCEL; } return m_returnValue; } }