package org.buzztroll.mud; import java.util.StringTokenizer; import java.util.Hashtable; import java.util.Vector; import java.awt.*; import java.io.*; import java.text.*; import java.net.*; import java.awt.event.*; import java.awt.datatransfer.*; import javax.swing.*; import javax.swing.text.*; import javax.swing.event.*; import javax.swing.border.*; import com.ozten.font.JFontChooser; public class MudChatWindow extends JFrame implements MudConnectionListener { private static final String PAGES = " pages, "; private static final String SAYS = " [to you]: "; private static final String WHISPER = " whispers to you, "; private static final String FROM = "(from "; protected JPopupMenu menu; protected JMenuItem pasteMenu; protected TextDisplay display; protected EmacsTextBox commandText; private JRadioButton privateReplyCB; private JRadioButton publicReplyCB; private Color peerColor = Color.red; private Color selfColor = Color.green; private MudConnection connection; private String who = null; private int whoLen; private String self = null; public MudChatWindow(MudConnection connection, String self, String peer, ConfigFrame configFrame) { super("Chat - [" + peer + "]"); this.connection = connection; this.connection.addListener(this); this.who = peer; this.whoLen = who.length(); this.self = self; this.display = new TextDisplay(configFrame); this.display.addMouseListener(new ChatMouseListener()); this.commandText = new EmacsTextBox(); this.commandText.addKeyListener(new ChatKeyListener()); this.commandText.setRows(1); this.commandText.setBorder(new EtchedBorder()); this.commandText.setLineWrap(true); this.commandText.setWrapStyleWord(true); this.getContentPane().setLayout(new BorderLayout()); this.getContentPane().add("Center", this.display); this.getContentPane().add("South", this.commandText); this.addWindowListener(new ChatWindowListener(this)); this.menu = new JPopupMenu("BuzzTroll Chat"); this.pasteMenu = menu.add("Paste"); this.pasteMenu.addActionListener(new ChatActionListener()); JMenu typeMenu = new JMenu("Reply"); this.privateReplyCB = new JRadioButton("Private"); this.publicReplyCB = new JRadioButton("Public"); typeMenu.add(this.privateReplyCB); typeMenu.add(this.publicReplyCB); ButtonGroup group = new ButtonGroup(); group.add(this.privateReplyCB); group.add(this.publicReplyCB); this.menu.add(typeMenu); this.menu.addSeparator(); this.menu.add("Dismiss"); this.peerColor = configFrame.namePanel.getColor(peer); this.selfColor = configFrame.namePanel.getSelfColor(); this.privateReplyCB.setSelected(true); this.commandText.grabFocus(); } public void disconnected() { display.addMessage(new DisplayMessage("Connection broken", Color.red, null)); } public void messageReceived(String message) { if (message == null) { return; } String msg = null; if (message.regionMatches(true, 0, who, 0, whoLen)) { if (message.regionMatches(true, whoLen, PAGES, 0, PAGES.length())) { msg = message.substring(whoLen + PAGES.length() + 1, message.length()-1); } else if (message.regionMatches(true, whoLen, SAYS, 0, SAYS.length())) { msg = message.substring(whoLen + SAYS.length()); } else if (message.regionMatches(true, whoLen, WHISPER, 0, WHISPER.length())) { msg = message.substring(whoLen + WHISPER.length() + 1, message.length()-1); } else { return; } } else if (message.startsWith(FROM)) { int pos = message.indexOf(')', FROM.length()); if (pos == -1) { return; } if (message.regionMatches(true, pos+2, who, 0, whoLen)) { msg = message.substring(pos+2+whoLen+1); } else { return; } } else { return; } msg = who + ": " + msg; this.display.addMessage(new DisplayMessage(msg, peerColor, null)); commandText.grabFocus(); } public void connectTic() {} class ChatKeyListener implements KeyListener { public void keyPressed(KeyEvent ke) {} public void keyReleased(KeyEvent ke) {} public void keyTyped(KeyEvent ke) { if( ke.getKeyChar() == '\n') { String msg = commandText.getRawText(); if (msg.length() == 0) { return; } if (privateReplyCB.isSelected()) { connection.sendLine("page " + who + " " + msg); } else { connection.sendLine(who + ", " + msg); } commandText.setText(""); display.addMessage(new DisplayMessage(self + ": " + msg, selfColor, null)); } } } class ChatWindowListener extends WindowAdapter { MudChatWindow window; public ChatWindowListener(MudChatWindow window) { this.window = window; } public void windowClosing(WindowEvent we) { connection.removeListener(this.window); this.window.dispose(); } } class ChatActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (e.getSource() == pasteMenu) { Clipboard clipboard = getToolkit().getSystemClipboard(); Transferable data = clipboard.getContents(this); if(data == null || !data.isDataFlavorSupported (DataFlavor.stringFlavor)) { return; } String strData = null; try { strData = (String)data.getTransferData(DataFlavor.stringFlavor); } catch (Exception ex) { System.err.println(ex.getMessage()); return; } StringBuffer buf = new StringBuffer(); buf.append("@pasteto ").append(who).append("\n"); buf.append(strData); buf.append("\n.\n"); connection.sendLine(buf.toString()); } } } class ChatMouseListener extends MouseAdapter { public void mouseClicked(MouseEvent e) { if ( ((e.getModifiers() & InputEvent.BUTTON2_MASK) != 0) || ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) ) { // TBD: disable paste button if nothing in clipboard // just like in MudClient.java menu.show(e.getComponent(), e.getX(), e.getY()); } else { commandText.grabFocus(); } } } }