Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a custom blocking Java Swing prompt

This problem is solved.

I'm am developing a Java Swing based projected, and the look & feel of the application is completely customized. We are trying to maintain a consistent appearance throughout the program, and the default Java dialog windows are not the same.

The current issue requires a control blocking call to the user prompt. Similar to JOptionPane.showConfirmDialog() In this case, the static call produces a window, and halts the flow of the program until the user selects an option. It also returns the value of the option. Note that the GUI itself is not locked up logically, but the user cannot interact with the rest of it.

int n = JOptionPane.showConfirmDialog(this,
    "Are you sure?",
    "Confirm"
    JOptionPane.YES_NO_OPTION);

I would like to duplicate this functionality with a customized appearance, and using a string. Ideally, my code would appear as follows:

String result = CustomPrompt.showPrompt(this,
    "Please enter your name", //Text
    "Prompt.",                //Title
    "John Smith");            //Default

This will generally be used for password input, and I understand the return type of a password is different, but this is an example. This can be accomplished by using a series of button and event listeners, in several classes, but the readability of the code and reliability of the application diminishes.

The Frame would be built via NetBeans and customized from there. I do understand that such a prompt already exists in Swing, but it's look & feel is completely and entirely different.

The question summarized: How to use a customized frame to prompt the user for input in a blocking manner.

The solution to this problem is as follows:

public class PromptForm extends JDialog
{
    transient char[] result;

    public char[] getResult()
    {
        return result;
    }
    public PromptForm(Frame parent)
    {
        super(parent, true);
        initComponents();
    }
    public void prompt()
    {
        this.setVisible(true);
    }
    public static char[] promptForPassword(Frame parent)
    {
        PromptForm pf = new PromptForm(parent);
        pf.prompt();
        return pf.getResult();
    }
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
    {
        result = jPasswordField1.getPassword();
        setVisible(false);
        dispose();
    }
    private void initComponents() {...}

    private javax.swing.JButton jButton1;
    private javax.swing.JPasswordField jPasswordField1;
}

Called by:

    char [] ret = PromptForm.promptForPassword(this);
    JOptionPane.showMessageDialog(this, new String(ret), "Neat", JOptionPane.QUESTION_MESSAGE);
like image 860
Reivax Avatar asked Feb 01 '12 16:02

Reivax


1 Answers

Make CustomPrompt extends JDialog, have it's constructor call super passing the owner Window and the desired ModalityType.

public class CustomPrompt extends JDialog {

  public static String showPrompt(Window parent, String title, String text, 
         String defaultText) {
    final CustomPrompt prompt = new CustomPrompt(parent);
    prompt.setTitle(title);
    // set other components text
    prompt.setVisible(true);

    return prompt.textField.getText();
  }

  private JTextField textField;

  // private if you only want this prompt to be accessible via constructor methods
  private CustomPrompt(Window parent) {
    super(parent, Dialog.DEFAULT_MODALITY_TYPE); 
    // Java >= 6, else user super(Frame, true) or super(Dialog, true);
    initComponents(); // like Netbeans
  }

  // initComponents() and irrelevant code. 
}
like image 87
Anthony Accioly Avatar answered Sep 18 '22 22:09

Anthony Accioly