Swing getHeight()值从0变为16

时间:2012-06-27 06:35:50

标签: java swing jlabel jtextfield layout-manager

我正在尝试在Swing中创建一个标签为“user”的框,一个用户名的文本字段和一个“登录”按钮。这是我的代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;

public class Engine
{
    JFrame frame;
    public void go()
    {
        setUpGui();
        userNameScreen();
    }
    public void setUpGui()
    {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    public void userNameScreen()
    {
        JPanel background = new JPanel();
            frame.getContentPane().add(background);
        JLabel labelUserName = new JLabel("User:");
            background.add(labelUserName);
            System.out.println(labelUserName.getHeight()); // 0
        JTextField textFieldUserName = new JTextField();
            System.out.println(labelUserName.getHeight()); // 16
            textFieldUserName.setPreferredSize(new Dimension(110,labelUserName.getHeight()));
            background.add(textFieldUserName);
        JButton buttonSignIn = new JButton("Sign In");
            background.add(buttonSignIn);
        /*
        background.add(labelUserName);
        background.add(textFieldUserName);
        background.add(buttonSignIn);
        frame.getContentPane().add(background);
        */
        frame.pack();
    }
}

我的驱动程序类只创建一个引擎实例,然后运行方法go()。
我读到Swing组件在添加之前没有高度/宽度属性(因为这是布局管理器决定它们有多少空间),所以在方法userNameScreen()中添加所有组件是有意义的在结尾*(这里注释掉)使textFieldUserName变量没有高度。
但是,你可以在同一个方法中看到userNameScreen(),我有它做

System.out.println(labelUserName.getHeight());

两次。第一次,它是0.第二次,它是16.我不明白为什么第一次,它会将其注册为0.它已经被添加到面板(在之前的行中),并且没有似乎是任何会改变它在第一个println()和下一个println之间的高度的东西。那么为什么第一个中的值为0,为什么它几乎立即变为16?

*我应该注意,当我说添加最后注释掉的所有内容时,它还包括删除/注释掉在代码中其他地方完成的所有相同命令。

2 个答案:

答案 0 :(得分:2)

在EDT上不创建/修改Swing组件是一个副作用。现在,当您在另一个线程中添加组件时,EDT正在忙于布局。

您的主要方法应如下所示:

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new Engine().go();
        }
    });
}

答案 1 :(得分:1)

我不确定为什么会发生这种情况,但可能是因为组件的添加可能在后台线程上,并且可能在下一个语句被调用之前没有更新,并且在几个毫秒后更新它并在您调用时出现它第二次。