Parmenides
Parmenides

Reputation: 85

Why pack() shrink the frame?

I have written a login window, and if I would use the setBounds() to define the size of the frame, all of the components are visible. But using the pack() the frame shrink to the minmal, and there is no any component to be displayed.

public class Window extends JFrame {
    public Window() {
        setTitle("Login");
        setLocationRelativeTo(null);
        setSize(new Dimension(200, 130));
        pack(); // it make the frame shrink to the minimal
        JLabel lblUser = new JLabel("User:");
        lblUser.setPreferredSize(new Dimension(10, 0));
        lblUser.setHorizontalAlignment(SwingConstants.RIGHT);
        TextField txtUser = new TextField(10);
        JLabel lblPassword = new JLabel("Password:");
        lblPassword.setPreferredSize(new Dimension(10, 0));
        lblPassword.setHorizontalAlignment(SwingConstants.RIGHT);
        TextField txtPassword = new TextField(10);
        JPanel pnlData = new JPanel(new GridLayout(2, 2, 5, 5));
        Border titleBorder = new TitledBorder("Login");
        pnlData.setBorder(titleBorder);
        pnlData.add(lblUser);
        pnlData.add(txtUser);
        pnlData.add(lblPassword);
        pnlData.add(txtPassword);
        JButton jbtOk = new JButton("OK");
        JButton jbtCancel = new JButton("Cancel");
        JPanel pnlButton = new JPanel(new FlowLayout(CENTER, 10, 0));
        pnlButton.add(jbtOk);
        pnlButton.add(jbtCancel);
        Box boxOutter = Box.createVerticalBox();
        boxOutter.add(pnlData);
        boxOutter.add(pnlButton);
        add(boxOutter);
        setVisible(true);
    }
}

Upvotes: 1

Views: 263

Answers (1)

Sergiy Medvynskyy
Sergiy Medvynskyy

Reputation: 11327

The method pack must be called after adding all of the components to a frame. And the method setLocationRelativeTo must be called after pack/setSize.

Another problem: lblPassword.setPreferredSize(new Dimension(10, 0));. This line make no sence.

And last one: don't mix AWT and Swing components. Use JTextField instead of TextField

Here is the your example corrected by me.

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.TextField;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

/**
 * <code>Window</code>.
 */
public class Window extends JFrame {
    public Window() {
        setTitle("Login");
        JLabel lblUser = new JLabel("User:");
        lblUser.setPreferredSize(new Dimension(10, 0));
        lblUser.setHorizontalAlignment(SwingConstants.RIGHT);
        JTextField txtUser = new JTextField(10);
        JLabel lblPassword = new JLabel("Password:");
        lblPassword.setHorizontalAlignment(SwingConstants.RIGHT);
        TextField txtPassword = new TextField(10);
        JPanel pnlData = new JPanel(new GridLayout(2, 2, 5, 5));
        Border titleBorder = new TitledBorder("Login");
        pnlData.setBorder(titleBorder);
        pnlData.add(lblUser);
        pnlData.add(txtUser);
        pnlData.add(lblPassword);
        pnlData.add(txtPassword);
        JButton jbtOk = new JButton("OK");
        JButton jbtCancel = new JButton("Cancel");
        JPanel pnlButton = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 0));
        pnlButton.add(jbtOk);
        pnlButton.add(jbtCancel);
        Box boxOutter = Box.createVerticalBox();
        boxOutter.add(pnlData);
        boxOutter.add(pnlButton);
        add(boxOutter);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Window::new);
    }
}

Upvotes: 1

Related Questions