I'm trying to create a custom dialog that acts much like th JOptionPane.showInputDialog() except it uses an asterisk as an echo character. So far, I've come up with the following. . .

class CustomInputDialog extends JDialog implements ActionListener
{
JLabel prompt;
JPasswordField input;
JButton ok;
JDialog dialog;
String word;

CustomInputDialog(String title, String directions)
{
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3,1));
prompt = new JLabel(directions);

input = new JPasswordField();
input.setEchoChar('*');

ok = new JButton("OK");
ok.addActionListener(this);

panel.add(prompt);
panel.add(input);
panel.add(ok);

dialog = new JDialog();
dialog.setResizable(false);
dialog.getContentPane().add(panel);
dialog.setTitle(title);
dialog.getContentPane().setLayout(new FlowLayout());
dialog.setVisible(true);

}

public void actionPerformed(ActionEvent event)
{
char[] temp = input.getPassword();
StringBuffer temp2 = new StringBuffer("");

for(int i = 0; i < temp.length; i++)
	{
	temp2.append(temp[i]);
	}
word = temp2.toString();
}

public String getText()
{
return word;
}
}

It doesn't seem to do anything when I call it, not that I really understand how to call it. . .

I tried using CustomInputDialog d = new CustomInputDialog();

and then String aString = d.getText();

but this didn't work at all. Can someone please point me in the right direction?

When you call setVisible(true) on a JFrame all other threads except the one handling that JFrame block until the JFrame has been set to invisible.
So your getText method never gets called.

You're also not creating a custom dialog. Override JDialog.

I somewhat understand that, but the setVisible method never does anything. i.e. the dialog never appears at all. I don't understand what you mean by override JDialog either. Sorry for all the questions, I'm a bit new with GUI programming.

Member Avatar for iamthwee

Google gave me tis...

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

/* PasswordDemo.java is a 1.4 application that requires no other files. */

public class PasswordDemo extends JPanel
                          implements ActionListener {
    private static String OK = "ok";
    private static String HELP = "help";

    private JFrame controllingFrame; //needed for dialogs
    private JPasswordField passwordField;

    public PasswordDemo(JFrame f) {
        //Use the default FlowLayout.
        controllingFrame = f;

        //Create everything.
        passwordField = new JPasswordField(10);
        passwordField.setEchoChar('*');
        passwordField.setActionCommand(OK);
        passwordField.addActionListener(this);

        JLabel label = new JLabel("Enter the password: ");
        label.setLabelFor(passwordField);

        JComponent buttonPane = createButtonPanel();

        //Lay out everything.
        JPanel textPane = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        textPane.add(label);
        textPane.add(passwordField);

        add(textPane);
        add(buttonPane);
    }

    protected JComponent createButtonPanel() {
        JPanel p = new JPanel(new GridLayout(0,1));
        JButton okButton = new JButton("OK");
        JButton helpButton = new JButton("Help");

        okButton.setActionCommand(OK);
        helpButton.setActionCommand(HELP);
        okButton.addActionListener(this);
        helpButton.addActionListener(this);

        p.add(okButton);
        p.add(helpButton);

        return p;
    }

    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();

        if (OK.equals(cmd)) { //Process the password.
            char[] input = passwordField.getPassword();
            if (isPasswordCorrect(input)) {
                JOptionPane.showMessageDialog(controllingFrame,
                    "Success! You typed the right password.");
            } else {
                JOptionPane.showMessageDialog(controllingFrame,
                    "Invalid password. Try again.",
                    "Error Message",
                    JOptionPane.ERROR_MESSAGE);
            }

            //Zero out the possible password, for security.
            for (int i = 0; i < input.length; i++) {
                input[i] = 0;
            }

            passwordField.selectAll();
            resetFocus();
        } else { //The user has asked for help.
            JOptionPane.showMessageDialog(controllingFrame,
                "You can get the password by searching this example's\n"
              + "source code for the string \"correctPassword\".\n"
              + "Or look at the section How to Use Password Fields in\n"
              + "the components section of The Java Tutorial.");
        }
    }

    /**
     * Checks the passed-in array against the correct password.
     * After this method returns, you should invoke eraseArray
     * on the passed-in array.
     */
    private static boolean isPasswordCorrect(char[] input) {
        boolean isCorrect = true;
        char[] correctPassword = { 'i', 'a', 'm', 't', 'h', 'w', 'e', 'e' };

        if (input.length != correctPassword.length) {
            isCorrect = false;
        } else {
            for (int i = 0; i < input.length; i++) {
                if (input[i] != correctPassword[i]) {
                    isCorrect = false;
                }
            }
        }

        //Zero out the password.
        for (int i = 0; i < correctPassword.length; i++) {
            correctPassword[i] = 0;
        }

        return isCorrect;
    }

    //Must be called from the event-dispatching thread.
    protected void resetFocus() {
        passwordField.requestFocusInWindow();
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Make sure we have nice window decorations.
        JFrame.setDefaultLookAndFeelDecorated(true);

        //Create and set up the window.
        JFrame frame = new JFrame("PasswordDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        final PasswordDemo newContentPane = new PasswordDemo(frame);
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Make sure the focus goes to the right component
        //whenever the frame is initially given the focus.
        frame.addWindowListener(new WindowAdapter() {
            public void windowActivated(WindowEvent e) {
                newContentPane.resetFocus();
            }
        });

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

I'm getting there. This class, based on the one iamthwee showed me works fine if i run the application directly. I just don't understand 1, how to add it into my application and how to have my application wait until something is entered before continuing.

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

class PasswordDialog extends JPanel implements ActionListener
{
private static JFrame frame;
private JPasswordField input;
private JLabel prompt;
char[] entry;
private static String userString;

PasswordDialog(String prompt)
{

input = new JPasswordField(20);
input.setEchoChar('*');
input.setActionCommand("OK");
input.addActionListener(this);

userString = prompt;

this.prompt = new JLabel(prompt);
this.prompt.setLabelFor(input);

JComponent buttonPane = createButtonPanel();

JPanel textPane = new JPanel(new FlowLayout(FlowLayout.TRAILING));
textPane.add(this.prompt);
textPane.add(input);

add(textPane);
add(buttonPane);
createAndShowGUI();
}

protected JComponent createButtonPanel() 
{
JPanel p = new JPanel(new GridLayout(0,1));
JButton okButton = new JButton("OK");

okButton.addActionListener(this);
p.add(okButton);
return p;
}

public void actionPerformed(ActionEvent event)
{
entry = input.getPassword();
frame.setVisible(false);
isReady = true;
}

public static void createAndShowGUI()
{
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame("PasswordDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final PasswordDialog newContentPane = new PasswordDialog(userString);
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);


frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
	    });
}

public String getText()
{
StringBuffer temp = new StringBuffer();

for(int i = 0; i < entry.length; i++)
	{
	temp.append(entry[i]);
	}

String returnString = temp.toString();
return returnString;
}

}

here's where I call the Dialog. maybe i'm doing this wrong? word is an instance variable in my application.

PasswordDialog p = new PasswordDialog(player.getName() + ", enter the secret word");

word = p.getText();

Thanks for the help so far.

A JPanel is always part of something else, usually either another JPanel, a JDialog, or a JFrame.

So you'd get a custom JDialog like this:

class RecordDetails extends JDialog {
    private JTextField customerNumber = new JTextField();
    private JButton okButton = new JButton();
    boolean cancelStatus = true;
    private SubcontractorDisplay details;
    private String customerId;
    private boolean readonly;

    public RecordDetails(Frame owner, Subcontractor record) {
        this(owner, record, true);
    }

    public RecordDetails(Frame owner, Subcontractor record, boolean readonly) {
        this(owner, "Subcontractor information", true);
        this.readonly = readonly;
        setData(record);
    }

    public RecordDetails(Frame owner, String title, boolean modal) {
        super(owner, title, modal);
        FlowLayout buttonLayout = new FlowLayout();
        JPanel screen = new JPanel();
        BorderLayout screenLayout = new BorderLayout();
        JButton cancelButton = new JButton();
        details = new SubcontractorDisplay();
        JPanel buttons = new JPanel();
        JPanel customerData = new JPanel();
        FlowLayout flowLayout1 = new FlowLayout();
        Box form = Box.createVerticalBox();
        Box booking = Box.createVerticalBox();
        JLabel customerLabel = new JLabel("Book for customer");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        screen.setLayout(screenLayout);
        customerLabel.setDisplayedMnemonic('B');
        customerLabel.setLabelFor(customerNumber);
        customerNumber.setToolTipText(
            "Customer number of the customer who wants to book this subcontractor");
        customerNumber.setColumns(10);
        cancelButton.setToolTipText(
            "Close this dialog without booking the subcontractor");
        cancelButton.setMnemonic('C');
        cancelButton.setText("Cancel");
        cancelButton.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                cancelOperation();
            }
        });
        okButton.setToolTipText(
            "Reserve the selected subcontractor for the indicated customer");
        okButton.setMnemonic('O');
        okButton.setText("OK");
        okButton.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                confirmOperation();
            }
        });
        buttons.setLayout(buttonLayout);
        buttonLayout.setAlignment(FlowLayout.RIGHT);
        this.setDefaultCloseOperation(javax.swing.WindowConstants.
                                      HIDE_ON_CLOSE);
        this.setModal(modal);
        this.setResizable(false);
        customerData.setLayout(flowLayout1);
        getContentPane().add(screen);
        screen.add(form, java.awt.BorderLayout.CENTER);
        form.add(details);
        form.add(Box.createVerticalStrut(15));
        form.add(booking);
        booking.add(customerData);
        booking.add(buttons);
        buttons.add(okButton);
        buttons.add(cancelButton);
        customerData.add(customerLabel);
        customerData.add(customerNumber);
        pack();
    }
    private void cancelOperation() {
        Logger.getLogger("suncertify.client").entering(this.getClass().getName(),
            "cancelOperation");
        cancelStatus = true;
        if (customerId == null) {
            customerId = "";
        }
        this.setVisible(false);
        Logger.getLogger("suncertify.client").exiting(this.getClass().getName(),
            "cancelOperation");
    }

    private void confirmOperation() {
        Logger.getLogger("suncertify.client").entering(this.getClass().getName(),
            "confirmOperation");
        cancelStatus = false;
        customerId = customerNumber.getText();
        this.setVisible(false);
        Logger.getLogger("suncertify.client").exiting(this.getClass().getName(),
            "confirmOperation");
    }
}

Which has a panel for some information to show and a few buttons.
I set a boolean to indicate whether the user presses OK or Cancel when a button is pressed so I can check that status afterwards.

If you set a JDialog to be modal using setVisible(true) on it the calling class will wait at that line until the JDialog is closed.

I tried using CustomInputDialog d = new CustomInputDialog();

and then String aString = d.getText();

So you're trying to display the dialog when you call getText()? Call the visible method from inside that then.

public String getText()
{
	this.setVisible(true);
	return word;
}
 
public void actionPerformed(ActionEvent e)
{
	if (e.getSource() == ok)
	{
		  //determine final value for "word"
		  word = temp2.toString();
		  this.setVisible(false);
	}
}

Now, when you call getText(), the dialog box will be displayed. When the user clicks the OK button, the dialog is hidden again and falls back to the next line in the getText() method. Which in this cause only does 1 more thing, returns the value of "word".

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.