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
GUI elements not showing until resize of window
提问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 initComponents
to take a main
object:
然后修改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 LayoutManager
for this job, GridBagLayout
or SpringLayout
对于 built_in FlowLayout
(for JPanel
) 我不建议使用pack()
for JFrame
,确定正确的方法可能是LayoutManager
为这项工作使用正确和更好的方法,GridBagLayout
或者SpringLayout
output by using JFrame#setSize()
and without pack()
使用JFrame#setSize()
和不使用输出pack()
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();
}
});
}
}