【问题标题】:Add JLabel dynamically in a JPanel (revalidate didn't work)在 JPanel 中动态添加 JLabel(重新验证不起作用)
【发布时间】:2016-05-02 16:47:24
【问题描述】:

我有一个方法尝试在 JPanel 中的 PackingByVolDialog 类中动态添加标签:

public static void addContent( String content, String container) {

        contentPanel = new JPanel();
        changingLabel = new JLabel(); 
        changingLabel.setText(container+"\n"+content);
        contentPanel.add(changingLabel);
        contentPanel.revalidate();
        contentPanel.repaint();
        dialog.add(contentPanel);
    }

在另一个类中,我调用addContent方法如下:

for (int u=0; u<containers.size()-1; u++) {

          PackingByVolDialog.addContent(content, container);

                 } //end for

这是我被要求制作的 MCVE(?)(我希望它是正确且有用的)

public class VolDialog extends JDialog {

    private static JLabel label = new JLabel() ;
    private static JPanel contentPanel = new JPanel();
    private static VolDialog dialog = new VolDialog(); 


  public static void main(String[] args) {
        try {
             dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
             dialog.add(contentPanel);
             dialog.revalidate();
             dialog.repaint();
            dialog.setVisible(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


 public static void addContent( String text) {

    contentPanel = new JPanel();
    changingLabel = new JLabel(); 
    changingLabel.setText(text);
    contentPanel.add(changingLabel);
    }


 public class content {

       for (int u=0; u<N; u++) {

               VolDialog.addContent("text");

             } //end for
          }

即使使用JPanel的repaintrevalidate,窗口中也只会显示最后的输出。

有谁知道问题出在哪里?

【问题讨论】:

  • 为什么在将面板添加到对话框之前调用revalidate和repaint(不会有效果,因为contentPanel还不可见)?而且您需要重新验证对话框,而不是 contentPanel。
  • 这段代码看起来不正确,包括使用静态交换 JPanel 和 JLabel ,避免使用 CardLayout -- 为了获得最好的帮助,请创建并发布一个有效的minimal reproducible example 这样我们就可以真正看看发生了什么。发帖前请阅读链接。
  • “我有一个尝试动态添加标签的方法..” 这是一个想法。保持面板不变,不要每次都刷新。保持相同的标签a好,只需更改标签文字!
  • @FredK :我更改了代码并对对话框进行了重新验证,然后在将面板添加到对话框后调用它,就像你说的那样!但没有任何改变,同样的显示。
  • 当它甚至没有编译时,它怎么会成为一个运行时问题的例子呢? MCVE 需要类定义、导入和main 方法才能将其显示在屏幕上。当你认为你有一个时,将它粘贴到你的 IDE 中的一个新项目中,编译它,运行它,然后检查问题是否显示。然后确保在编辑问题以添加之前使用 IDE 为“格式化代码”定义的快捷方式。或者就像我通常在复制/粘贴注释中所说的那样:使用合乎逻辑且一致的缩进代码行和块的形式。缩进是为了让代码的流程更容易理解!

标签: java swing jpanel jlabel


【解决方案1】:

我做的项目太大太复杂

这就是为什么您在提问时总是需要创建和发布 MCVE。我们没有时间查看和了解您的整个项目。由您来理解您所询问的问题,然后简化代码以复制问题。很多时候,当你这样做时,你会发现你的问题。如果没有,那么您可以发布一段简单的代码。

这不是一件容易的事。

一旦你做了几次,就像生活中的任何事情一样,它会变得越来越容易。

我很着急,因为我根本没有时间编写新代码

您仍然应该编写结构良好且设计良好的代码。使用正常的 Swing 编码约定正确地创建 MVCE 无需更多时间。

例如:

  1. 您不应该扩展 JDialog。您所做的只是将组件添加到对话框中,因此您只需在 main() 方法中创建对话框。

  2. 您不应该使用静态变量和方法。这表明代码设计不佳。

  3. 类名应以大写字符开头

  4. 您的代码无法编译。

  5. 您永远不会创建“内容”类的新实例,因此永远不会调用 addContent(...) 方法。所以这意味着你甚至从未测试过你发布的代码。

当您提出问题时,您需要花时间正确地做事,并向我们提供解决问题所需的信息。

只有最后一个输出显示在窗口中。

Swing 框架和对话框的默认布局管理器是BorderLayout。您只能将单个组件添加到 BorderLayout 的“CENTER”(未指定约束时的默认设置)。

所以基本上你需要改变对话框的布局管理器。尝试改变:

dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setLayout( new FlowLayout() );

看看有什么不同。

如果您需要更多帮助,请发布适当的 MCVE。一个实际编译并且设计良好的。

【讨论】:

  • 感谢您的回复和建议!我已经解决了这个问题,现在它工作得很好。
  • 好吧,在我们花时间回答问题之前,您应该告诉我们这一点。一旦你找到答案,你就应该做出回应,这样我们就不会花时间回答已经回答过的问题。
  • 我打算稍后发布答案,但你是对的。对此感到抱歉。
猜你喜欢
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 2014-12-29
  • 2011-10-31
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多