2013-02-17 43 views
4

我正在編程一個聊天客戶端在Java中,我想有一個單一的JDialog所有開放聊天。所以我決定使用一個JTabbedPane,其中一個標籤代表一次聊天。焦點JTextArea在JTabbedPane

我把一個JPanel放到每個標籤中,它只包含一個用於消息歷史的JTextPane和一個用戶輸入消息的JTextArea。

爲了更好的可用性我實現了一個功能,重點在

  1. 新ChatTab被打開ChatTabs(JTabbedPane的火災的ChangeListener)
之間
  • 用戶變化的JTextArea

    我有一個類ChatWindow,它擴展了JDialog並顯示JTabbedPane。這是我實現ChangeListener的地方。

    private JTabbedPane chatTabPane; 
    private List<ChatTab> chatTabs; 
    
    public ChatWindow() { 
        chatTabs = new ArrayList<ChatTab>(); 
    
        JPanel chatWindowPanel = new JPanel(new BorderLayout()); 
    
        chatTabPane = new JTabbedPane(JTabbedPane.TOP); 
        chatWindowPanel.add(chatTabPane); 
    
        this.add(chatWindowPanel, BorderLayout.CENTER); 
    
        chatTabPane.addChangeListener(new ChangeListener() { 
    
         @Override 
         public void stateChanged(ChangeEvent arg0) { 
          focusInputField(); 
         } 
        }); 
    } 
    
    public ChatTab addChatTab(Contact contact) { 
        ChatTab newChatTab = new ChatTab(); 
        chatTabs.add(newChatTab); 
        chatTabPane.addTab(contact.toString(), null, newChatTab.getPanel()); 
        return newChatTab; 
    } 
    
    public void focusInputField() { 
        for (ChatTab chatTab : chatTabs) { 
         if(chatTab.getPanel() == chatTabPane.getSelectedComponent()) { 
          chatTab.focusInputField(); 
         } 
        } 
    } 
    
    public JTabbedPane getChatTabs() { 
        return chatTabPane; 
    } 
    } 
    

    的方法focusInputField()在類ChatTab只是看起來是這樣的:

    public void focusInputField() { 
        inputField.requestFocusInWindow(); 
        inputField.requestFocus(); 
    } 
    

    好了,這就是對焦點,當標籤被改變。除此之外,我還實現了在創建新聊天標籤時關注JTextArea。這是在類ChatWindowController處理。有一種方法setChatVisible()我打電話的時候,我添加一個新的選項卡,將ChatWindow類:

    public void setChatVisible() { 
        if(!chatWindow.isVisible()) { 
         chatWindow.setVisible(true); 
    
         chatWindow.focusInputField(); 
        } 
    } 
    

    因此,這裏是我的問題:當我打開一個新的chattab的重點工作。在大多數情況下,當用戶更改選項卡時,它也可以工作,但是當我打開多個新的聊天選項卡並在「第一次」選項卡之間切換時,它不會集中。我切換到的標籤的JTextArea沒有關注。但是,當我再次切換時,它始終都能正常工作。

    有誰知道這個問題可能是什麼?我真的沒有想法。

  • 回答

    4

    不正確的同步可能導致間歇性故障。幾個東西應該嚴格審查:

    • 確認您構建移動event dispatch thread(EDT)所有GUI元素。

    • 由於您肯定使用多個線程,因此驗證所有更新都發生在EDT上,對於example

    • 您可以使用invokeLater()在EDT上訂購事件,如here所示。

    • 優選requestFocusInWindow()超過requestFocus(),但不要同時使用兩者。

    +1

    非常感謝!我不認爲美國東部時間可能是問題。使用EventQueue.invokeLater()在ChatTab類中調用focusInputField()方法解決了我的問題。 – 2013-02-17 17:36:45