1

我正在捕获JTextArea中的每个 keyPress并将其发送到聊天服务器,以让另一端的人知道用户正在输入。

目前我得到了这个:

sm.addKeyListener(new KeyAdapter() {
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            sendMsg(sm.getText(), "message", atName);
            sm.setText(null);
        } else { // Typing
            sendMsg("", "typing", atName);
        }
    }
});

这很好用,它会sendMsg("", "typing", atName);在每个按键上发送,除了Enter.

但是,这会稍微减慢服务器的速度。

为了不发送所有按键,我怎么能添加一个计时器或其他东西?

4

4 回答 4

2

您可以有一个标志来指示用户是否正在键入。然后你只能在他们第一次按键时发送一个“打字”消息。

boolean isTyping = false;

sm.addKeyListener(new KeyAdapter() {
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            sendMsg(sm.getText(), "message", atName);
            sm.setText(null);
            isTyping = false;
        } else { // Typing
            if (isTyping) {
                if (sm.getText().length() == 0) {
                    isTyping = false;
                    // Send a message indicating the user has stopped typing
                    sendMsg("", "stopTyping", atName); //Customize the message type here, may need to adjust the server
                }
            } else {
                isTyping = true;
                sendMsg("", "typing", atName);
            }
        }
    }
});
于 2013-09-01T21:14:40.337 回答
1

x如果用户正在键入,则创建一个每秒发送一次消息的新线程。

public void Updater implements Runnable {

    private volatile boolean typing;        

    public void typing() {
        typing = true;
    }

    public void run() {
        while (true) {
            if (typing) {
                 sendMsg(...);
                 typing = false;
            }
            Thread.sleep(x * 1000); // x - seconds
        }
    }
}

然后updater.typing()在按下键时调用。

于 2013-09-01T21:14:16.623 回答
0

1) 创建一个单独的线程,负责与服务器通信(如果服务器响应缓慢,这也有助于避免 GUI 冻结)。

2) 侦听器只是写入指示用户操作的队列(详细程度取决于您)。在最简单的情况下,它只是设置一个标志。

3)每隔 x 秒,线程读取队列/标志,重置它并发送消息(如果需要)。

或者,在您的侦听器中设置日期属性,每次发送消息时都会存储当前时间。每次事件到达时,如果没有经过足够的时间,它就会被忽略。更简单,但不太“精确”。此外,如果服务器响应缓慢,它将出现“GUI 冻结”问题。

于 2013-09-01T21:10:48.173 回答
0

将类型的成员变量添加long到侦听器(lastSent例如调用),以keyReleased计算与保存值之间的差异,System.currentTimeInMillis()并且仅在差异大于您的阈值时发送。请记住lastSent在实际发送内容时进行设置。

于 2013-09-01T21:11:38.040 回答