好的,我已经在网上搜索了所有内容,但还没有找到解决问题的方法,也许我缺少一些简单的东西,所以我在这里…
我有一个相当大的项目,处理维修业务的工单。它是所有与数据库连接的页面,其中包含许多页面的代码和类。但是我只是在前端添加了一小段代码,基本上检查了我们的注释区域中的新消息。
无论如何,我显示一个带有两个 JLabel 的简单 JFrame
,同时一个单独的线程查询数据库。所有这些都在程序开始时发生。问题是在等待期间(这是程序加载的其余部分,而不是数据库线程),我的小“请稍候” JFrame
出现了它的框架,但是没有胆量,没有背景,也没有 JLabel ,它显示了后缀,但是到那时,它已经失去了意义。 __
我编写了以下示例程序。它显示一个简单的 JFrame (CheckingMessagesGUI:一个带有两个 JLabel 的 JFrame
,仅此而已)睡眠5秒钟,然后显示Example(主程序) JFrame
,然后在此示例中立即关闭(),当然我的真实程序继续执行多很多。我发现这似乎是造成问题的原因。一旦睡眠计时器用完,将显示窗口,但是显示该代码的代码是在命令之前给出的,并且应该以正确的顺序执行吗?
System.exit(0)``invokeLater``Thread.sleep
我的问题是为什么invokeLater
导致我的 JFrame 无法正确显示?
我的理解invokeLater
是,这样做的目的是使项目在正确的AWT事件线程上运行,这使我认为此窗口将正确绘制。无论如何,我确定我缺少明显的东西。我invokeLater
在下面的代码中注释掉了该部分,它可以正确运行,如果将其放回原位,则不会…
提前谢谢了。
package javaapplication6;
public class Example extends javax.swing.JFrame {
public Example() {
System.out.println("Example started");
setBounds(100,100,200,200);
System.out.println("cmGUI instantiated");
CheckingMessagesGUI cmGUI = new CheckingMessagesGUI();
System.out.println("Set cmGUI visible");
cmGUI.setVisible(true);
cmGUI.validate();
try {
System.out.println("timer started");
Thread.sleep(5000);
System.out.println("timer done");
} catch(InterruptedException e){
}
System.exit(0);
}
public static void main(String[] args) {
/*java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() { */
System.out.println("Started");
System.out.println("example Instantiated");
Example example = new Example();
System.out.println("example visible");
example.setVisible(true);
/* }
});
*/
}
}
更新:为澄清起见,我意识到Thread.sleep()
将阻止所有内容,但是在调用sleep之前我的CheckingMessagesGUI是否应该已经完全绘制好了?这就是问题。
invokeLater在事件调度线程中运行Runnable,该线程也用于更新GUI。
您的睡眠正在阻塞此线程,因此GUI也不会得到 服务 ,直到您从invokeLater代码返回之前,无法进行任何更新。
这就是为什么您不应该在此线程中进行任何长时间(耗时的)计算的原因。它们应该在其他(新)线程中完成。
事件调度队列状态
事件分发线程上的任务必须快速完成;如果没有,则将备份未处理的事件,并且用户界面将无响应。
您的代码可以更改为(未经测试):
public Example(){
System.out.println("Example started");
setBounds(100,100,200,200);
System.out.println("cmGUI instantiated");
CheckingMessagesGUI cmGUI = new CheckingMessagesGUI();
System.out.println("Set cmGUI visible");
cmGUI.setVisible(true);
cmGUI.validate();
Thread thread = new Thread(new Runnable() {
try {
System.out.println("timer started");
Thread.sleep(5000);
System.out.println("timer done");
} catch(InterruptedException e) {
}
System.exit(0);
});
thread.start();
}
编辑:让我们更“深入”(这是我对Swing / AWT工作的看法)。
我想应该在CheckingMessagesGUI类中显示“请稍候”(请参阅注释),但不是。
这与GUI的工作方式有关。如果调用相应的(Swing)方法(draw,setText,setLocation等),它不会直接更改显示内容。它只是将事件在事件队列中排队。事件调度线程是(应该是)唯一读取此队列并处理事件的线程。只要它被阻止(在这种情况下为睡眠),就不会显示对GUI的更改。GUI被冻结。
EDIT2:
invokeLater
将Runnable 附加
到队列的末尾,以便在处理所有未决事件之后由EDT稍后执行,然后将执行invokeLater调用之后的下一个命令。
invokeAndWait
与上面相同,但是实际的线程会阻塞,直到EDT执行Runnable(在挂起事件之后)为止,也就是说,invokeAndWait之后的命令仅在提交的Runnable执行之后才启动。
问题内容: 由于某种原因,当我添加到优先级队列时,它不能完全按字母顺序对字符串进行排序,也无法理解原因。 这是添加到PriorityBlockingQueue的代码: 但是我没有得到完全排序的输出(只有前几行,但是您可以看到它没有排序): 这是预期输出文件中排序输出的实数(第一部分): 问题答案: 我怀疑您正在尝试迭代并打印元素。 请注意,优先级队列数据结构(AKA heap)不能保证排序- 它保
我很困惑。我有一个域类 ,其中包含两个 属性 和 ,以及一个用于创建新周期的相应控制器方法和模板。 问题:即使请求模型显然被正确地反序列化为具有两个正确的属性的实例,我仍然在中遇到错误,其中属性显然没有转换为,而是保留为s。验证失败,出现以下情况: 这是域类: 这是创建新周期的控制器方法: 这是百里香叶模板: 这是调试器在控制器中的处设置断点时告诉我的。显然,是一个实例,具有两个属性,每个属性都有
问题内容: 我正在做一个游戏,但是每当我运行第二个jFrame时,我都必须调整它的大小才能获得第二个jFrame的正确大小,有人知道为什么吗? 这是第一个jFrame类中的方法,它将打开第二个类: 这是第二个jFrame类,我必须重新调整它的大小才能正确显示山雀: 问题答案: 我读得很快,正在寻找一种特定的方法。 该方法是: JFrame中的此方法可能非常有用,但也很难处理,您需要非常了解如何设置
问题内容: 我已经尝试了两个类组件: 并使用功能组件: 页面上显示的x值永远不会改变,或者似乎是随机改变的。是什么赋予了? 问题答案: 当您告诉React某些更改时,React仅知道使用其为状态管理提供的功能来重新渲染: 另外,功能组件应该是 纯 组件(没有副作用),因此要更新它们,React会给我们带来麻烦: 因此,您不能只是分配给一个变量并期望React知道:您必须使用它的更新函数,以便它知道
问题内容: 所以我已经在Java编程学了一个学期左右的时间,而且我遇到了几次这个问题,最后才开始提出问题。 如果我做一个然后设置大小,例如。帧实际上并不长。据我所知,它实际上更长。另外,如果您将垂直尺寸设置得非常小(低于30),则框架甚至不会显示,只有操作系统顶部的窗口栏和框架才会变大,直到您将值超过30(这样看起来与)相同。为什么会这样,修复起来并不难,但是很奇怪,我很好奇为什么会这样? 如果您
我最近编写了一个包含背景图像的系统主页。设置背景后,我创建的按钮无法正确显示。它只是在我使用鼠标并指向按钮的位置后出现的。有人能教我如何解决这个问题吗?谢谢你的帮助。代码如下: 公共类主页扩展JFrame{