I am capturing each keyPress within a JTextArea and sending it off to the chatserver to let the person on the other end know that the user is typing.

Currently I got this:

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);
        }
    }
});

This works fine it sends sendMsg("", "typing", atName); on each keypress except for Enter.

However this is slowing down the server a bit.

How could i add a timer or something to this in order not to send exactly all keypresses?

有帮助吗?

解决方案

You could have a flag which would indicate if the user was typing. Then you could only send one "typing" message, the first time they press a key.

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);
            }
        }
    }
});

其他提示

Make a new thread that sends a message once per x seconds if a user is typing.

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
        }
    }
}

Then call updater.typing() whenever key is pressed.

1) Create a separate thread that will be in charge of communicating with the server (this also helps avoiding GUI freezes if the server is slow answering).

2) The listener just writes to a queue indicating the user action (the level of detail is up to you). In the simplest case, it just sets a flag.

3) Every x seconds, the thread reads the queue/flag, resets it and sends the message (if needed).

Alternatively, set a date attribute in your listener, and every time you send a message the current time is stored. Every time an event arrives, if there has not passed enough time, it simply gets ignored. Simpler, but less "precise". Also, it will have "GUI frozen" issues if the server is slow answering.

Add a member variable of type long to the listener (called lastSent for instance), in keyReleased compute the difference between System.currentTimeInMillis() and the saved value and only send when the difference is greater than your threshold. Remember to set lastSent whenever you actually send something.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top