java 直到调整窗口大小才显示 GUI 元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12295056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:20:11  来源:igfitidea点击:

GUI elements not showing until resize of window

javaswing

提问by Andrei0427

I have been experimenting with making GUIs in java as opposed to just using "static" all the time and come across the "SwingUtilities.invokeLater()" method. I manage to get everything setup but when it comes to run the application, nothing appears on the JPanel until I resize the window. Is there a fix for this or am I doing it wrong?

我一直在尝试用 Java 制作 GUI,而不是一直使用“静态”,并遇到了“SwingUtilities.invokeLater()”方法。我设法设置了所有内容,但是在运行应用程序时,JPanel 上没有任何显示,直到我调整窗口大小。有没有办法解决这个问题,还是我做错了?

Heres my code:

这是我的代码:

public class main extends JPanel implements ActionListener{ 
public JLabel userLabel;
public JLabel passLabel;
public JTextField userField;
public JTextField passField;
public JButton login;
public JButton closeLogin;
public JButton help;

public main(){
    userLabel = new JLabel("Username: ");
    passLabel = new JLabel("Password: ");
    userField = new JTextField(16);
    passField = new JTextField(16);

    login = new JButton("Login");
    login.setActionCommand("login");
    login.setMnemonic(KeyEvent.VK_L);
    closeLogin = new JButton("Close");
    closeLogin.setActionCommand("closeLogin");
    closeLogin.setMnemonic(KeyEvent.VK_E);
    help = new JButton("Help");
    help.setActionCommand("helpLogin");
    help.setMnemonic(KeyEvent.VK_H);

    login.addActionListener(this);
    closeLogin.addActionListener(this);
    help.addActionListener(this);

    add(userLabel);
    add(userField);
    add(passLabel);
    add(passField);
    add(login);
    add(help);
    add(closeLogin);

}
public void actionPerformed(ActionEvent e){ 
}
public static void initComponents(){
    JFrame loginFrame = new JFrame("Encrypted Chat - Login");
    loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    main loginPanel = new main();
    loginPanel.setLayout(new FlowLayout());
    loginFrame.setSize(300, 125);
    loginFrame.setResizable(false);
    loginFrame.setVisible(true);        
}
public static void main(String args[]){
    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            initComponents();
        }
    });
}

}

}

EDIT: I know the password JTextField is meant to be a JPasswordField.. so ignore it :P

编辑:我知道密码 JTextField 是一个 JPasswordField ..所以忽略它:P

采纳答案by sjr

You never add your content to the JFrame. The minimal set of changes you need:

您永远不会将内容添加到 JFrame。您需要的最少更改集:

  public static void main(String args[]){
    final main main = new main();
    SwingUtilities.invokeLater(new Runnable(){
      public void run(){
        initComponents(main);
      }
    });
  }

And then modify initComponentsto take a mainobject:

然后修改initComponents取一个main对象:

  public static void initComponents(main main){
    JFrame loginFrame = new JFrame("Encrypted Chat - Login");
    loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    main loginPanel = new main();
    loginPanel.setLayout(new FlowLayout());
    loginFrame.setSize(300, 125);
    loginFrame.setResizable(false);
    loginFrame.setVisible(true);
    loginFrame.add(main);  // <----- this line is added
  }

回答by Balázs édes

Two basic advices:

两个基本建议:

1.)When you use swing, and stuff doesnt show up/update, you should call JPanel.revalidate()and JPanel.repaint()These two functions will update your panel. If you are using a JFrame and you didn't add any extra panels to it, then you can get the content panel by JFrame.getContentPane()

1.)当您使用 Swing 时,没有显示/更新内容,您应该调用JPanel.revalidate()JPanel.repaint()这两个函数将更新您的面板。如果您使用的是 JFrame 并且没有向其中添加任何额外的面板,那么您可以通过以下方式获取内容面板JFrame.getContentPane()

2.)When you finished adding Components to a panel/frame you should also call pack()on the frame, this will ensure, that all your Components have the prefered size.

2.)将组件添加到面板/框架后,您还应该调用pack()框架,这将确保所有组件都具有首选大小。

回答by mKorbel

for built_in FlowLayout(for JPanel) I don't suggest to use pack()for JFrame, sure correct way could be to use proper and better LayoutManagerfor this job, GridBagLayoutor SpringLayout

对于 built_in FlowLayout(for JPanel) 我不建议使用pack()for JFrame,确定正确的方法可能是LayoutManager为这项工作使用正确和更好的方法,GridBagLayout或者SpringLayout

output by using JFrame#setSize()and without pack()

使用JFrame#setSize()和不使用输出pack()

enter image description here

在此处输入图片说明

for example

例如

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class MainLogin implements ActionListener {

    private JFrame loginFrame = new JFrame("Encrypted Chat - Login");
    private JPanel pnl = new JPanel();
    private JLabel userLabel;
    private JLabel passLabel;
    private JTextField userField;
    private JTextField passField;
    private JButton login;
    private JButton closeLogin;
    private JButton help;

    public MainLogin() {
        userLabel = new JLabel("Username: ");
        passLabel = new JLabel("Password: ");
        userField = new JTextField(16);
        passField = new JTextField(16);
        login = new JButton("Login");
        login.setActionCommand("login");
        login.setMnemonic(KeyEvent.VK_L);
        closeLogin = new JButton("Close");
        closeLogin.setActionCommand("closeLogin");
        closeLogin.setMnemonic(KeyEvent.VK_E);
        help = new JButton("Help");
        help.setActionCommand("helpLogin");
        help.setMnemonic(KeyEvent.VK_H);
        login.addActionListener(this);
        closeLogin.addActionListener(this);
        help.addActionListener(this);
        pnl.add(userLabel);
        pnl.add(userField);
        pnl.add(passLabel);
        pnl.add(passField);
        pnl.add(login);
        pnl.add(help);
        pnl.add(closeLogin);
        loginFrame.add(pnl);
        loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        loginFrame.setSize(300, 125);
        loginFrame.setResizable(false);
        loginFrame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                MainLogin mainLogin = new MainLogin();
            }
        });
    }
}