【问题标题】:JPanel not displaying in JFrame - JavaJPanel 未在 JFrame 中显示 - Java
【发布时间】:2012-09-14 19:54:21
【问题描述】:

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

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

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

    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);

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

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

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

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

谢谢。

编辑:

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);

这会有帮助吗?

【问题讨论】:

    标签: java swing jframe jpanel


    【解决方案1】:

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

    在调用setVisible(true) 之前,您似乎需要pack()setSize(int,int)setExtendedState(int) 和/或setResizable(boolean) 方法的某种组合。


    编辑:

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

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

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

    尽可能延迟呼叫setVisible(true)。最好不要在 JFrame 构造函数中调用它。

    如果您在启动应用程序后需要修改 Swing 控件,则需要通过 事件调度线程 来完成(请参阅中的 invokeLaterinvokeAndWait 方法SwingUtilities 等)。

    【讨论】:

    • 那么我要先设置 RESIZABILITY 吗?那么能见度呢?会不会……出于某种原因是问题所在?好的,我刚刚尝试了 pack(),setSize 已经存在,setExtendedState(JFrame.ALL_DONT_WORK) 和 setResizable(false) 都在调用 setVisible(true) 之前,它不起作用。我还想超双三重四倍注意,这发生在我的其他应用程序中,我 setResizable(false) 等使其可显示......而且我记得我的讲师说她以前也遇到过同样的问题她只是调整它的大小来修复它。
    • @Dois - 看看 Swing 教程中的并发性 - java.sun.com/docs/books/tutorial/uiswing
    • 在 invokeLater 中调用 JFrame(我的 Server 类)似乎有效。谢谢大家,节省了我很多时间并治愈了我的头痛。
    【解决方案2】:

    此类间歇性故障表明存在同步问题。确保您在EDT 上构建和运行您的GUI。此外,您可能希望看到这个非常简单的,~100 行,GUI chat program

    【讨论】:

      【解决方案3】:

      调用 setVisible 为时过早。它立即运行并在调用它时绘制窗口。如果您尚未将所有组件添加到框架,则它们不会被绘制。这就是为什么调整框架的大小似乎使它出现的原因。因为调整大小会导致执行重绘。

      将 setVisible 设为 JFrame 构造函数中的最后一次调用。

      【讨论】:

      • 实际上,最初当我遇到问题时,我认为这可能是问题所在,但实际上我有一个循环运行每秒 60 次,为我的容器调用 repaint,所以我排除了这种情况。也许我的记忆被笼罩了,但无论如何, SwingUtilities.invokeLater 似乎工作得很好。谢谢大家。
      猜你喜欢
      • 1970-01-01
      • 2011-07-18
      • 2014-03-16
      • 2014-10-02
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 2022-01-12
      • 2012-10-17
      相关资源
      最近更新 更多