/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.GUI;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import jpcsp.Emulator;
import jpcsp.HLE.Modules;
import jpcsp.HLE.modules.sceUtility;
import jpcsp.network.INetworkAdapter;
import org.apache.log4j.Logger;
/**
* @author gid15
*
* Network Chat User Interface
*/
public class ChatGUI extends JFrame {
private static final long serialVersionUID = 5376146560681704272L;
private Logger log = Emulator.log;
private JScrollPane scrollPane;
private JLabel chatMessagesLabel;
private JTextField chatMessage;
private JButton sendButton;
private JLabel adhocIDLabel;
private JLabel groupNameLabel;
private JLabel membersLabel;
private JLabel membersList;
private List<String> chatMessages = new LinkedList<String>();
private List<String> members = new LinkedList<String>();
private static final String chatMessageHeader = "<html>";
private static final String chatMessageFooter = "</html>";
private static final String membersHeader = "<html>";
private static final String membersFooter = "</html>";
private HashMap<String, Color> nickNameColors = new HashMap<String, Color>();
private int allColorsIndex = 0;
// Always assign the GRAY color to me.
private static final Color colorForMe = Color.GRAY;
// The Nicknames will be assigned these colors (first come, first served)
private static final Color[] allColors = new Color[]{
Color.BLUE,
Color.RED,
Color.CYAN,
Color.GREEN,
Color.MAGENTA,
Color.ORANGE,
Color.PINK,
Color.YELLOW,
Color.BLACK
};
public ChatGUI() {
initComponents();
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
nickNameColors.put(getMyNickName(), colorForMe);
updateMembersLabel();
}
private void initComponents() {
scrollPane = new JScrollPane();
chatMessagesLabel = new JLabel();
chatMessage = new JTextField();
sendButton = new JButton();
adhocIDLabel = new JLabel();
groupNameLabel = new JLabel();
membersLabel = new JLabel();
membersList = new JLabel();
setTitle("Chat");
setResizable(true);
sendButton.setText("Send");
sendButton.setDefaultCapable(true);
getRootPane().setDefaultButton(sendButton);
sendButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
onSend();
}
});
// Start displaying the chat message from the bottom
chatMessagesLabel.setVerticalAlignment(SwingConstants.BOTTOM);
chatMessagesLabel.setPreferredSize(new Dimension(500, 300));
scrollPane.setViewportView(chatMessagesLabel);
adhocIDLabel.setText(getAdhocID());
groupNameLabel.setText(getGroupName());
membersLabel.setText("Members:");
membersList.setPreferredSize(new Dimension(100, chatMessagesLabel.getPreferredSize().height));
chatMessage.setEditable(true);
//
// Layout:
//
// +-------------------------------------------+-----------------+
// | | adhocIDLabel |
// | | groupNameLabel |
// | chatMessageLabel in scrollPane | membersLabel |
// | +-----------------+
// | | membersList |
// | | |
// | | |
// | | |
// | | |
// +-------------------------------------------+----+------------+
// | chatMessage | sendButton |
// +------------------------------------------------+------------+
//
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup()
.addGroup(layout.createSequentialGroup()
.addComponent(scrollPane)
.addGroup(layout.createParallelGroup()
.addGroup(layout.createParallelGroup()
.addComponent(adhocIDLabel))
.addGroup(layout.createParallelGroup()
.addComponent(groupNameLabel))
.addComponent(membersLabel)
.addComponent(membersList)))
.addGroup(layout.createSequentialGroup()
.addComponent(chatMessage)
.addComponent(sendButton)));
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(scrollPane)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup()
.addComponent(adhocIDLabel))
.addGroup(layout.createParallelGroup()
.addComponent(groupNameLabel))
.addComponent(membersLabel)
.addComponent(membersList)))
.addGroup(layout.createParallelGroup()
.addComponent(chatMessage)
.addComponent(sendButton)));
pack();
}
private void onSend() {
String message = chatMessage.getText();
if (log.isDebugEnabled()) {
log.debug(String.format("Sending chat message '%s'", message));
}
// Send the chat message to the network adapter
INetworkAdapter networkAdapter = Modules.sceNetModule.getNetworkAdapter();
if (networkAdapter != null) {
networkAdapter.sendChatMessage(message);
chatMessage.setText("");
// Add my own chat to the messages
addChatMessage(getMyNickName(), message, true);
}
}
private void addChatLine(String line) {
chatMessages.add(line);
StringBuilder formattedText = new StringBuilder();
formattedText.append(chatMessageHeader);
for (String chatMessage : chatMessages) {
formattedText.append(String.format("<br>%s</br>\n", chatMessage));
}
formattedText.append(chatMessageFooter);
chatMessagesLabel.setText(formattedText.toString());
}
private Color getNewColor() {
if (allColorsIndex >= allColors.length) {
allColorsIndex = 0;
}
return allColors[allColorsIndex++];
}
private Color getNickNameColor(String nickName) {
Color color = nickNameColors.get(nickName);
if (color == null) {
// No color yet assigned to the nickName, assign a new one
color = getNewColor();
nickNameColors.put(nickName, color);
}
return color;
}
public void addChatMessage(String nickName, String message) {
addChatMessage(nickName, message, false);
}
private String getFormattedNickName(String nickName, boolean isMe) {
Color nickNameColor = getNickNameColor(nickName);
String nickNameSuffix = isMe ? " (me)" : "";
return String.format("<font color='#%06X'>%s%s</font>", nickNameColor.getRGB() & 0x00FFFFFF, nickName, nickNameSuffix);
}
private void addChatMessage(String nickName, String message, boolean isMe) {
String line;
if (nickName == null) {
line = message;
} else {
line = String.format("%s - %s", getFormattedNickName(nickName, isMe), message);
}
addChatLine(line);
}
@Override
public void dispose() {
Emulator.getMainGUI().endWindowDialog();
super.dispose();
}
private void updateMembersLabel() {
if (membersList == null) {
return;
}
StringBuilder label = new StringBuilder();
label.append(membersHeader);
// Always put myself in front of the list
label.append(String.format("<br>%s</br>", getFormattedNickName(getMyNickName(), true)));
for (String member : members) {
label.append(String.format("<br>%s</br>", getFormattedNickName(member, false)));
}
label.append(membersFooter);
membersList.setText(label.toString());
}
public void updateMembers(List<String> members) {
this.members.clear();
this.members.addAll(members);
updateMembersLabel();
}
private static String getMyNickName() {
return sceUtility.getSystemParamNickname();
}
private static String getAdhocID(){
return Modules.sceNetAdhocctlModule.hleNetAdhocctlGetAdhocID();
}
private static String getGroupName(){
return Modules.sceNetAdhocctlModule.hleNetAdhocctlGetGroupName();
}
}