In my chat you have the option to create a user group, when a user connects to the chat, this option is available, and the user can create as many groups as he wants and he and other users connected to the chat can enter it, but initially, when there are no groups created yet, and only one user creates one or more groups, these groups will only be shown to other users who have created groups.
I created a button to update the group list, but it is not working. I would like to know if there is any way so that when only one user creates a group, that group will already be displayed to all other users who are connected in the chat.
Some code snippets:
ClientFrame:
package client;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
import server.ChatMessage;
import server.ChatMessage.Action;
import server.ServerService;
public class ClientFrame extends javax.swing.JFrame {
private Socket socket;
private ChatMessage message;
private ClientService service;
public ClientFrame()throws IOException {
initComponents();
}
private class ListenerSocket implements Runnable {
private ObjectInputStream input;
public ListenerSocket (Socket socket) throws IOException {
this.input = new ObjectInputStream (socket.getInputStream ());
}
@Override
public void run() {
try {
while((message = (ChatMessage) input.readObject()) != null){
Action action = message.getAction();
if(action.equals(action.CONNECT)){
connected(message);
}else if(action.equals(action.USERS_ONLINE)){
RefreshOnlines(message);
}else if(action.equals(action.ONLINE_GROUPS)){
RefreshOnlinesGroups(message);
}
}
} catch (IOException ex) {
dispose();
Logger.getLogger (ServerService.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger (ServerService.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void connected (ChatMessage message) {
if (message.getText().equals("NO")) {
txtName.setText("");
JOptionPane.showMessageDialog (null, "Connection not made. /n Try another name.");
return;
}
message = message;
btnConnect.setEnabled(false);
txtName.setEditable(false);
txtNewGroup.setEnabled(true);
btnCreateGroup.setEnabled(true);
btnUpdateGroups.setEnabled(true);
JOptionPane.showMessageDialog (null, "Connection successful");
}
private void RefreshOnlines (ChatMessage message) {
System.out.println (message.getSetOnlines().toString());
Set <String> names = message.getSetOnlines ();
names.remove ((String) message.getName ());
String [] array = (String []) names.toArray (new String [names.size ()]);
listOnlines.setListData (array);
listOnlines.setSelectionMode (ListSelectionModel.SINGLE_SELECTION);
listOnlines.setLayoutOrientation (JList.VERTICAL);
}
private void RefreshOnlinesGroups (ChatMessage message) {
System.out.println (message.getSetOnlinesGroups().toString());
Set <String> namesGroups = message.getSetOnlinesGroups ();
String [] arrayGroup = (String []) namesGroups.toArray (new String [namesGroups.size ()]);
listGroups.setListData (arrayGroup);
listGroups.setSelectionMode (ListSelectionModel.SINGLE_SELECTION);
listGroups.setLayoutOrientation (JList.VERTICAL);
}
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jScrollPane5 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList<>();
jPanel1 = new javax.swing.JPanel();
txtName = new javax.swing.JTextField();
btnConnect = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jScrollPane4 = new javax.swing.JScrollPane();
listOnlines = new javax.swing.JList<>();
jScrollPane6 = new javax.swing.JScrollPane();
listGroups = new javax.swing.JList<>();
btnCreateGroup = new javax.swing.JButton();
txtNewGroup = new javax.swing.JTextField();
btnUpdateGroups = new javax.swing.JButton();
jPanel3 = new javax.swing.JPanel();
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane1.setViewportView(jTextArea1);
jButton1.setText("jButton1");
jButton2.setText("jButton2");
jList1.setModel(new javax.swing.AbstractListModel<String>() {
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
public int getSize() { return strings.length; }
public String getElementAt(int i) { return strings[i]; }
});
jScrollPane5.setViewportView(jList1);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
txtName.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtNameActionPerformed(evt);
}
});
btnConnect.setText("Connect");
btnConnect.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnConnectActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(txtName, javax.swing.GroupLayout.DEFAULT_SIZE, 289, Short.MAX_VALUE)
.addContainerGap())
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(106, 106, 106)
.addComponent(btnConnect)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(btnConnect)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
listOnlines.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
jScrollPane4.setViewportView(listOnlines);
jScrollPane6.setViewportView(listGroups);
btnCreateGroup.setText("Create Group");
btnCreateGroup.setEnabled(false);
btnCreateGroup.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnCreateGroupActionPerformed(evt);
}
});
txtNewGroup.setEnabled(false);
btnUpdateGroups.setText("Update Groups");
btnUpdateGroups.setEnabled(false);
btnUpdateGroups.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnUpdateGroupsActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 12, Short.MAX_VALUE) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
.addComponent(jScrollPane6, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(35, 35, 35))
.addComponent(txtNewGroup, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 216, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnUpdateGroups)
.addComponent(btnCreateGroup))
.addGap(63, 63, 63))))
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 376, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(jPanel2Layout.createSequentialGroup()
.addComponent(jScrollPane6, javax.swing.GroupLayout.PREFERRED_SIZE, 292, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtNewGroup, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCreateGroup) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnUpdateGroups)))
.addGap(0, 14, Short.MAX_VALUE)));
jPanel3.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 309, Short.MAX_VALUE));
jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 323, Short.MAX_VALUE));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false).addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addContainerGap()));
layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addGroup(layout.createSequentialGroup().addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))).addContainerGap()));
pack();
}// </editor-fold>
private void txtNameActionPerformed(java.awt.event.ActionEvent evt) {
}
private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {
String name = this.txtName.getText ();
if (! name.isEmpty ()) {
this.message = new ChatMessage ();
this.message.setAction (Action.CONNECT);
this.message.setName (name);
this.service = new ClientService();
try {
this.socket = this.service.connect ();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Server not connected"); Logger.getLogger(ClientFrame.class.getName()).log(Level.SEVERE, null, ex);
}
try {
new Thread (new ListenerSocket (this.socket)). start ();
} catch (IOException ex) { Logger.getLogger(ClientFrame.class.getName()).log(Level.SEVERE, null, ex);
}
try {
setTitle(name);
this.service.send(message);
} catch (IOException ex) {
Logger.getLogger (ClientFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void btnCreateGroupActionPerformed(java.awt.event.ActionEvent evt) {
this.message = new ChatMessage ();
String newGroup = this.txtNewGroup.getText ();
if (! newGroup.isEmpty ()) {
this.message.setAction (Action.NEW_GROUP);
this.message.setGroupReserved(newGroup);
try {
this.service.send (this.message);
} catch (IOException ex) {
Logger.getLogger (ClientFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}else{
JOptionPane.showMessageDialog (null, "Enter a name to create a group");
}
}
private void btnUpdateGroupsActionPerformed(java.awt.event.ActionEvent evt) {
this.message = new ChatMessage();
this.message.setAction(Action.ONLINE_GROUPS);
try {
this.service.send(this.message);
} catch (IOException ex) {
Logger.getLogger(ClientFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
// Variables declaration - do not modify
private static javax.swing.JButton btnConnect;
private javax.swing.JButton btnCreateGroup;
private javax.swing.JButton btnUpdateGroups;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JList<String> jList1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane4;
private javax.swing.JScrollPane jScrollPane5;
private javax.swing.JScrollPane jScrollPane6;
private javax.swing.JTextArea jTextArea1;
private javax.swing.JList<String> listGroups;
private javax.swing.JList<String> listOnlines;
private javax.swing.JTextField txtName;
public static javax.swing.JTextField txtNewGroup;
// End of variables declaration
}
ServerService:
package server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import server.ChatMessage.Action;
public class ServerService {
private ServerSocket serverSocket;
private Socket socket;
public static Map<String, ObjectOutputStream>mapOnlines = new
HashMap<String, ObjectOutputStream>();
private static Map<String, ObjectOutputStream>mapGroup = new
HashMap<String, ObjectOutputStream>();
public ServerService() throws IOException{
try{
serverSocket = new ServerSocket(5555);
System.out.println("Server ON");
}catch(IOException ex){
Logger.getLogger(ServerService.class.getName()).log(Level.SEVERE,
null, ex);
}
while(true){
socket = serverSocket.accept();
new Thread(new ListenerSocket(socket)).start();
}
}
private class ListenerSocket implements Runnable {
private ObjectOutputStream output;
private ObjectInputStream input;
public ListenerSocket(Socket socket) throws IOException{
this.output = new ObjectOutputStream(socket.getOutputStream());
this.input = new ObjectInputStream(socket.getInputStream());
}
public void run() {
ChatMessage message = null;
sendOnlinesGroups();
try {
while((message = (ChatMessage) input.readObject()) != null){
Action action = message.getAction();
if(action.equals(action.CONNECT)){
boolean isConnect = connect(message, output);
if(isConnect){
mapOnlines.put(message.getName(), output);
sendOnlines();
}
}else if(action.equals(action.NEW_GROUP)){
if(mapGroup.containsKey(message.getGroupReserved())){
JOptionPane.showMessageDialog(null, "A group with that
name already exists");
}else{
JOptionPane.showMessageDialog(null, "Successfully created
group");
mapGroup.put(message.getGroupReserved(), output);
sendOnlinesGroups();
}
}else if(action.equals(action.ONLINE_GROUPS)){
sendOnlinesGroups();
}
}
}catch(IOException ex){ Logger.getLogger(ServerService.class.getName()).log(Level.SEVERE,
null, ex);
} catch (ClassNotFoundException ex){
Logger.getLogger(ServerService.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
private boolean connect(ChatMessage message, ObjectOutputStream output)
throws IOException{
if(mapOnlines.size()== 0){
message.setText("YES");
send(message, output);
return true;
}
if(mapOnlines.containsKey(message.getName())){
message.setText("NO");
send(message,output);
return false;
}else{
message.setText("YES");
send(message,output);
return true;
}
}
private void send(ChatMessage message, ObjectOutputStream output) throws
IOException{
output.writeObject(message);
}
private void sendOnlines(){
Set<String> setNames = new HashSet<String>();
for(Map.Entry<String, ObjectOutputStream> kv : mapOnlines.entrySet()){
setNames.add(kv.getKey());
}
ChatMessage message = new ChatMessage();
message.setAction(Action.USERS_ONLINE);
message.setSetOnlines(setNames);
for (Map.Entry<String, ObjectOutputStream> kv : mapOnlines.entrySet()){
message.setName(kv.getKey());
try{
kv.getValue().writeObject(message);
}catch(IOException ex) { Logger.getLogger(ServerService.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
private void sendOnlinesGroups(){
Set<String> setNamesGroups = new HashSet<String>();
for(Map.Entry<String, ObjectOutputStream> kv : mapGroup.entrySet()){
setNamesGroups.add(kv.getKey());
}
ChatMessage message = new ChatMessage();
message.setAction(Action.ONLINE_GROUPS);
message.setSetOnlinesGroups(setNamesGroups);
for (Map.Entry<String, ObjectOutputStream> kv : mapGroup.entrySet()){
message.setGroupReserved(kv.getKey());
try {
kv.getValue().writeObject(message);
}catch(IOException ex) { Logger.getLogger(ServerService.class.getName()).log(Level.SEVERE,
null, ex);
}
}
}
public static boolean criarGrupo(){
ChatMessage message = new ChatMessage();
if(mapGroup.containsKey(message.getGroupReserved())){
JOptionPane.showMessageDialog(null, "A group with that name already
exists");
return false;
}else{
JOptionPane.showMessageDialog(null, "Successfully created group");
return true;
}
}
}
ChatMessage:
package server;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class ChatMessage implements Serializable{
String name;
private Set<String> setOnlinesGroups = new HashSet<String>();
String groupReserved;
String text;
private String nameReserved;
private Set<String> setOnlines = new HashSet<String>();
private Set<String> setOnlinesPrivate = new HashSet<String>();
private Action action;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getNameReserved() {
return nameReserved;
}
public void setNameReserved(String nameReserved) {
this.nameReserved = nameReserved;
}
public Action getAction() {
return action;
}
public void setAction(Action action) {
this.action = action;
}
public Set<String> getSetOnlines() {
return setOnlines;
}
public void setSetOnlines(Set<String> setOnlines) {
this.setOnlines = setOnlines;
}
public Set<String> getSetOnlinesPrivate() {
return setOnlinesPrivate;
}
public void setSetOnlinesPrivate(Set<String> setOnlinesPrivate) {
this.setOnlinesPrivate = setOnlinesPrivate;
}
public Set<String> getSetOnlinesGroups() {
return setOnlinesGroups;
}
public void setSetOnlinesGroups(Set<String> setOnlinesGroups) {
this.setOnlinesGroups = setOnlinesGroups;
}
public String getGroupReserved() {
return groupReserved;
}
public void setGroupReserved(String groupReserved) {
this.groupReserved = groupReserved;
}
public enum Action {
CONNECT,DISCONNECT,SEND_ONE,SEND_ONE2,
SEND_ALL,USERS_ONLINE,ONLINE_GROUPS,NEW_GROUP,REMOVE_GROUP,SEND_GROUP,
}
}
Client:
package client;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Client {
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new ClientFrame().setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE,
null, ex);
}
}
});
}
}
ClientService:
package client;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import server.ChatMessage;
public class ClientService {
private Socket socket;
private ObjectOutputStream output;
public static int hostt;
public Socket connect() throws IOException{
this.socket = new Socket("localhost",5555);
this.output = new ObjectOutputStream(socket.getOutputStream());
return socket;
}
public void send(ChatMessage message) throws IOException{
output.writeObject(message);
}
}
Server:
package server;
import java.io.IOException;
public class Server {
public static void main(String[] args) throws IOException {
new ServerService();
}
}