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, "West");
        contentPane.add(password, "Center");
	f.setContentPane(contentPane);
        f.pack();
        f.show();

	//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) {
	}
    }
}
