为什么会造成的invokeLater我的JFrame不能正确显示? [英] Why does InvokeLater cause my JFrame not to display correctly?

查看:114
本文介绍了为什么会造成的invokeLater我的JFrame不能正确显示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我读过的一个搜索所有网站上,我也没有找到解决我的问题呢,也许我失去了一些东西简单,所以我在这里...

Ok I've read an searched all over the web, and I've not found the solution to my problem yet, perhaps I'm missing something simple, hence here I am...

我有一个相当大的项目,处理工作单的维修业务。这是code以及类的所有数据库连接,许多许多网页。但我只是说code的短位到前端,基本上检查我们的笔记领域的新信息。

I've got a rather large project, that handles work orders for a repair business. It's all database connected, many many pages of code, and classes. But i just added a short bit of code to the front end that essentially checks for new messages in our notes area.

反正我显示一个简单的的JFrame 的有两个* *的JLabel s,而一个独立的线程查询数据库。这一切发生在节目的开始。问题是我的小请稍候的的JFrame 的出现有它的框架,但没有胆量,没有背景,没有*的JLabel * S,在等待期间(这是程序加载的其余部分,不数据库线程),后记它显示,但那时它缺少了点。

Anyway, I display a simple JFrame with two *JLabel*s while a separate thread queries the database. This all happens at the start of the program. The problem is my little "please wait" JFrame comes up with its frame but no guts, no background, and no *JLabel*s, during the wait (which is the rest of the program loading, not the database thread), afterwords it displays, but by then its missing its point.

我写了下面的示例程序。它显示了一个简单的的JFrame 的(CheckingMessagesGUI:一个的的JFrame 的有两个*的JLabel * S,仅此而已),休眠5秒然后显​​示示例(主程序)的的JFrame 的,然后立即关闭( System.exit(0))在这个例子中,当然,我的真正的程序接着做更多。我发现的是,的invokeLater 似乎是造成问题的原因。一旦睡眠定时器冲出窗口将显示,但code,以显示它是在视频下载命令之前给定的,并且应该按照这个顺序做了是否正确?

I wrote the following example program. It displays a simple JFrame (CheckingMessagesGUI: a JFrame with two *JLabel*s, nothing more) sleeps for 5 sec then displays the Example (main program) JFrame, then instantly closes (System.exit(0)) in this example, of course my real program goes on to do a lot more. What I found is that invokeLater seems to be causing the problem. Once the sleep timer runs out the window will display, but the code to display it was given before the Thread.sleep command, and should have been done in that order correct?

我的问题是为什么的invokeLater 原因我的的JFrame 的不正确显示?

My question is why does invokeLater cause my JFrame not to display correctly?

它我的理解是的invokeLater 的目的是使该项目正确的AWT事件线程,这让我觉得,这个窗口会得到正确地绘制上运行。无论如何,我敢肯定,我失去了一些东西明显。我注释掉下面的code中的的invokeLater 部分,它运行正确,如果你把它放回它不...

Its my understanding that the purpose of invokeLater is so that the items run on the correct AWT event thread, which would make me think that this window would get painted correctly. Anyway I'm sure I'm missing something obvious. I commented out the invokeLater part in the code below, and it runs correctly, if you put it back it doesn't...

提前非常感谢。

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);
        /*      }
        });
        */
    }
}

更新:
为了澄清,我意识到视频下载()将阻止一切,但应该不是我的CheckingMessagesGUI已经被完全绘制之前,我打电话睡觉了吗?这是问题。

UPDATE: To clarify, I realize Thread.sleep() will block everything, but shouldn't my CheckingMessagesGUI already have been fully drawn before I call sleep? That is the issue.

推荐答案

的invokeLater运行中也用于更新GUI中的事件指派线程了Runnable。结果
你的睡眠阻止此主题所以也GUI没有得到的服务的,没有更新可以做,直到你从的invokeLater code返回。结果
这就是为什么你不应该在这个主题做任何长(耗时)计算。他们应该在不同的(新)线程来完成。

invokeLater runs the Runnable in the Event Dispatch Thread which also is used for updating the GUI.
Your sleep is blocking this Thread so the GUI also does not get serviced, no updates can be done till you return from the invokeLater code.
That's why you should not do any long (time consuming) computations in this Thread. They should be done in an different (new) Thread.

事件调度队列状态

事件调度线程必须迅速完成任务上;如果他们不这样做,未处理事件备份和用户界面变得无法响应。

Tasks on the event dispatch thread must finish quickly; if they don't, unhandled events back up and the user interface becomes unresponsive.

您code可以更改为(未测试):

Your code could be changed to (not tested):

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

编辑:
让我们有点更深(和它的我的挥杆的工作/ AWT的视图)。结果
我想在请稍候(见注释)应显示在CheckingMessagesGUI类,但并非如此。结果
这是关系到GUI的工作方式。它不直接在显示器上改变任何东西,如果你调用相应的(摇摆)的方法(平局,的setText,的setLocation,...);它只是在排队事件队列事件。事件调度线程是(应该是)读取此队列和处理事件的唯一主题。只要它被阻止 - 在这种情况下,睡眠 - 将显示到GUI中没有改变。该GUI被冻结。

let's go a bit "deeper" (and it's my view of the working of Swing/AWT).
I suppose the "please wait" (see comments) should be displayed in the CheckingMessagesGUI class, but isn't.
That's related to the way the GUI works. It does not directly change anything on the display if you call the corresponding (Swing) methods (draw, setText, setLocation, ...); it just queues an Event in the Event Queue. The Event Dispatch Thread is (should be) the only Thread that reads this queue and process the events. As long as it is being blocked - by the sleep in this case - no changes to the GUI will be displayed. The GUI is frozen.

EDIT2:结果
的invokeLater 了Runnable是的的队列是后者的所有悬而未决的事件后,由EDT执行的到底有没有被处理,接下来的命令后该电话的invokeLater将被执行。结果
如上但实际线程阻塞,直到Runnable接口是由EDT(未完成的事件后)执行 invokeAndWait 一样的,那就是,继invokeAndWait该命令将只得到后开始提交的Runnable被执行了。


invokeLater the Runnable is appended to the end of the queue to be latter executed by the EDT after all pending events have been processed, the next command after the invokeLater call will be executed.
invokeAndWait same as above but the actual Thread blocks until the Runnable was executed (after pending events) by the EDT, that is, the command following the invokeAndWait will only get started after the submitted Runnable was executed.

这篇关于为什么会造成的invokeLater我的JFrame不能正确显示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆