2008-12-10 54 views
1

这里的基本思想是:的Java窗口缓冲击键,直到用户用鼠标点击

有一个java窗口(主)打开另一个Java窗口(子)。当创建了孩子,初始化的一部分设置在子窗口中相应的文本字段中的焦点:

childTextField.requestFocusInWindow(); 
childTextField.setCaretPosition(0); 

孩子一般是一个严重的按键通过命令行接口类型打开。当窗口被请求时,90%的时间,焦点正确地进入子窗口文本字段,并且用户可以在框中键入。如果打开孩子的命令被发送(按下回车键),并且用户在新窗口创建之前立即开始输入,则文本会被正确缓冲并在窗口打开后显示在新文本框中。

但是,每过一段时间,当用户请求的子窗口中打开,然后开始打字,他们的文本不显示在文本框中。只有在字段中用鼠标点击后,才会显示他们输入的文本。这就像它被存储在某个地方,直到点击它们才会出现。

真正令人沮丧的是,我似乎无法可靠地重现问题。它绝对会发生,但不够经常地调试很好。

当然还有各种其他的魔力会在幕后,其中包括与服务器应用程序的通信,但我不相信它的相关。

任何想法或想法将非常感激。

回答

0

首先看,这听起来像它可能是在实施中的错误;该键应与鼠标事件处于相同的事件队列中。还有另一个可能的问题:事件队列运行在与程序main分离的线程中;不知道应用程序的其他部分发生了什么,很容易想知道事件队列线程是否被阻塞了。

实际上,您在复制时遇到的困难使得该声音更有可能。

调试该案件需要一点技巧和诀窍。如果你在Solaris 10或OS/X上,我推荐使用dtrace;您可以轻松地在事件队列中放置一个跟踪点。如果没有,你可能想要另一个线程周期性地在事件队列中放置一些东西。

0

被封锁的事件队列线程听起来很可能。不幸的是,我在窗户上,所以没有跟踪,但我一定会更彻底地探索。

当然,其他任何可能有其他想法的人都会受到欢迎。

1

我有类似的问题。尝试添加后,您的init()

EventQueue.invokeLater(new Runnable() { 
    public void run() { 
     childtextfield.requestFocus(); 
     childTextField.setCaretPosition(0); 
    } 
}); 

这对我有用。

0

事实证明,答案并不是那么有趣。在您提到事件队列后,我再深入了解代码。事实证明,该应用程序有一个自定义的键盘焦点管理器。它会做一些事情,例如缓冲等待打开子窗口时输入的文本。在打开子窗口的代码中,它会调用一个函数(通过侦听器)来刷新缓冲区并将其显示在屏幕上。在那10%或更少的时间内,这不会发生。但是,同样的刷新功能也附加到文本字段内发生的鼠标点击。所以,你猜对了,它没有与窗口的开口齐平,而是在点击鼠标的时候。

感谢您的帮助...即使它不完全是解决方案,它绝对指出我在正确的方向。现在我只需要弄清为什么当窗口打开时flush函数并不总是被调用......

+0

没关系,那个几乎肯定是*是一个错误。我会尽早将焦点管理器或调用logger.info或类似的东西放到焦点管理器中,查看事件的真实情况,并浏览代码路径。可能性有一个意外的情况和不刷新的代码路径。 – 2008-12-14 18:40:25