我正在尝试在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?
*我应该注意,当我说添加最后注释掉的所有内容时,它还包括删除/注释掉在代码中其他地方完成的所有相同命令。
答案 0 :(得分:2)
在EDT上不创建/修改Swing组件是一个副作用。现在,当您在另一个线程中添加组件时,EDT正在忙于布局。
您的主要方法应如下所示:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Engine().go();
}
});
}
答案 1 :(得分:1)
我不确定为什么会发生这种情况,但可能是因为组件的添加可能在后台线程上,并且可能在下一个语句被调用之前没有更新,并且在几个毫秒后更新它并在您调用时出现它第二次。