2008-12-10 53 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