Search code examples
javaswinglayout-managerjoptionpane

how to set & manage the layout of JOptionPane


I have a simple JOptionPane with some components and I want to arrange them.

enter image description here

For example I want to put the label next to the text/password field, sets their width etc..

This is like how I did it, of course the result wasn't what I wanted:

public class CreateApplicationUserScreen {

  CreateApplicationUserScreen(){
    JLabel l_name=new JLabel("Username");
    JLabel l_pass=new JLabel("Password");
    JTextField tf_name=new JTextField(10);
    JPasswordField pf_pass=new JPasswordField(10);
    JButton b_privs = new JButton("Privs");
    JButton b_databases = new JButton("Databases");

    int res = JOptionPane.showOptionDialog(window, 
                                          new Object[] { l_name, tf_name, 
                                                         l_pass, pf_pass, 
                                                         b_privs, b_databases }, 
                                          "Create application user", 
                                          JOptionPane.OK_CANCEL_OPTION,
                                          JOptionPane.PLAIN_MESSAGE,null, 
                                          new String[]{"Create", "Cancel"},
                                          "default");
  }
}

Solution

  • You can add any Swing component to the option pane. So build your own panel:

    import java.awt.*;
    import javax.swing.*;
    
    public class OptionPanePanel
    {
        private static void createAndShowUI()
        {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo( null );
            frame.setVisible( true );
    
            //  Build a custom panel
    
            JPanel panel = new JPanel( new GridLayout(2, 2) );
            panel.add( new JLabel("First Name") );
            JTextField firstName = new JTextField(10);
    //      firstName.addAncestorListener( new RequestFocusListener(false) );
            panel.add( firstName );
            panel.add( new JLabel("Last Name") );
            JTextField lastName = new JTextField(10);
            panel.add( lastName );
    
            int result = JOptionPane.showConfirmDialog(
                frame, // use your JFrame here
                panel,
                "Use a Panel",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.PLAIN_MESSAGE);
    
            if(result == JOptionPane.YES_OPTION)
            {
                System.out.println(firstName.getText() + " : " + lastName.getText());
            }
            else
            {
                System.out.println("Canceled");
            }
    
            //  Let Option Pane build the panel for you
    
            Object[] msg = {"First Name:", firstName, "Last Name:", lastName};
    
            result = JOptionPane.showConfirmDialog(
                frame,
                msg,
                "Use default layout",
                JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.PLAIN_MESSAGE);
    
            if (result == JOptionPane.YES_OPTION)
            {
                System.out.println(firstName.getText() + " : " + lastName.getText());
            }
            else
            {
                System.out.println("Canceled");
            }
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowUI();
                }
            });
        }
    }
    

    One drawback to this approach is that the focus will be on the button, not the text field. So you may want to use the RequestFocusListener to place focus on your first text field.