greenleafvolatile
greenleafvolatile

Reputation: 13

How to resize JOptionPane?

I made a login dialog using a JOptionPane.

The dialog contains a custom JPanel and custom JButton components.

I want to display a message at the bottom (SOUTH) of the panel when the user enters an incorrect password.

To display that message I use a custom JLabel.

Problem: when the message is displayed the buttons get 'pushed' down and are no longer fully inside the option pane. Ideally the option pane would automatically resize to accommodate the new size of the panel.

I can set the preferredSize of the label to match the Font I'm using in it and the number of lines I want to display in the label, e.g. font size 10 and one line of text setPreferredSize(Integer.MIN_VALUE, 10), 2 lines of text setPreferredSize(Integer.Min_Value, 20) etc.

Downsides:

1) When the message is not displayed the empty label takes up more space than I'd like.

I tried JOptionPane.getRootFrame.pack(). Did not work.

The code below (SSCC) shows what I mean. If you click 'login' the errorLabel text is set and buttons will be 'pushed' down.

import java.awt.event.ActionEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.util.Arrays;
import java.util.logging.Logger;

public class LoginDialog {

    private JTextField usernameField;
    private JLabel errorLabel;
    private JPasswordField passwordField;

    public LoginDialog(){
    }


    private JPanel createMainPanel(){

        JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
        mainPanel.add(createLabelsPanel(), BorderLayout.WEST);
        mainPanel.add(createTextFieldsPanel(), BorderLayout.CENTER);


        errorLabel=new JLabel();
        errorLabel.setFont(new Font(errorLabel.getFont().getName(), Font.PLAIN, 10));
        errorLabel.setForeground(Color.RED);
        errorLabel.setHorizontalAlignment(SwingConstants.CENTER);
        errorLabel.setText("");
        mainPanel.add(errorLabel, BorderLayout.SOUTH);

        return mainPanel;
    }

    private JPanel createLabelsPanel(){

        JPanel labelsPanel = new JPanel(new GridLayout(0, 1, 10, 10));
        labelsPanel.add(new JLabel("Username", SwingConstants.RIGHT));
        labelsPanel.add(new JLabel("Password", SwingConstants.RIGHT));

        return labelsPanel;
    }

    private JPanel createTextFieldsPanel(){

        JPanel textFieldsPanel = new JPanel(new GridLayout(0, 1, 10, 10));

        usernameField = new JTextField();
        passwordField = new JPasswordField();

        textFieldsPanel.add(usernameField);
        textFieldsPanel.add(passwordField);

        return textFieldsPanel;
    }

    private JButton[] createButtons() {

        JButton loginButton = new JButton("Login");

        loginButton.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent event){

                errorLabel.setText("<html> More than two <BR> lines of text <BR> </html>");
            }
        });

        JButton registerButton = new JButton("Register");


        JButton cancelButton = new JButton("Cancel");

        return new JButton[]{loginButton, registerButton, cancelButton};
    }


    private void showAndCreateDialog() {

        JOptionPane.showOptionDialog(null, createMainPanel(), "Login", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, createButtons(), createButtons()[0]);

    }

    public static void main(String[] args){

        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                new LoginDialog().showAndCreateDialog();
            }
        });
    }
}

Buttons get 'pushed' down and are no longer shown fully within the option pane. Would like to learn how to resize option pane to accommodate new JPanel dimensions.

Upvotes: 1

Views: 1457

Answers (1)

MDK
MDK

Reputation: 499

In order to pack the dialog after showing you will need access to the actual JDialog. This can be done by adding a new attribute dialog and replacing the showOptionDialog with

JOptionPane pane = new JOptionPane(createMainPanel(),
    JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
    createButtons(), createButtons()[0]);
dialog = pane.createDialog("Login");
dialog.setVisible(true);

then you can simply call dialog.pack() after setting the text and the dialog will resize.

Note: The default option object has to be contained in the options array, if you call createButtons() twice it will be a different object and won't work, instead store the options like this:

JButton[] buttons = createButtons();
JOptionPane pane =
    new JOptionPane(createMainPanel(), JOptionPane.DEFAULT_OPTION,
        JOptionPane.PLAIN_MESSAGE, null, buttons, buttons[0]);

Upvotes: 1

Related Questions