BoxLayout: can't setup child component size

谁说我不能喝 提交于 2021-02-05 09:32:13

问题


I have a JFrame - SuperTest and JPanel - SuperLogin. The login panel has the username and password input fields and a login button. I want it to look like this:

but it looks like the pic below, with input fields having too huge height and width.

SuperTest.java:

import javax.swing.*;

public class SuperTest extends JFrame {
    public SuperTest()  {
        add(new SuperLogin());
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(600, 400);
    }

    public static void main(String[] args) {
        SuperTest test = new SuperTest();
    }
}

SuperLogin.java:

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

public class SuperLogin extends JPanel {
    private JButton loginButton =
            new JButton("Login");
    private TextField usernameField =
            new TextField();
    private TextField passwordField =
            new TextField();

    public SuperLogin()  {
        BoxLayout layout =
                new BoxLayout(this, BoxLayout.Y_AXIS);
        setLayout(layout);

        add(new JLabel("Login"));

        add(usernameField);
        add(passwordField);
        add(loginButton);

        componentSetup();
    }

    private void componentSetup()  {
        loginButton.setSize(20, 10);
        usernameField.setSize(100, 50);
        passwordField.setSize(100, 50);

        loginButton.setMinimumSize(new Dimension(20, 10));
        usernameField.setMinimumSize(new Dimension(100, 50));
        passwordField.setMinimumSize(new Dimension(100, 50));

        loginButton.setPreferredSize(new Dimension(20, 10));
        usernameField.setPreferredSize(new Dimension(100, 50));
        passwordField.setPreferredSize(new Dimension(100, 50));

    }
}

I read that setting min, preferred size would be enough, but it looks like it's not.


回答1:


I put everything into a single class. Explanations after the code.

import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class SuperOne implements Runnable {
    private JButton  loginButton;
    private JFrame  frame;
    private JPasswordField  passwordField;
    private JTextField  usernameField;

    @Override
    public void run() {
        showGui();
    }

    private JPanel createLoginPanel() {
        JPanel loginPanel = new JPanel();
        BoxLayout layout = new BoxLayout(loginPanel, BoxLayout.PAGE_AXIS);
        loginPanel.setLayout(layout);
        loginPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        JLabel loginLabel = new JLabel("Login");
        loginLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        usernameField = new JTextField(10);
        usernameField.setAlignmentX(Component.CENTER_ALIGNMENT);
        passwordField = new JPasswordField(10);
        passwordField.setAlignmentX(Component.CENTER_ALIGNMENT);
        loginButton = new JButton("login");
        loginButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        loginPanel.add(loginLabel);
        loginPanel.add(Box.createVerticalStrut(15));
        loginPanel.add(usernameField);
        loginPanel.add(Box.createVerticalStrut(5));
        loginPanel.add(passwordField);
        loginPanel.add(Box.createVerticalStrut(5));
        loginPanel.add(loginButton);
        return loginPanel;
    }

    private void showGui() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(createLoginPanel());
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    /**
     * Start here.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new SuperOne());
    }
}
  1. All code that deals with the GUI components must run on the Event Dispatch Thread (EDT). Although not mandatory, I like to explicitly launch the EDT by calling EventQueue.invokeLater().
  2. Refer to the Web page with the tutorial on BoxLayout that appears in the other answer.
  3. JTextField and JPasswordField both have a columns property. I find that better for setting a desired width than using setPreferredSize()

Here is a screen capture of the running app.




回答2:


From the Oracle docs for BoxLayout:

What if none of the components has a maximum width? In this case, if all the components have identical X alignment, then all components are made as wide as their container.

So you just need to set the maximum size.



来源:https://stackoverflow.com/questions/63159903/boxlayout-cant-setup-child-component-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!