【问题标题】:Focusing a JTextArea in a JTabbedPane在 JTabbedPane 中聚焦 JTextArea
【发布时间】:2013-02-17 15:27:49
【问题描述】:

我正在用 Java 编写一个聊天客户端,我希望有一个 JDialog 用于所有打开的聊天。所以我决定使用 JTabbedPane,其中一个选项卡代表一个聊天。

我在每个选项卡中都放了一个 JPanel,它只包含一个用于消息历史记录的 JTextPane 和一个用户输入消息的 JTextArea。

为了更好的可用性,我实现了一个功能,当

  1. 新的 ChatTab 已打开
  2. 用户在 ChatTab 之间切换(JTabbedPane 的 ChangeListener 触发)

我有一个类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;
}
}

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 没有焦点。但是,当我再次切换时,它一直有效。

有谁知道问题出在哪里?我真的没有想法。

【问题讨论】:

    标签: java swing focus jtabbedpane changelistener


    【解决方案1】:

    不正确的同步可能会导致间歇性故障。应该批判性地检查几件事:

    • 验证您在 event dispatch thread (EDT) 上构造了所有 GUI 元素。

    • 由于您肯定在使用多个线程,因此请验证所有更新都发生在 EDT 上,example

    • 您可以使用invokeLater() 对EDT 上的事件进行排序,如图here

    • 首选requestFocusInWindow() 而不是requestFocus(),但不要同时使用两者。

    【讨论】:

    • 非常感谢!我不认为 EDT 可能是问题所在。使用 EventQueue.invokeLater() 在 ChatTab 类中调用 focusInputField() 方法解决了我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-01
    • 2014-06-03
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    相关资源
    最近更新 更多