【问题标题】:How do you update a JDialog with new information?如何用新信息更新 JDialog?
【发布时间】:2012-04-11 20:06:40
【问题描述】:

我有一个 GUI,它允许用户单击按钮并查看文本文件的内容。问题是文件可能相当大(超过 100,000 行数据),读取和显示在表格中可能需要 15 秒以上。

文本文件格式示例:

*/
    Account ID     : 8 digit number
    Money Charged  : Integer < $10
    Values separated by \t 

/*


Account Id    Money Charged
----------    --------------
731298        3
359412        5
624937        1

所以当按钮被点击时,它会读取每一行并将每个 id 放入 map 并增加账户的费用。

一旦完成,它将在 JDialog 中放置一个带有信息的 JTable。但是,一旦单击按钮,用户可能会对程序正在做什么感到困惑,因为我在 JDialog 和 JTable 出现之前经历了超过 10-15 秒的延迟。

那么有没有办法让 JDialog 出现一个字符串,让用户知道它正在创建表? (我认为可以使用 JDialog 方法之一来完成,例如 repaint()validate,但这些方法似乎没有奏效。

这是我认为应该完成的顺序:

//Psuedo-code
actionPerformed {
    create frame
    display label that lets user know its creating table
    read text file
    create map and place values
    remove label
    update dialog with table // unsure what to do to update it properly
}

所以我的总体问题很简单: 是否可以通知用户它当前正在计算数据(通过 JDialog 中的 JLabel),一旦读取数据,显示 JTable(通过更新 JDialog)?

如果需要,我可以提供来源。虽然不确定它是否真的需要

编辑

public void actionPerformed(ActionEvent event) {
    JFrame frame = new JFrame();
    JDialog dialog = new JDialog(frame, "Account Charges", true);
    JLabel label = new JLabel("Currently calculating the charges")

    dialog.getContentPane().add(label);       //add waiting label
    dialog.setVisible(true);              
    readData(myFile);                         //read file and create table
    dialog.getContentPane().remove(label);    //waiting label no longer needed
    dialog.getContentPane().add(myJtable);    //update dialog with the table
}

【问题讨论】:

  • If needed, I can provide source. Not sure it's really needed though,没错,天上有星星之类的选项,哪个是你的,请用SSCCE编辑你的问题
  • @mKorbel 我以为有人会要求 SSCCE,这就是我添加最后一行的原因。我仍然认为不需要回答是否能够使用新信息更新 JDialog。但我会整理一个简单的程序,这样就有一个 SSCCE
  • 由你决定,当然你不能那样做,因为问题描述得很好:-)
  • @Devon_C_Miller 我认为进度条对于我想做的事情来说有点太花哨了。我只是想显示一个字符串/标签。原因是,有时创建和加载表需要 100 毫秒而不是 15 秒以上

标签: java swing repaint jdialog


【解决方案1】:

1) I have a Gui which allows the user to click a button and view the contents of a text file.

  • 使用 CardLayout,如果您确实需要阻止或提供输入掩码以输入/修改/删除已显示或存在的值,我建议您创建另一个容器

2)The issue is that the file can be rather large (100,000+ rows of data) and can take upwards of 15 seconds to read and display in a table.

  • 除了内部修订,我不认识任何人,他们可能想要检查或处理 100k 行,使用 SwingWorker 将 FileIO 填充到 TableModel,并为 JTable 创建分页

3) //伪代码

动作执行{

create frame - 不是 JFrame re_use 现有的JDialog,当然更好的是CardLayout

display label that lets user know its creating table - 不知道就这样

read text file - 使用带有 JProgressBar 的 SwingWorker,转换数据并将其放入 TableModel,使用批​​处理更新 TableModel f.e。每 50 行,查找 JTable 的分页,然后您将只显示所需的行数,而不是 100k,这可能很疯狂:-)

create map and place values - 可能没用,因为您将所有必需的信息都存储在 TableModel 中

remove label - 不知道就这样

update dialog with table - Jtable 可以立即从 SwinWorker 更新,Swing GUI 可以访问所有鼠标或键盘输入,无需等待,也不会延迟 10-15 秒

}

【讨论】:

  • 我明白你为什么现在想要一个 SSCCE。我想我们互相误解了。我想知道的重要部分是如何在填充表格时添加/删除标签,然后将表格添加到对话框中,而不是在那里放置等待标签。 (当您发布答案时,我正在创建 SSCCE)
  • @WilliamShatner mKorbel 是正确的。您不应该通过在 EDT 上创建模型来阻止 UI 15 秒。 SwingWorker 的建议非常有效。如果您在打开对话框后立即开始在 EDT 上解码您的模型,我什至不确定您是否可以保证带有标签的 JDialog 将始终被绘制。如果您想切换到更动态的标签(比如进度条或旋转图标),您需要释放 EDT 以进行重绘。所以SwingWorker 是要走的路
  • @Robin 我并不是要暗示 mKorbel 一点也不正确。我只是想说明我的问题只是询问更新 JDialog 上显示的信息。 (用户可以在觉得耗时太长时关闭它)。 mKorbel 回答了很多我一定会研究和了解的事情。感谢您和 mKorbel 的建议。我仍在学习并不断寻求向那些已经克服了我每天遇到的简单编码问题的人学习
  • 在阅读了SwingWorker之后,我相信你们两个是对的。我必须在一个线程中执行此操作,以确保它更新没有任何问题。谢谢两位的建议! @AndrewThompson,当我更多地阅读罗宾所说的内容时,我删除了它。我做错了,我认为在查看更多示例后需要一个线程
  • @WilliamShatner 酷。希望对你来说一切顺利。 :) 如果您在实施时遇到任何问题,请向我们提出新问题。
【解决方案2】:

JDialogs 能够在其中保存组件,例如您正在谈论的表格。你可以简单地告诉用户你在做什么,使用JDialog's getContentPane方法添加/删除进度条和标签等组件,以便通知他们程序正在运行。

另外,如果我错了,请纠正我,但repaint() 通常是java.awt 软件包使用的方法,而不是javax.swing ...仅在某些情况下使用。

-- 另一个解决方案-- 您甚至可以在对话框打开之前告诉用户发生了什么。也许在 GUI 或进度条上有一个“当前状态”标签。当文件被完全读取并准备好使用时,您可以打开对话框并快速将值发布到表上。

【讨论】:

  • 我添加了一个编辑以显示我使用getContentPane() 方法尝试过的内容,但它只显示标签?是否需要在创建表后再次将对话框设置为可见?
  • 另外,您对repaint() 的看法可能是正确的,我只是在四处寻找可能使其发挥作用的方法。我也喜欢您的替代解决方案,并会记住它,以防我不得不采取这种方式
  • getContentPane().validate() 应该可以完成这项工作。它总是有助于查看 Java API。因为getContentPane() 返回一个Container,所以我查看了该特定类的API here
  • 在尝试了几次之后,我无法让它自动更新。我想我可能不得不按照 mKorbel 和 Robin 的建议在一个线程中完成它
【解决方案3】:

使用您的解决方案的最简单方法是在您的操作完成后执行label.setVisible(false)。当然,应该制作您的布局管理器(或其他良好的免费设计),以便在标签变得不可见时其他组件正确调整大小/重新定位。通常它应该自动发生。

还有其他方法可以做到,但你会花更多时间来制作它们。

【讨论】:

  • 我的问题是它没有在 JTable 准备好时添加它。我在问题的底部添加了一些代码作为我正在做的示例
  • @WilliamShatner 哦,是的,抱歉,我用 netbeans gui builder 制作 java GUI 应用程序已有 2 周了,但我忘记了除了 gui 之外还有其他东西-_-
猜你喜欢
  • 1970-01-01
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 2021-10-19
  • 1970-01-01
相关资源
最近更新 更多