JPanel 未在 JFrame 中显示 - Java

2022-01-24 00:00:00 java swing jpanel jframe

Server 是我创建的一个扩展 JFrame 的类.

Server is a class I made that extends JFrame.

    Server serverApp = new Server(TITLE, WIDTH, HEIGHT, true, false);

我已经有效地删除了几乎所有其他代码,但问题仍然存在!

I've effectively removed almost all the other code but the problem still remains!

    c = getContentPane();
    c.setLayout(new BorderLayout());

    //Components  /***AHHHHH***/
    lblEnterMessage = new JLabel("Enter Message ");
    txtEnterMessage = new JTextField(50);
    txtEnterMessage.addActionListener(this);
    btnSend = new JButton("Send");
    btnSend.addActionListener(this);
    taDisplay = new JTextArea("Test, test test.", 10, 0);
    taDisplay.setEditable(false);
    JScrollPane jspDisplay = new JScrollPane(taDisplay);

    pnlChatTop = new JPanel(new FlowLayout());
    pnlChatTop.add(lblEnterMessage);
    pnlChatTop.add(txtEnterMessage);
    pnlChatTop.add(btnSend);
    pnlChat = new JPanel(new BorderLayout());
    pnlChat.add(pnlChatTop, BorderLayout.CENTER);
    pnlChat.add(jspDisplay, BorderLayout.SOUTH);

    c.add(pnlChat, BorderLayout.CENTER);

哦,天哪,它突然工作了......我正要删除这个问题,但我又运行了几次,只是随机工作,有时不工作.

Oh dang, it just suddenly WORKED... And I was about to remove this question but I ran it again a few times it and just randomly WORKS and doesn't WORK at times.

我只记得以前在其他项目"中遇到过这个问题,我的解决方案是调整窗口大小.每当我简单地调整它的大小时,组件就会显示出来.

I've just remembered having this problem before with other 'projects' and my solution was to make the window resizable. Whenever I simply resized it, the components would display.

这一次,我正在制作一个游戏,但我不希望它可以调整大小......而且我想知道如何以正确的方式永久解决这个问题.

This time, I'm making a game and I don't want it to be resizable... and I wanna know how to fix this problem for good and in the proper way anyway.

帮助!有谁知道为什么会这样?

Help! Does anyone know why this is happening?

谢谢.

public Server(String title, int sizeW, int sizeH, boolean visibility, boolean resizability) {

    /* Initialization */
    //JFrame settings
    setTitle(title);
    setSize(sizeW, sizeH);
    setVisible(visibility);
    setResizable(resizability);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    addKeyListener(this);

这会有帮助吗?

推荐答案

从您提供的代码中看不出问题.

The problem is not apparent from the code you have provided.

听起来你想要 pack(), setSize(int,int), setExtendedState(int) 和/或 setResizable(boolean) 方法之前调用 setVisible(true).

It sounds like you want some combination of the pack(), setSize(int,int), setExtendedState(int) and/or setResizable(boolean) methods prior to calling setVisible(true).

setTitle(title);
setSize(sizeW, sizeH);
setVisible(visibility);
setResizable(resizability);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

此代码中存在竞争条件.有时主线程会在框架显示之前使组件进入正确的状态以进行绘制;有时框架会在一切准备就绪之前获胜并开始绘画.

There is a race condition in this code. Sometimes the main thread will get the components into the correct state to be painted before the frame displays; sometimes the frame wins and starts painting before everything is ready.

使用 Swing 的好处是您可以自动使用多线程代码.虽然在主线程上初始化控件通常是安全的,但一旦您启动 事件调度线程(正如 setVisible(true) 肯定会那样),所有的赌注都是关闭.

The thing about using Swing is that you are automatically working with multi-threaded code. Although it is generally safe to initialize controls on the main thread, once you cause the event dispatch thread to start (as setVisible(true) will surely do), all bets are off.

尽可能长时间地延迟调用 setVisible(true).最好不要从 JFrame 构造函数中调用它.

Delay calling setVisible(true) as long as possible. Preferably, don't call it from within your JFrame constructor.

如果您在启动应用程序后需要修改 Swing 控件,则需要通过 事件调度线程 来完成(参见 invokeLater 和SwingUtilities<中的 invokeAndWait 方法/a> 等).

If you need to modify Swing controls after you've kicked off your application, you'll need to do it via the event dispatch thread (see the invokeLater and invokeAndWait methods in SwingUtilities, among others).

相关文章