/* * Copyright (C) 2015 * * * * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package edu.wright.cs.fa15.ceg3120.concon.common; import edu.wright.cs.fa15.ceg3120.concon.common.data.RequestType; import edu.wright.cs.fa15.ceg3120.concon.common.data.UserAccount; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.Serializable; import java.util.Arrays; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.SpringLayout; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; /** * This is the main launch point for the UIs. It is responsible for creating * the unified login window, interfacing with the net-stack, and launching the * UI corresponding the account type of the user once verified at the database * level. * * @author Paul Quackenbush * */ public class LoginPopUp implements Serializable{ private static final long serialVersionUID = 1L; private UserAccount user; private static ArrayBlockingQueue<UserAccount> incoming = new ArrayBlockingQueue<>(3); private JButton loginButton; private JButton btnCreateAccount; private transient SpringLayout currentLayout; private JTextField uuidField; private JPasswordField passwordField; private Resources imageResources; private static final String ICON_IMG = "icon.png"; /** * Creates a new instance of <code>LogininPopUp</code>. */ public LoginPopUp() { user = null; loginButton = new JButton(); btnCreateAccount = new JButton(); uuidField = new JTextField(); passwordField = new JPasswordField(); imageResources = new Resources(); } /** * temp. */ private void buildGui() { final JFrame loginFrame = new StringFrame(this); loginFrame.setSize(500, 300); loginFrame.setLocationRelativeTo(null); uuidField.requestFocus(); loginFrame.setIconImage(imageResources.getImage(ICON_IMG ).getImage()); loginFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); loginFrame.addWindowListener(new MyWindowAdapter()); loginFrame.setVisible(true); // if new account link/button clicked btnCreateAccount.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ev) { loginButton.setEnabled(false); btnCreateAccount.setEnabled(false); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { launchNewAccountGui(); loginButton.setEnabled(true); btnCreateAccount.setEnabled(true); } }); } }); /* * need action listener for login button that will block until we receive a response from * Networking so user can be set properly. Preferably a blocking mechanism that will timeout * when we want it to. */ loginButton.addActionListener(new LoginListener(loginFrame)); uuidField.addKeyListener(new LoginListener(loginFrame)); passwordField.addKeyListener(new LoginListener(loginFrame)); }// end buildGui /** * Use this method to pass data to the UserAccount queue. * <p> * More description to come... * </p> * * @param user (UserAccount sub-class) * * @return true if the item was successfully inserted * * @throws InterruptedException * thrown if interrupted... */ public static boolean addUserToQueue(UserAccount user) throws InterruptedException { System.out.println("added user to queue."); return incoming.offer(user, 1, TimeUnit.SECONDS); } /** * Launches the Create New User GUI and renders the login window unresponsive until * CreateNewAccountGUI.buildGUI returns. At least it would in theory... */ private void launchNewAccountGui() { (new CreateNewAccount()).buildGui(); // TODO do more stuffs? maybe/ maybe not }// end launchNewAccountGUI /** * Creates the text field panel for the UI. * * @return Fully constructed text field panel */ public FieldPanel createFieldPanel() { return new FieldPanel(); } /** * Makes findBugs quiet... */ public void readObject() { // XXX currentLayout = new SpringLayout(); } /** * Entry point for the main unit. * * @param args Command line arguments */ public static void main(String[] args) { // Schedules the GUI construction on the EDT SwingUtilities.invokeLater(new Runnable() { @Override public void run() { (new LoginPopUp()).buildGui(); } }); } /** * Listener for the login functionality. * * @author Quack * */ private class LoginListener extends KeyAdapter implements ActionListener{ JFrame loginFrame; /** * Creates a new instance of <code>LoginListener</code>. * @param frame JFrame */ public LoginListener(JFrame frame) { loginFrame = frame; } @Override public void keyPressed(KeyEvent ev) { int keyPress = ev.getKeyCode(); if (keyPress == KeyEvent.VK_ENTER) { actionPerformed(null); } } @Override public void actionPerformed(ActionEvent ev) { if (verifyFields()) { // user has been set // blah blah... shipped user to network, reset user to null loginButton.setEnabled(false); btnCreateAccount.setEnabled(false); /* Add invocation of ArrayBlockingQueue.poll(long, TimeUnit) * to the end of the EDT execution queue to ensure a "happens * after" relationship with the JButton.setEnabled(boolean) * calls. */ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { //this needs to come out (new CreateNewAccount()).buildGui(); // remove above user = incoming.poll(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); JOptionPane.showConfirmDialog(null, "The program experienced an internal error." + "\nPlease try again...", "Error", JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE); } finally { System.out.println(user + " test"); if (user != null) { /* * Schedule the loginFrame to be disposed on the EDT before * launching the new GUI. */ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { loginFrame.dispose(); } }); //user = new ServerAdminAccount(); if (user.getClass().equals(UserAccount.class)) { JOptionPane.showMessageDialog(null, "Database Response:\n " + (user.getdbResponse() == null ? "ERROR" : user.getdbResponse()), "Error", JOptionPane.ERROR_MESSAGE); loginButton.setEnabled(true); btnCreateAccount.setEnabled(true); } else { user.launchGui(); } } else { JOptionPane.showMessageDialog(null, "Your request timed out." + "\nPlease try again...", "Error", JOptionPane.ERROR_MESSAGE); loginButton.setEnabled(true); btnCreateAccount.setEnabled(true); } } //end try/catch/finally } //end run }); } }// end actionPerformed /** * Verifies that the user has supplied input. * @return true iff all fields have been filled */ public boolean verifyFields() { String uuid = uuidField.getText(); if (uuid.length() > 0) { if (passwordField.getPassword().length > 0) { // XXX encrypt pswd before creating new UserAccount user = new UserAccount(uuid, null, passwordField.getPassword(), RequestType.LOOK_UP); } else { JOptionPane.showMessageDialog(null, "The password field is blank." + "\nPlease try agian...", "Error", JOptionPane.ERROR_MESSAGE); return false; } } else { JOptionPane.showMessageDialog(null, "The Username field is blank.\nPlease try agian...", "Error", JOptionPane.ERROR_MESSAGE); return false; } return true; }//end verifyFields }//end LoginListener /** * temp. * @author Quack * */ private class MyWindowAdapter extends WindowAdapter{ @Override public void windowClosing(WindowEvent ev) { // release any network/file resources passwordField.setText(""); if (user != null) { if (user.getPswd().length > 0) { char[] overwrite = new char[user.getPswd().length]; for (int i = 0; i < overwrite.length; ++i) { overwrite[i] = '\0'; } user.setPswd(overwrite); System.out.println("overwrite:" + Arrays.toString(user.getPswd())); } } // end if(user != null) System.exit(0); } }//end MyWindowAdapter /*############################################################################*/ /*############################################################################*/ /*############################################################################*/ /** * TODO Explain. * * @author Corey Miller * */ public static class StringFrame extends JFrame { private static final long serialVersionUID = 1L; private FieldPanel currentPanel; private LoginPopUp popup; /** * Creates a new instance of <code>StringFrame</code>. */ public StringFrame(LoginPopUp popUp) { super("Login"); this.popup = popUp; currentPanel = popup.createFieldPanel(); setupFrame(); } /** * Retrieve the content pane from {@code currentPanel}. */ private void setupFrame() { this.setContentPane(currentPanel); } } /** * JPanel containing the login text fields. * * @author Corey Miller */ public class FieldPanel extends JPanel { private static final long serialVersionUID = 1L; ImageIcon img; /** * Creates a new instance of <code>FieldPanel</code>. */ public FieldPanel() { setBackground(Color.ORANGE); loginButton = new JButton("Login"); currentLayout = new SpringLayout(); try { img = imageResources.getImage("ceg3120_logos.png"); } catch (Exception e) { e.printStackTrace(); /*handled in paint()*/ } setupPanel(); } @Override public void paint(Graphics graphics) { super.paint(graphics); if (img != null) { graphics.drawImage(img.getImage(), this.getWidth() - 235, this.getHeight() - 290, 300, 300, this ); } else { graphics.drawString("No image", 400, 200); } } //end paint /** * Generate the panel. */ private void setupPanel() { this.setLayout(currentLayout); this.add(loginButton); btnCreateAccount = new JButton("Create Account"); currentLayout.putConstraint(SpringLayout.SOUTH, btnCreateAccount, -10, SpringLayout.SOUTH, this); currentLayout.putConstraint(SpringLayout.EAST, btnCreateAccount, -10, SpringLayout.EAST, this); add(btnCreateAccount); JLabel lblHomeOwnerLogin = new JLabel("Contractor App Login "); currentLayout.putConstraint(SpringLayout.NORTH, lblHomeOwnerLogin, 32, SpringLayout.NORTH, this); currentLayout.putConstraint(SpringLayout.WEST, lblHomeOwnerLogin, 98, SpringLayout.WEST, this); currentLayout.putConstraint(SpringLayout.EAST, lblHomeOwnerLogin, -144, SpringLayout.EAST, this); lblHomeOwnerLogin.setForeground(new Color(0, 0, 0)); lblHomeOwnerLogin.setFont(new Font("Times New Roman", Font.BOLD, 19)); add(lblHomeOwnerLogin); uuidField = new JTextField(); currentLayout.putConstraint(SpringLayout.SOUTH, lblHomeOwnerLogin, -34, SpringLayout.NORTH, uuidField); currentLayout.putConstraint(SpringLayout.EAST, loginButton, 0, SpringLayout.EAST, uuidField); currentLayout.putConstraint(SpringLayout.WEST, uuidField, 125, SpringLayout.WEST, this); currentLayout.putConstraint(SpringLayout.EAST, uuidField, -181, SpringLayout.EAST, this); currentLayout.putConstraint(SpringLayout.SOUTH, uuidField, -156, SpringLayout.SOUTH, this); add(uuidField); uuidField.setColumns(10); passwordField = new JPasswordField(); currentLayout.putConstraint(SpringLayout.NORTH, loginButton, 6, SpringLayout.SOUTH, passwordField); currentLayout.putConstraint(SpringLayout.NORTH, passwordField, 6, SpringLayout.SOUTH, uuidField); currentLayout.putConstraint(SpringLayout.WEST, passwordField, 0, SpringLayout.WEST, uuidField); currentLayout.putConstraint(SpringLayout.SOUTH, passwordField, 49, SpringLayout.NORTH, uuidField); currentLayout.putConstraint(SpringLayout.EAST, passwordField, -181, SpringLayout.EAST, this); passwordField.setBackground(Color.WHITE); passwordField.setToolTipText(""); add(passwordField); JLabel lblAccountName = new JLabel("Account Name "); currentLayout.putConstraint(SpringLayout.NORTH, lblAccountName, 3, SpringLayout.NORTH, uuidField); currentLayout.putConstraint(SpringLayout.EAST, lblAccountName, -6, SpringLayout.WEST, uuidField); lblAccountName.setForeground(Color.BLACK); lblAccountName.setFont(new Font("Times New Roman", Font.PLAIN, 12)); add(lblAccountName); JLabel lblPassword = new JLabel("Password"); currentLayout.putConstraint(SpringLayout.SOUTH, lblPassword, 0, SpringLayout.SOUTH, passwordField); currentLayout.putConstraint(SpringLayout.EAST, lblPassword, -6, SpringLayout.WEST, passwordField); lblPassword.setForeground(Color.BLACK); lblPassword.setFont(new Font("Times New Roman", Font.PLAIN, 12)); add(lblPassword); } } //ends FieldPanel }//end LoginPopUp