[client] new chat

This commit is contained in:
magenoxx 2011-06-14 21:08:38 +04:00
parent 8f971f28b9
commit 2a7b412a8c
9 changed files with 281 additions and 69 deletions

View file

@ -39,14 +39,19 @@ import java.awt.event.KeyEvent;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.components.ColorPane;
import mage.remote.Session; import mage.remote.Session;
import mage.view.ChatMessage.MessageColor; import mage.view.ChatMessage.MessageColor;
import org.jdesktop.swingx.graphics.ColorUtilities;
import sun.plugin2.gluegen.runtime.CPU;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com, nantuko
*/ */
public class ChatPanel extends javax.swing.JPanel { public class ChatPanel extends javax.swing.JPanel {
@ -56,19 +61,73 @@ public class ChatPanel extends javax.swing.JPanel {
private List<String> players = new ArrayList<String>(); private List<String> players = new ArrayList<String>();
private TableModel tableModel; private TableModel tableModel;
/**
* Chat message color for opponents.
*/
private static final Color OPPONENT_COLOR = Color.RED;
/**
* Chat message color for client player.
*/
private static final Color MY_COLOR = Color.GREEN;
/**
* Chat message color for timestamps.
*/
private static final Color TIMESTAMP_COLOR = new Color(255, 255, 0, 120);
/**
* Chat message color for messages.
*/
private static final Color MESSAGE_COLOR = Color.white;
/**
* This will be a chat that will be connected to {this} and will handle redirected messages;
* Mostly used to redirect user messages to another window.
*/
private ChatPanel connectedChat;
/**
* Parent chat this chat connected to.
* Used to send messages using parent chat as it is the only one connected to server.
*/
private ChatPanel parentChatRef;
/**
* Selected extended view mode.
*/
private VIEW_MODE extendedViewMode = VIEW_MODE.NONE;
public enum VIEW_MODE {
NONE, GAME, CHAT
}
/**
* Maps message colors to {@link Color}.
*/
private static final Map<MessageColor, Color> colorMap = new HashMap<MessageColor, Color>();
static {
colorMap.put(MessageColor.BLACK, Color.black);
colorMap.put(MessageColor.GREEN, Color.green);
colorMap.put(MessageColor.ORANGE, Color.orange);
colorMap.put(MessageColor.BLUE, Color.blue);
colorMap.put(MessageColor.RED, Color.red);
}
/** Creates new form ChatPanel */ /** Creates new form ChatPanel */
public ChatPanel() { public ChatPanel() {
this(false); this(false);
} }
/** /**
* @param extendedView if true, adds chat/players tabs * @param addPlayersTab if true, adds chat/players tabs
*/ */
/** Creates new form ChatPanel */ /** Creates new form ChatPanel */
public ChatPanel(boolean extendedView) { public ChatPanel(boolean addPlayersTab) {
tableModel = new TableModel(); tableModel = new TableModel();
initComponents(); initComponents();
if (!extendedView) simplifyComponents(); if (!addPlayersTab) simplifyComponents();
} }
public void connect(UUID chatId) { public void connect(UUID chatId) {
@ -84,26 +143,55 @@ public class ChatPanel extends javax.swing.JPanel {
session.leaveChat(chatId); session.leaveChat(chatId);
} }
public void receiveMessage(String message, MessageColor color) { /**
switch (color) { * Display message in the chat.
case BLACK: * Use different colors for timestamp, username and message.
this.txtConversation.setForeground(Color.BLACK); *
break; * @param username message sender
case RED: * @param message message itself
this.txtConversation.setForeground(Color.RED); * @param time timestamp
break; * @param color Preferred color. Not used.
case GREEN: */
this.txtConversation.setForeground(Color.GREEN); public void receiveMessage(String username, String message, String time, MessageColor color) {
break; if (extendedViewMode.equals(VIEW_MODE.GAME)) {
case BLUE: this.txtConversation.append(TIMESTAMP_COLOR, time + " ");
this.txtConversation.setForeground(Color.BLUE); this.txtConversation.append(MESSAGE_COLOR, (username.isEmpty() ? "" : username + ":") + message + "\n");
break; } else {
case ORANGE: this.txtConversation.append(TIMESTAMP_COLOR, time + " ");
this.txtConversation.setForeground(Color.ORANGE); Color userColor;
break; if (parentChatRef != null) {
userColor = parentChatRef.session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
} else {
userColor = session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
} }
this.txtConversation.append(message + "\n"); this.txtConversation.append(userColor, username + ": ");
txtConversation.setCaretPosition(txtConversation.getText().length() - 1); this.txtConversation.append(MESSAGE_COLOR, message + "\n");
}
}
public ChatPanel getConnectedChat() {
return connectedChat;
}
public void setConnectedChat(ChatPanel connectedChat) {
this.connectedChat = connectedChat;
}
public void setParentChat(ChatPanel parentChatRef) {
this.parentChatRef = parentChatRef;
}
public void disableInput() {
this.txtMessage.setVisible(false);
}
public void useExtendedView(VIEW_MODE extendedViewMode) {
this.extendedViewMode = extendedViewMode;
this.txtConversation.setExtBackgroundColor(new Color(0,0,0,100));
this.txtConversation.setBackground(new Color(0,0,0,0));
this.txtConversation.setForeground(new Color(255,255,255));
this.jScrollPane1.setOpaque(false);
this.jScrollPane1.getViewport().setOpaque(false);
} }
class TableModel extends AbstractTableModel { class TableModel extends AbstractTableModel {
@ -169,7 +257,9 @@ class TableModel extends AbstractTableModel {
txtMessage = new javax.swing.JTextField(); txtMessage = new javax.swing.JTextField();
jTabbedPane1 = new javax.swing.JTabbedPane(); jTabbedPane1 = new javax.swing.JTabbedPane();
jScrollPane1 = new javax.swing.JScrollPane(); jScrollPane1 = new javax.swing.JScrollPane();
txtConversation = new javax.swing.JTextArea(); //txtConversation = new JTextArea();
txtConversation = new ColorPane();
//txtConversation = new JTextPane();
jScrollPane2 = new javax.swing.JScrollPane(); jScrollPane2 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable(); jTable1 = new javax.swing.JTable();
@ -181,13 +271,17 @@ class TableModel extends AbstractTableModel {
jTabbedPane1.setTabPlacement(javax.swing.JTabbedPane.BOTTOM); jTabbedPane1.setTabPlacement(javax.swing.JTabbedPane.BOTTOM);
txtConversation.setColumns(20); //txtConversation.setColumns(20);
txtConversation.setEditable(false); txtConversation.setOpaque(false);
txtConversation.setFont(new java.awt.Font("Arial", 0, 10)); //txtConversation.setEditable(false);
txtConversation.setLineWrap(true); txtConversation.setFont(new java.awt.Font("Arial", 0, 14));
txtConversation.setRows(5); //txtConversation.enableInputMethods(false);
txtConversation.setWrapStyleWord(true); //txtConversation.setLineWrap(true);
//txtConversation.setRows(5);
//txtConversation.setWrapStyleWord(true);
jScrollPane1.setViewportView(txtConversation); jScrollPane1.setViewportView(txtConversation);
jScrollPane1.setBorder(new EmptyBorder(0,0,0,0));
jTabbedPane1.addTab("chat", jScrollPane1); jTabbedPane1.addTab("chat", jScrollPane1);
@ -238,7 +332,11 @@ class TableModel extends AbstractTableModel {
private void txtMessageKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtMessageKeyTyped private void txtMessageKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtMessageKeyTyped
if (evt.getKeyChar() == KeyEvent.VK_ENTER) { if (evt.getKeyChar() == KeyEvent.VK_ENTER) {
if (parentChatRef != null) {
parentChatRef.session.sendChatMessage(parentChatRef.chatId, this.txtMessage.getText());
} else {
session.sendChatMessage(chatId, this.txtMessage.getText()); session.sendChatMessage(chatId, this.txtMessage.getText());
}
this.txtMessage.setText(""); this.txtMessage.setText("");
this.txtMessage.repaint(); this.txtMessage.repaint();
} }
@ -278,7 +376,8 @@ class TableModel extends AbstractTableModel {
private javax.swing.JScrollPane jScrollPane2; private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTabbedPane jTabbedPane1; private javax.swing.JTabbedPane jTabbedPane1;
private javax.swing.JTable jTable1; private javax.swing.JTable jTable1;
private javax.swing.JTextArea txtConversation; //private javax.swing.JTextArea txtConversation;
private ColorPane txtConversation;
private javax.swing.JTextField txtMessage; private javax.swing.JTextField txtMessage;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables

View file

@ -0,0 +1,70 @@
package mage.client.components;
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import java.awt.*;
/**
* Enhanced {@link JTextPane} with text highlighting support.
*
* @author nantuko
*/
public class ColorPane extends JTextPane {
/**
* This method solves the known issue with Nimbus LAF background transparency and background color.
* @param color
*/
public void setExtBackgroundColor(Color color) {
setBackground(new Color(0,0,0,0));
JPanel jPanel = new JPanel();
jPanel.setBackground(color);
setLayout(new BorderLayout());
add(jPanel);
}
public void append(Color color, String s) {
if (color == null) {
return;
}
try {
setEditable(true);
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, color);
int len = getDocument().getLength();
setCaretPosition(len);
setCharacterAttributes(aset, false);
replaceSelection(s);
setEditable(false);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* A little trick to paint black background under the text.
*
* @param g
*/
public void paintChildren(Graphics g) {
super.paintComponent(g);
}
/**
* A little trick to paint black background under the text.
*
* @param g
*/
public void paintComponent(Graphics g) {
super.paintChildren(g);
}
}

View file

@ -50,6 +50,7 @@ import javax.swing.border.LineBorder;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.cards.Cards; import mage.client.cards.Cards;
import mage.client.chat.ChatPanel;
import mage.client.dialog.CombatDialog; import mage.client.dialog.CombatDialog;
import mage.client.dialog.ExileZoneDialog; import mage.client.dialog.ExileZoneDialog;
import mage.client.dialog.PickChoiceDialog; import mage.client.dialog.PickChoiceDialog;
@ -133,7 +134,8 @@ public class GamePanel extends javax.swing.JPanel {
components.put("pnlBattlefield", pnlBattlefield); components.put("pnlBattlefield", pnlBattlefield);
components.put("jPanel3", jPanel3); components.put("jPanel3", jPanel3);
components.put("hand", hand); components.put("hand", hand);
components.put("chatPanel", chatPanel); components.put("gameChatPanel", gameChatPanel);
components.put("userChatPanel", userChatPanel);
components.put("jLayeredPane", jLayeredPane); components.put("jLayeredPane", jLayeredPane);
components.put("gamePanel", this); components.put("gamePanel", this);
@ -141,7 +143,7 @@ public class GamePanel extends javax.swing.JPanel {
} }
public void cleanUp() { public void cleanUp() {
this.chatPanel.disconnect(); this.gameChatPanel.disconnect();
this.players.clear(); this.players.clear();
logger.debug("players clear."); logger.debug("players clear.");
this.pnlBattlefield.removeAll(); this.pnlBattlefield.removeAll();
@ -166,8 +168,8 @@ public class GamePanel extends javax.swing.JPanel {
this.btnConcede.setVisible(true); this.btnConcede.setVisible(true);
this.pnlReplay.setVisible(false); this.pnlReplay.setVisible(false);
this.btnStopWatching.setVisible(false); this.btnStopWatching.setVisible(false);
this.chatPanel.clear(); this.gameChatPanel.clear();
this.chatPanel.connect(session.getGameChatId(gameId)); this.gameChatPanel.connect(session.getGameChatId(gameId));
if (!session.joinGame(gameId)) if (!session.joinGame(gameId))
hideGame(); hideGame();
} }
@ -182,8 +184,8 @@ public class GamePanel extends javax.swing.JPanel {
this.btnConcede.setVisible(false); this.btnConcede.setVisible(false);
this.btnStopWatching.setVisible(true); this.btnStopWatching.setVisible(true);
this.pnlReplay.setVisible(false); this.pnlReplay.setVisible(false);
this.chatPanel.clear(); this.gameChatPanel.clear();
this.chatPanel.connect(session.getGameChatId(gameId)); this.gameChatPanel.connect(session.getGameChatId(gameId));
if (!session.watchGame(gameId)) if (!session.watchGame(gameId))
hideGame(); hideGame();
} }
@ -197,7 +199,7 @@ public class GamePanel extends javax.swing.JPanel {
this.btnConcede.setVisible(false); this.btnConcede.setVisible(false);
this.btnStopWatching.setVisible(false); this.btnStopWatching.setVisible(false);
this.pnlReplay.setVisible(true); this.pnlReplay.setVisible(true);
this.chatPanel.clear(); this.gameChatPanel.clear();
if (!session.startReplay(gameId)) if (!session.startReplay(gameId))
hideGame(); hideGame();
} }
@ -493,7 +495,14 @@ public class GamePanel extends javax.swing.JPanel {
btnNextPlay = new javax.swing.JButton(); btnNextPlay = new javax.swing.JButton();
pnlBattlefield = new javax.swing.JPanel(); pnlBattlefield = new javax.swing.JPanel();
hand = new mage.client.cards.Cards(true); hand = new mage.client.cards.Cards(true);
chatPanel = new mage.client.chat.ChatPanel(); gameChatPanel = new mage.client.chat.ChatPanel();
gameChatPanel.useExtendedView(ChatPanel.VIEW_MODE.GAME);
userChatPanel = new mage.client.chat.ChatPanel();
userChatPanel.setParentChat(gameChatPanel);
userChatPanel.useExtendedView(ChatPanel.VIEW_MODE.CHAT);
gameChatPanel.setConnectedChat(userChatPanel);
gameChatPanel.disableInput();
jTabbedPane1 = new JTabbedPane();
hand.setCardDimension(handCardDimension); hand.setCardDimension(handCardDimension);
@ -502,7 +511,7 @@ public class GamePanel extends javax.swing.JPanel {
jSplitPane1.setResizeWeight(1.0); jSplitPane1.setResizeWeight(1.0);
jSplitPane1.setOneTouchExpandable(true); jSplitPane1.setOneTouchExpandable(true);
jSplitPane1.setMinimumSize(new java.awt.Dimension(26, 48)); jSplitPane1.setMinimumSize(new java.awt.Dimension(26, 48));
jSplitPane1.setDividerLocation(Integer.MAX_VALUE); //jSplitPane1.setDividerLocation(Integer.MAX_VALUE);
//pnlGameInfo.setBorder(javax.swing.BorderFactory.createEtchedBorder()); //pnlGameInfo.setBorder(javax.swing.BorderFactory.createEtchedBorder());
pnlGameInfo.setOpaque(false); pnlGameInfo.setOpaque(false);
@ -681,6 +690,11 @@ public class GamePanel extends javax.swing.JPanel {
hand.setBorder(emptyBorder); hand.setBorder(emptyBorder);
HandContainer handContainer = new HandContainer(hand); HandContainer handContainer = new HandContainer(hand);
jTabbedPane1.setTabPlacement(javax.swing.JTabbedPane.BOTTOM);
jTabbedPane1.addTab("Game", gameChatPanel);
jTabbedPane1.addTab("Chat", userChatPanel);
jTabbedPane1.setSelectedIndex(1);
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout); jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup( jPanel3Layout.setHorizontalGroup(
@ -705,8 +719,8 @@ public class GamePanel extends javax.swing.JPanel {
jPanel3.setMinimumSize(new Dimension(1024, 768)); jPanel3.setMinimumSize(new Dimension(1024, 768));
jSplitPane1.setLeftComponent(jPanel3); jSplitPane1.setLeftComponent(jPanel3);
chatPanel.setMinimumSize(new java.awt.Dimension(100, 48)); gameChatPanel.setMinimumSize(new java.awt.Dimension(100, 48));
jSplitPane1.setRightComponent(chatPanel); jSplitPane1.setRightComponent(jTabbedPane1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
@ -804,8 +818,9 @@ public class GamePanel extends javax.swing.JPanel {
private javax.swing.JButton btnPreviousPlay; private javax.swing.JButton btnPreviousPlay;
private javax.swing.JButton btnStopReplay; private javax.swing.JButton btnStopReplay;
private javax.swing.JButton btnStopWatching; private javax.swing.JButton btnStopWatching;
private mage.client.chat.ChatPanel chatPanel; private mage.client.chat.ChatPanel gameChatPanel;
private mage.client.game.FeedbackPanel feedbackPanel; private mage.client.game.FeedbackPanel feedbackPanel;
private mage.client.chat.ChatPanel userChatPanel;
private mage.client.cards.Cards hand; private mage.client.cards.Cards hand;
private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel3;
private javax.swing.JSplitPane jSplitPane1; private javax.swing.JSplitPane jSplitPane1;
@ -825,5 +840,6 @@ public class GamePanel extends javax.swing.JPanel {
private javax.swing.JLabel txtTurn; private javax.swing.JLabel txtTurn;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
private JTabbedPane jTabbedPane1;
private Border emptyBorder = new EmptyBorder(0,0,0,0); private Border emptyBorder = new EmptyBorder(0,0,0,0);
} }

View file

@ -102,8 +102,13 @@ public class CallbackClientImpl implements CallbackClient {
else if (callback.getMethod().equals("chatMessage")) { else if (callback.getMethod().equals("chatMessage")) {
ChatMessage message = (ChatMessage) callback.getData(); ChatMessage message = (ChatMessage) callback.getData();
ChatPanel panel = frame.getChat(callback.getObjectId()); ChatPanel panel = frame.getChat(callback.getObjectId());
if (panel != null) if (panel != null) {
panel.receiveMessage(message.getMessage(), message.getColor()); if (message.isUserMessage() && panel.getConnectedChat() != null) {
panel.getConnectedChat().receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), ChatMessage.MessageColor.BLACK);
} else {
panel.receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), message.getColor());
}
}
} }
else if (callback.getMethod().equals("replayInit")) { else if (callback.getMethod().equals("replayInit")) {
GamePanel panel = frame.getGame(callback.getObjectId()); GamePanel panel = frame.getGame(callback.getObjectId());

View file

@ -87,6 +87,9 @@ public class TablesPanel extends javax.swing.JPanel {
initComponents(); initComponents();
tableTables.createDefaultColumnsFromModel(); tableTables.createDefaultColumnsFromModel();
chatPanel.useExtendedView(ChatPanel.VIEW_MODE.NONE);
chatPanel.setOpaque(false);
chatPanel.setBorder(null);
Action join = new AbstractAction() Action join = new AbstractAction()
{ {

View file

@ -38,6 +38,8 @@ import java.util.UUID;
public class ChatMessage implements Serializable { public class ChatMessage implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String username;
private String time;
private String message; private String message;
private MessageColor color; private MessageColor color;
@ -45,8 +47,10 @@ public class ChatMessage implements Serializable {
BLACK, RED, GREEN, BLUE, ORANGE; BLACK, RED, GREEN, BLUE, ORANGE;
} }
public ChatMessage(String message, MessageColor color) { public ChatMessage(String username, String message, String time, MessageColor color) {
this.username = username;
this.message = message; this.message = message;
this.time = time;
this.color = color; this.color = color;
} }
@ -57,4 +61,16 @@ public class ChatMessage implements Serializable {
public MessageColor getColor() { public MessageColor getColor() {
return color; return color;
} }
public boolean isUserMessage() {
return color != null && color.equals(MessageColor.BLUE);
}
public String getUsername() {
return username;
}
public String getTime() {
return time;
}
} }

View file

@ -60,7 +60,8 @@ public class ThemePluginImpl implements ThemePlugin {
unsetOpaque(ui.get("pnlBattlefield")); unsetOpaque(ui.get("pnlBattlefield"));
unsetOpaque(ui.get("jPanel3")); unsetOpaque(ui.get("jPanel3"));
unsetOpaque(ui.get("hand")); unsetOpaque(ui.get("hand"));
unsetOpaque(ui.get("chatPanel")); unsetOpaque(ui.get("gameChatPanel"));
unsetOpaque(ui.get("userChatPanel"));
ui.get("gamePanel").remove(ui.get("jLayeredPane")); ui.get("gamePanel").remove(ui.get("jLayeredPane"));
bgPanel.add(ui.get("jLayeredPane")); bgPanel.add(ui.get("jLayeredPane"));

View file

@ -75,13 +75,15 @@ public class ChatSession {
public void broadcast(String userName, String message, MessageColor color) { public void broadcast(String userName, String message, MessageColor color) {
Calendar cal = new GregorianCalendar(); Calendar cal = new GregorianCalendar();
final String msg = timeFormatter.format(cal.getTime()) + " " + userName + ":" + message; final String msg = message;
final String time = timeFormatter.format(cal.getTime());
final String username = userName;
logger.debug("Broadcasting '" + msg + "' for " + chatId); logger.debug("Broadcasting '" + msg + "' for " + chatId);
for (UUID sessionId: clients.keySet()) { for (UUID sessionId: clients.keySet()) {
Session session = SessionManager.getInstance().getSession(sessionId); Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null) if (session != null)
try { try {
session.fireCallback(new ClientCallback("chatMessage", chatId, new ChatMessage(msg, color))); session.fireCallback(new ClientCallback("chatMessage", chatId, new ChatMessage(username, msg, time, color)));
} catch (CallbackException ex) { } catch (CallbackException ex) {
logger.fatal("broadcast error", ex); logger.fatal("broadcast error", ex);
} }