2013-02-17 4 views
4

Java로 채팅 클라이언트를 프로그래밍 중입니다. 열려있는 모든 채팅에 대해 하나의 JDialog를 갖고 싶습니다. 그래서 탭이 단일 채팅을 나타내는 JTabbedPane으로 작업하기로 결정했습니다.JTabbedPane에서 JTextArea에 초점 맞추기

모든 탭에 JPanel을 넣습니다.이 탭에는 메시지 기록에 대한 JTextPane과 사용자가 메시지를 입력하는 JTextArea가 포함되어 있습니다. 더 나은 유용성

나는 새로운 ChatTab가 ChatTabs (JTabbedPane의 화재의 ChangeListener의) 사이

  • 사용자 변경 열립니다

    1. JTextArea에 초점을 맞추고있는 기능을 구현

      클래스 ChatWindow이 JDialog를 확장하고 JTabbedPane을 표시합니다. 이것이 ChangeListener를 구현 한 곳입니다. 클래스 ChatTab에서

      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()은 단순히 다음과 같습니다

      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 요소를 구성하는지 확인합니다.

    • 확실하게 다중 스레드를 사용하고 있으므로 example에 대해 모든 업데이트가 EDT에서 발생하는지 확인하십시오.

    • here과 같이 invokeLater()을 사용하여 EDT에서 이벤트를 정렬 할 수 있습니다.

    • requestFocusInWindow()requestFocus() 이상으로 지정하지만 둘 다 사용하지 마십시오.

    +1

    정말 고마워요! EDT가 문제가 될 수 있다고 생각하지 않았습니다. EventQueue.invokeLater()를 사용하여 ChatTab 클래스의 focusInputField() 메서드를 호출하면 문제가 해결됩니다. –