From fd8213fe61e368ce6c4ffa1b47cf127196f1c700 Mon Sep 17 00:00:00 2001 From: Yana Stamcheva Date: Mon, 22 May 2006 09:19:45 +0000 Subject: [PATCH] send typing notification events when user is typing --- .../communicator/impl/gui/main/MainFrame.java | 14 ++ .../impl/gui/main/message/ChatWritePanel.java | 154 +++++++++++++----- 2 files changed, 123 insertions(+), 45 deletions(-) diff --git a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java index a68bdcb28..9c4527f09 100755 --- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java @@ -73,6 +73,8 @@ public class MainFrame extends JFrame { private Hashtable protocolProviders = new Hashtable(); private Hashtable imOperationSets = new Hashtable(); + + private Hashtable tnOperationSets = new Hashtable(); private MetaContactListService contactList; @@ -246,6 +248,12 @@ else if(key.equals(OperationSetBasicInstantMessaging.class.getName()) else if(key.equals(OperationSetTypingNotifications.class.getName())){ OperationSetTypingNotifications tn = (OperationSetTypingNotifications)value; + + this.tnOperationSets.put(protocolProvider, tn); + + //Add to all typing notification operation sets the Message + //listener implemented in the ContactListPanel, which handles + //all received messages. tn.addTypingNotificationsListener (this.getTabbedPane().getContactListPanel()); } @@ -326,6 +334,12 @@ public String getDefaultAccount(ProtocolProviderService protocolProvider){ this.imOperationSets.get(protocolProvider); } + public OperationSetTypingNotifications getTypingNotifications + (ProtocolProviderService protocolProvider){ + return (OperationSetTypingNotifications) + this.tnOperationSets.get(protocolProvider); + } + /** * Returns the main tabbed pane containing the contactlist, call list etc. * @return MainTabbedPane The main tabbed pane containing the diff --git a/src/net/java/sip/communicator/impl/gui/main/message/ChatWritePanel.java b/src/net/java/sip/communicator/impl/gui/main/message/ChatWritePanel.java index 1933ff511..ec773febf 100755 --- a/src/net/java/sip/communicator/impl/gui/main/message/ChatWritePanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/message/ChatWritePanel.java @@ -11,32 +11,47 @@ import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; import javax.swing.BorderFactory; +import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JScrollPane; +import javax.swing.Timer; + import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; +import net.java.sip.communicator.impl.gui.main.StatusSelectorBox; import net.java.sip.communicator.impl.gui.utils.AntialiasingManager; import net.java.sip.communicator.impl.gui.utils.Constants; +import net.java.sip.communicator.impl.gui.utils.ImageLoader; +import net.java.sip.communicator.service.protocol.OperationSetTypingNotifications; +import net.java.sip.communicator.util.Logger; public class ChatWritePanel extends JScrollPane - implements UndoableEditListener { + implements UndoableEditListener, KeyListener { + + private Logger logger = Logger.getLogger(ChatWritePanel.class); private JEditorPane editorPane = new JEditorPane(); private UndoManager undo = new UndoManager(); - private ChatPanel chatPanel; - + private ChatPanel chatPanel; + private TypingTimer typingTimer = new TypingTimer(); + + private int typingState = -1; + public ChatWritePanel (ChatPanel chatPanel){ super(); @@ -49,10 +64,9 @@ public ChatWritePanel (ChatPanel chatPanel){ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); this.editorPane.getDocument().addUndoableEditListener(this); + this.editorPane.addKeyListener(this); - this.enableKeyboardEvents(); - - this.getViewport().add(editorPane, BorderLayout.CENTER); + this.getViewport().add(editorPane, BorderLayout.CENTER); this.getVerticalScrollBar().setUnitIncrement(30); } @@ -68,44 +82,14 @@ public void paint(Graphics g){ g2.setColor(Constants.MSG_WINDOW_BORDER_COLOR); g2.setStroke(new BasicStroke(1.5f)); - g2.drawRoundRect(3, 3, this.getWidth() - 4, this.getHeight() - 4, 8, 8); - + g2.drawRoundRect(3, 3, this.getWidth() - 4, + this.getHeight() - 4, 8, 8); } public JEditorPane getEditorPane() { return editorPane; } - private void enableKeyboardEvents(){ - - this.editorPane.addKeyListener(new KeyAdapter(){ - public void keyPressed(KeyEvent e){ - if ((e.getModifiers() & KeyEvent.CTRL_MASK) == KeyEvent.CTRL_MASK && - (e.getKeyCode() == KeyEvent.VK_ENTER)){ - - JButton sendButton = chatPanel.getSendPanel().getSendButton(); - - sendButton.requestFocus(); - sendButton.doClick(); - } - else if ((e.getModifiers() & KeyEvent.CTRL_MASK) == KeyEvent.CTRL_MASK && - (e.getKeyCode() == KeyEvent.VK_Z)){ - - if(undo.canUndo()){ - undo(); - } - } - else if ((e.getModifiers() & KeyEvent.CTRL_MASK) == KeyEvent.CTRL_MASK && - (e.getKeyCode() == KeyEvent.VK_R)){ - - if(undo.canRedo()){ - redo(); - } - } - } - }); - } - public void undoableEditHappened(UndoableEditEvent e) { //Remember the edit this.undo.addEdit(e.getEdit()); @@ -114,18 +98,98 @@ public void undoableEditHappened(UndoableEditEvent e) { private void undo() { try { undo.undo(); - } catch (CannotUndoException ex) { - System.out.println("Unable to undo: " + ex); - ex.printStackTrace(); + } catch (CannotUndoException e) { + logger.error("Unable to undo.", e); } } private void redo() { try { undo.redo(); - } catch (CannotRedoException ex) { - System.out.println("Unable to redo: " + ex); - ex.printStackTrace(); + } catch (CannotRedoException e) { + logger.error("Unable to redo.", e); } - } + } + + public void keyTyped(KeyEvent e){ + + } + + public void keyPressed(KeyEvent e){ + if ((e.getModifiers() & KeyEvent.CTRL_MASK) == KeyEvent.CTRL_MASK && + (e.getKeyCode() == KeyEvent.VK_ENTER)){ + stopTyping(); + + JButton sendButton = chatPanel.getSendPanel().getSendButton(); + + sendButton.requestFocus(); + sendButton.doClick(); + } + else if ((e.getModifiers() & KeyEvent.CTRL_MASK) == KeyEvent.CTRL_MASK && + (e.getKeyCode() == KeyEvent.VK_Z)){ + + if(undo.canUndo()){ + undo(); + } + } + else if ((e.getModifiers() & KeyEvent.CTRL_MASK) == KeyEvent.CTRL_MASK && + (e.getKeyCode() == KeyEvent.VK_R)){ + + if(undo.canRedo()){ + redo(); + } + } + else{ + if(typingState != OperationSetTypingNotifications.STATE_TYPING){ + typingTimer.setDelay(2*1000); + typingState = OperationSetTypingNotifications.STATE_TYPING; + chatPanel.getTnOperationSet() + .sendTypingNotification(chatPanel.getProtocolContact(), + typingState); + } + + if(!typingTimer.isRunning()){ + typingTimer.start(); + } + else{ + typingTimer.restart(); + } + } + } + + public void keyReleased(KeyEvent e){ + } + + private class TypingTimer extends Timer { + + public TypingTimer(){ + //Set the initial delay + super(2*1000, null); + + this.addActionListener(new TimerActionListener()); + } + + private class TimerActionListener implements ActionListener { + public void actionPerformed(ActionEvent e){ + if(getDelay() == 2*1000){ + chatPanel.getTnOperationSet() + .sendTypingNotification(chatPanel.getProtocolContact(), + OperationSetTypingNotifications.STATE_PAUSED); + typingState = OperationSetTypingNotifications.STATE_PAUSED; + setDelay(3*1000); + } + else{ + stopTyping(); + } + } + } + } + + public void stopTyping(){ + chatPanel.getTnOperationSet() + .sendTypingNotification(chatPanel.getProtocolContact(), + OperationSetTypingNotifications.STATE_STOPPED); + typingState = OperationSetTypingNotifications.STATE_STOPPED; + typingTimer.stop(); + } }