import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class PasswordDemo {
    public static void main(String[] argv) {
        final JFrame f = new JFrame("PasswordDemo");

        /* Constructing a SwingWorker causes a new Thread to 
         * be created which will run the worker.construct()
         * method we've defined here.  Calls to worker.get() 
         * will wait until the construct() method has returned
         * a value, see below.
         */
        final SwingWorker worker = new SwingWorker() {
            public Object construct() {
                return new ExpensiveDialogComponent();
            }
        };

        /* The ActionListener below gets a component to display 
         * in its message area from the worker, which constructs
         * the component in another thread.  The call to worker.get()
         * will wait if the component is still being constructed.
         */
        ActionListener showSwingWorkerDialog = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JPasswordField input = (JPasswordField)e.getSource();
                char[] password = input.getPassword();
                if (isPasswordCorrect(password))
                    JOptionPane.showMessageDialog(f, worker.get());
                else
                    JOptionPane.showMessageDialog(f,
                        new JLabel("Invalid password."));
            }
        };

        JLabel label = new JLabel("Enter the password: ");
        JPasswordField password = new JPasswordField(10);
        password.setEchoChar('#');

        password.addActionListener(showSwingWorkerDialog);

        JPanel contentPane = new JPanel(new BorderLayout());
        contentPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        contentPane.add(label, BorderLayout.WEST);
        contentPane.add(password, BorderLayout.CENTER);
        f.setContentPane(contentPane);
        f.pack();
        f.setVisible(true);

        //The following is safe because adding a listener is always safe.
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    private static boolean isPasswordCorrect(char[] input) {
        char[] correctPassword = { 'b', 'u', 'g', 'a', 'b', 'o', 'o' };
        if (input.length != correctPassword.length)
            return false;
        for (int i = 0;  i < input.length; i ++)
            if (input[i] != correctPassword[i])
                return false;
        return true;
    }
}

class ExpensiveDialogComponent extends JLabel {
    public ExpensiveDialogComponent() {
        super("This is the world's most expensive label.");
        try {
            Thread.sleep(10000); //sleep for 10 seconds
        } catch (InterruptedException e) {
        }
    }
}
