BoxLayout:无法设置子组件大小

huangapple go评论55阅读模式
英文:

BoxLayout: can't setup child component size

问题

以下是您要翻译的代码部分:

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("登录");
    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("登录"));

        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));

    }
}

请注意,我已将按钮文本从英文 "Login" 更改为中文 "登录",以便与您的要求一致。如果您有任何其他需要,请告诉我。

英文:

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:

BoxLayout:无法设置子组件大小

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.

BoxLayout:无法设置子组件大小

答案1

得分: 2

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());
    }
}
英文:

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.

BoxLayout:无法设置子组件大小

答案2

得分: 0

Oracle文档中关于BoxLayout的部分:

> 如果没有组件具有最大宽度怎么办?在这种情况下,如果所有组件具有相同的X对齐方式,那么所有组件都会被调整为与容器一样宽。

所以你只需要设置最大尺寸。

英文:

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.

huangapple
  • 本文由 发表于 2020年7月30日 02:08:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/63159903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定