Java でチャット クライアントをプログラミングしていますが、開いているすべてのチャットに対して 1 つの JDialog を使用したいと考えています。そこで、タブが 1 つのチャットを表す JTabbedPane を使用することにしました。
すべてのタブに JPanel を配置しました。これには、メッセージ履歴用の JTextPane と、ユーザーがメッセージを入力する JTextArea が含まれています。
使いやすさを向上させるために、JTextArea にフォーカスする機能を実装しました。
- 新しい ChatTab が開かれます
- ユーザーが ChatTabs 間で変更されます (JTabbedPane の ChangeListener が起動します)。
JDialog を拡張して JTabbedPane を表示するクラスChatWindowがあります。これは、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;
}
}
ChatTabクラスの focusInputField() メソッドは、単純に次のようになります。
public void focusInputField() {
inputField.requestFocusInWindow();
inputField.requestFocus();
}
さて、それはタブが変更されたときのフォーカスです。それに加えて、新しいチャット タブが作成されたときに JTextArea がフォーカスされるようにも実装しました。これはクラスChatWindowControllerで処理されます。ChatWindowクラスに新しいタブを追加するときに呼び出すメソッドsetChatVisible()があります。
public void setChatVisible() {
if(!chatWindow.isVisible()) {
chatWindow.setVisible(true);
chatWindow.focusInputField();
}
}
ここに私の問題があります。新しいチャットタブを開くとフォーカスが機能します。ほとんどの場合、ユーザーがタブを変更したときにも機能しますが、複数の新しいチャット タブを開いて初めてタブを切り替えると、フォーカスしません。切り替え先のタブの JTextArea がフォーカスされません。ただし、もう一度切り替えると、常に機能します。
問題が何であるかを知っている人はいますか?私は本当にアイデアがありません。