My problem is, I can still send messages between Clients(Client-to-Client) but after sending two or three times, messages are no more displayed to the recipient.
So basically whenever the Client wish to send a message to another Client, the message is first sent to the server. But as you have noticed from my coding, I am sending the server data in form of an object.
For example:
send(new ChatMessage(type, sender, content, recipient));
When you send a message the type is "message". When the server receives the object, it checks the receive data and its type.
For example:
ChatMessage cm = (ChatMessage) in[client[id].readObject();
if(cm.type.equals("message"){
send(findUserThread(toWhom), new ChatMessage("message", sender, content, recipient);
}
If the type is "message", then it sends that specific client the message.
I am using System.out.println() at the Client side to see the incoming data from server. So when I try to send some messages, it is working fine but then after sending some messages nothing is display on my chat screen.
According to my logic the errors can be:
1 Selected index in JList
2 Client[] array or username[] array
3 ObjectOutputStream and ObjectInputStream
ServerGUI class(Server Side)
package test2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.*;
import java.util.zip.GZIPOutputStream;
import javax.swing.SwingUtilities;
public class ServerGUI extends JFrame implements ActionListener {
public JList online;
private JTextField ipaddress, textMessage;
private JButton send, start, disconnect;
private JTextArea chatArea;
private JLabel port;
int client[] = new int[100];
private ObjectOutputStream out[] = new ObjectOutputStream[client.length + 1];
private ObjectInputStream in[] = new ObjectInputStream[client.length + 1];
String username[] = new String[client.length + 1];
static String b;
public String nm, usm;
private ServerSocket server;
private Socket connect;
boolean success = true;
int id = 0;
ArrayList<String> UserList = new ArrayList<String>();
public ServerGUI() {
Container c = getContentPane();
c.setLayout(new BorderLayout());
c.setPreferredSize(new Dimension(650, 500));
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
p.setBackground(Color.LIGHT_GRAY);
p.add(port = new JLabel("Port No"));
p.add(ipaddress = new JTextField("1500"));
p.add(start = new JButton("START"));
p.add(disconnect = new JButton("DISCONNECT"));
disconnect.setEnabled(false);
start.setBorderPainted(false);
start.setBackground(Color.blue);
start.setForeground(Color.WHITE);
disconnect.setBorderPainted(false);
disconnect.setBackground(Color.blue);
disconnect.setForeground(Color.WHITE);
ipaddress.setCaretPosition(0);
JPanel p1 = new JPanel();
p1.setLayout(new FlowLayout());
p1.setBackground(Color.LIGHT_GRAY);
p1.add(chatArea = new JTextArea());
chatArea.setPreferredSize(new Dimension(300, 350));
chatArea.setLineWrap(true);
chatArea.setEditable(false);
JPanel p2 = new JPanel();
p2.setLayout(new FlowLayout());
p2.setBackground(Color.LIGHT_GRAY);
p2.add(textMessage = new JTextField(20));
p2.add(send = new JButton("SEND"));
send.setBackground(Color.blue);
send.setForeground(Color.WHITE);
send.setBorderPainted(false);
start.addActionListener(this);
send.addActionListener(this);
c.add(p, BorderLayout.NORTH);
c.add(p1, BorderLayout.CENTER);
c.add(p2, BorderLayout.SOUTH);
}
//current time
SimpleDateFormat log = new SimpleDateFormat("HH:mm");
String d = log.format(new Date());
//Start server
public void Start() {
int portNo = 0;
try {
String no = ipaddress.getText();
portNo = Integer.parseInt(no);
chatArea.append("Connection to port " + portNo + "...\n");
server = new ServerSocket(portNo);
success = true;
} catch (Exception ex) {
chatArea.append("Error cannot bind to port \n");
success = false;
}
if (success == true) {
addClient ob1 = new addClient("RunServer");
start.setEnabled(false);
disconnect.setEnabled(true);
}
}
public class addClient implements Runnable {
Thread t;
addClient(String tot) {
t = new Thread(this, tot);
t.start();
}
public void run() {
while (true) {
try {
try {
WaitClient();
} catch (Exception ex) {
break;
}
for (int i = 0; i < client.length; i++) {
if (client[i] == 0) {
client[i] = i + 1;
id = i;
break;
}
}
//set stream to send and receive data
out[client[id]] = new ObjectOutputStream(connect.getOutputStream());
out[client[id]].flush();
in[client[id]] = new ObjectInputStream(connect.getInputStream());
chatArea.append(d + " Client:[" + client[id] + "] : Connected successful \n");
chatArea.setCaretPosition(chatArea.getText().length());
//inform user that connection is successfull
ChatMessage cm = (ChatMessage) in[client[id]].readObject(); // read client username
if(cm.type.equals("login")){
chatArea.append("User " +cm.sender + " connected successfully" + "\n" );
username[client[id]] = cm.sender;
System.out.println(username[0]+ username[1]+ username[2]);
send(client[id], new ChatMessage("login", username[client[id]], "user", "SERVER"));
sendUserList(cm.sender);
Announce("newuser", "SERVER", cm.sender);
}
Chat c = new Chat(client[id], "StartChat" + client[id]); // make new thread for every new client
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class Chat implements Runnable {
int id1;
Chat ob1;
Thread t;
Chat(int id1, String info1) {
this.id1 = id1; // create a thread for client
t = new Thread(this, info1);
t.start();
}
public void run() {
boolean running = true;
while(running){
try {
ChatMessage cm = (ChatMessage) in[client[id]].readObject(); // read client username
if(cm.type.equals("message")){
send(findUserThread(cm.recipient), new ChatMessage(cm.type, cm.sender, cm.content, cm.recipient));
}
} catch (Exception e) {
}
}
}
}
//wait for connection, then display connection information
private void WaitClient() throws IOException {
chatArea.append(d + " : Waiting for connection... \n");
connect = server.accept();
chatArea.append(d + " : Now connected to " + connect.getInetAddress().getHostName() + "\n");
}
//send message to specific user
public void sendUser(int number, String info) {
try {
out[number].writeObject(info);
out[number].flush();
} catch (Exception e) {
}
}
public void sendServer(String por) {
for (int i = 0; i < client.length; i++) // for loop trying to send message from server to all clients
{
if (client[i] != 0) // this line stop server to send messages to offline clients
{
try {
out[i + 1].writeObject(por);
out[i + 1].flush();
} catch (Exception e) {
}
}
}
}
public void Announce(String type, String sender, String content){
ChatMessage cm = new ChatMessage(type, sender, content, "All");
for(int i = 0; i < id; i++){
send(client[i], cm);
}
}
public void send(int number, ChatMessage cm) {
try {
out[number].writeObject(cm);
out[number].flush();
} catch (Exception e) {
}
}
void sendAll(int num, String por) {
for (int i = 0; i < client.length; i++) // for loop trying to send message from server to all clients
{
if (client[i] != 0) // this line stop server to send messages to offline clients (if "clientNiz[X] = 0" don't try to send him message, because that slot is empty)
{
if (num != i + 1) // don't repeat messages (when for ex. client_1 send message to all clients, this line stop server to send same message back to client_1)
{
try {
out[i + 1].writeObject(por);
out[i + 1].flush();
} catch (Exception e) {
}
}
}
}
}
public void sendUserList(String toWhom){
for(int i = 0; i <= id; i++){
send(findUserThread(toWhom), new ChatMessage("newuser", "SERVER", username[client[i]], toWhom));
}
}
public int findUserThread(String usr){
for(int i = 0; i <= id; i++){
if(username[client[i]].equals(usr)){
return client[i];
}
}
return -1;
}
private int findClient(int num){
for (int i = 0; i <= id; i++){
if (client[i] == (num+1)){
return i;
}
}
return -1;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == send) {
//current time
String s1 = textMessage.getText();
send(client[id], new ChatMessage("message", "admin", s1, "client"));
chatArea.append("Administrator: " + s1 + "\n");
} else if (e.getSource() == start) {
Start();
}
if (e.getSource() == disconnect) {
try {
server.close();
} catch (Exception ex) {
}
for (int i = 0; i < client.length; i++) {
try {
in[i].close();
out[i].close();
} catch (Exception ex) {
}
}
chatArea.append("Server is disconnected\n");
start.setEnabled(true);
disconnect.setEnabled(false);
}
}
}
MainGUI class(Client Side)
package test2;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
public class MainGUI extends javax.swing.JFrame {
public MainGUI() {
initComponents();
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
jButton3 = new javax.swing.JButton();
start = new javax.swing.JButton();
jLabel2 = new javax.swing.JLabel();
textMessage = new javax.swing.JTextField();
jScrollPane2 = new javax.swing.JScrollPane();
chatArea = new javax.swing.JTextArea();
usernm = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
send = new javax.swing.JButton();
upload = new javax.swing.JButton();
filename = new javax.swing.JTextField();
jScrollPane1 = new javax.swing.JScrollPane();
online = new javax.swing.JList();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("ICARE ");
setFocusable(false);
setPreferredSize(new java.awt.Dimension(840, 650));
setResizable(false);
getContentPane().setLayout(null);
jButton1.setText("Video Call");
getContentPane().add(jButton1);
jButton1.setBounds(270, 10, 100, 30);
jButton3.setText("Send");
jButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton3ActionPerformed(evt);
}
});
getContentPane().add(jButton3);
jButton3.setBounds(690, 100, 100, 30);
start.setBackground(new java.awt.Color(51, 51, 255));
start.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
start.setForeground(new java.awt.Color(255, 255, 255));
start.setText("Start");
start.setBorder(null);
start.setBorderPainted(false);
start.setRequestFocusEnabled(false);
start.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
startActionPerformed(evt);
}
});
getContentPane().add(start);
start.setBounds(630, 50, 90, 40);
getContentPane().add(jLabel2);
jLabel2.setBounds(0, 0, 820, 0);
getContentPane().add(textMessage);
textMessage.setBounds(270, 450, 420, 70);
chatArea.setColumns(20);
chatArea.setFont(new java.awt.Font("Arial", 0, 14)); // NOI18N
chatArea.setRows(5);
jScrollPane2.setViewportView(chatArea);
getContentPane().add(jScrollPane2);
jScrollPane2.setBounds(270, 140, 520, 300);
getContentPane().add(usernm);
usernm.setBounds(450, 60, 170, 30);
jLabel1.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
jLabel1.setText("Enter your nickname:");
getContentPane().add(jLabel1);
jLabel1.setBounds(270, 60, 150, 30);
send.setBackground(new java.awt.Color(51, 51, 255));
send.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
send.setForeground(new java.awt.Color(255, 255, 255));
send.setText("Send");
send.setBorder(null);
send.setBorderPainted(false);
send.setRequestFocusEnabled(false);
send.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
sendActionPerformed(evt);
}
});
getContentPane().add(send);
send.setBounds(700, 470, 90, 40);
upload.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
upload.setText("+");
upload.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
uploadActionPerformed(evt);
}
});
getContentPane().add(upload);
upload.setBounds(633, 100, 50, 30);
getContentPane().add(filename);
filename.setBounds(270, 100, 350, 30);
jScrollPane1.setViewportView(online);
getContentPane().add(jScrollPane1);
jScrollPane1.setBounds(30, 20, 220, 500);
pack();
}// </editor-fold>
private void startActionPerformed(java.awt.event.ActionEvent evt) {
Start();
}
private void sendActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String z = textMessage.getText();
String target = online.getSelectedValue().toString();
chatArea.append("[ " + usernm.getText() + " ] : " + z + "\n");
send(new ChatMessage("message", usernm.getText(), z, target));
textMessage.setText("");
}
private void uploadActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
//Create a file chooser
//In response to a button click:
JFileChooser fileChooser = new JFileChooser();
fileChooser.showDialog(this, "Select File");
file = fileChooser.getSelectedFile();
if(file != null){
if(!file.getName().isEmpty()){
String str;
if(filename.getText().length() > 30){
String t = file.getPath();
str = t.substring(0, 20) + " [...] " + t.substring(t.length() - 20, t.length());
}
else{
str = file.getPath();
}
filename.setText(str);
}
}
}
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
long size = file.length();
if(size < 120 * 1024 * 1024){
sendUser("download");
}
else{
chatArea.append("File is size too large\n");
}
}
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MainGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainGUI().setVisible(true);
}
});
}
// Variables declaration - do not modify
public javax.swing.JTextArea chatArea;
private javax.swing.JTextField filename;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton3;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
public javax.swing.JList online;
private javax.swing.JButton send;
private javax.swing.JButton start;
private javax.swing.JTextField textMessage;
private javax.swing.JButton upload;
private javax.swing.JTextField usernm;
// End of variables declaration
private ObjectOutputStream out;
private ObjectInputStream in;
static String b; //variable for message
private Socket join;
boolean success = true;
private String serverIP = "127.0.0.1"; //set IP Address
ArrayList<String> userlist = new ArrayList<String>(); //ArrayList to store online users
//current time
SimpleDateFormat log = new SimpleDateFormat("HH:mm");
String d = log.format(new Date());
public File file;
public DefaultListModel model = new DefaultListModel();
//Start client program
public void Start() {
try {
start.setEnabled(false);
chatArea.append(d + " : Attempting connection... \n");
join = new Socket(serverIP, 10500);
chatArea.append(d + " : Connected to - " + join.getInetAddress().getHostName() + "\n");
success = true;
} catch (Exception ex) {
chatArea.append("Error cannot bind to port \n");
success = false;
}
if (success == true) {
ClientThread ct = new ClientThread();
}
}
class ClientThread implements Runnable {
ClientThread ct;
Thread t;
ClientThread() {
t = new Thread(this, "RunClient");
t.start();
}
public void run() {
try {
try {
out = new ObjectOutputStream(join.getOutputStream());
out.flush();
in = new ObjectInputStream(join.getInputStream());
send(new ChatMessage("login", usernm.getText(), "password", "SERVER"));
} catch (Exception e) { }
CThread c1 = new CThread();
} catch (Exception ex) { }
}
}
class CThread implements Runnable {
CThread ob1;
Thread t;
CThread() {
t = new Thread(this, "Message");
t.start();
}
public void run() {
boolean running = true;
try {
while(running){
try {
ChatMessage cm = (ChatMessage) in.readObject();
System.out.println("Incoming :" + cm.toString());
if(cm.type.equals("login")){
chatArea.append(cm.sender + " is online" + "\n");
}else if(cm.type.equals("message")){
if(cm.recipient.equals(usernm.getText())){
chatArea.append("[ "+cm.sender +" ] : " + cm.content + "\n");
}
}else if(cm.type.equals("newuser")){
online.setModel(model);
model.addElement(cm.content);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
} catch (Exception ex) {
}
}
}
void sendUser(String por) {
try {
out.writeObject(por);
out.flush();
} catch (Exception e) {
}
}
void send(ChatMessage cm){
try {
out.writeObject(cm);
out.flush();
} catch (Exception e) {
}
}
}
ChatMessage class
package test2;
import java.io.Serializable;
public class ChatMessage implements Serializable{
private static final long serialVersionUID = 1L;
public String type, sender, content, recipient;
public ChatMessage(String type, String sender, String content, String recipient){
this.type = type; this.sender = sender; this.content = content; this.recipient = recipient;
}
#Override
public String toString(){
return "{type='"+type+"', sender='"+sender+"', content='"+content+"', recipient='"+recipient+"'}";
}
}
ServerTest to run ServerGUI
public class ServerTest
{
public static void main(String args[]){
ServerGUI m = new ServerGUI();
m.setTitle("Server");
m.setVisible(true);
m.pack();
//to make to the center of the screen
m.setLocationRelativeTo(null);
}
}
Classes in Java should start with uppercase. For example: ServerGUI but not addClient as seen in your code.
Classes represent objects. Or "classes" of objects. For example Car or ServerGUI but not addClient. What is an new addClient()? Is that an object really?
Variable names should have significant names if possible. For example Car limousine = new Car(4,Color.Black) and not addClient ob1 = new addClient("RunServer"). What does ob1 mean?
Comments are fresh air for readers. Please, use comments. For example: //we are going to represent the server as a special user with admin privileges
Method names ir Java should not start with uppercase. This is a bad example: private void WaitClient() throws IOException
Indent and blank lines. Don't know if it is your fault partly or completely but the code is bad indented, has blank lines inside blocks (not just one or two, nor acting as separator), and misses spaces (if(cm.type.equals("login")){)
StackOverflow is not a good place for your problem. Here people ask specific questions. Yours is not a specific question, it is more a "my program doesn't work" problem.
In conclusion: your code is hard to read and understand. It seems you are new to Java so please, start with simple and easy examples, use a Java IDE like Eclipse or Netbeans and take your time! You won't learn Java in a week, be patient.
Sorry if I've been too honest but that's what I think (and probably one of the reasons nobody else here is helping you).
But after sending two or three messages, my program stop sending messages
First of all you should try to debug your application. Using logs or System.out.println you can easily find out where is it "stopping". Is the message being sent to the server? Is the server sending the message to the client? You can answer these questions with just a few println.
Once you know where (in your code, which method) it is failing you can post a more specific question if you still need help.
Also when you have a problem, please explain what problem it is really, in detail. Does the application crash? Does it stop sending messages to everybody? "my program stops sending messages" is a little bit vague.
EDIT: Well, now that I see the code, please, do not do this:
void send(ChatMessage cm){
try {
out.writeObject(cm);
out.flush();
} catch (Exception e) {
}
}
If an exception is thrown, you won't notice.
You should add:
e.printStackTrace();
inside every catch() block so you can see errors in console when they occur.
Nobody likes red messages in console, but hiding them is not going to help. Always print errors, or log them, or both :)
Related
I'm trying to make a chat function with Java. The problem is that I have two classes. One for Client and one for ClientGUI. Where the Client one has the logic parts and the ClientGUI the design. The problem is getting is in row 46 where new ListenFromServer().start(); is getting a error
No enclosing instance of type Controller is accessible. Must
qualify the allocation with an enclosing instance of type
COntroller(e.g. x.new A() where x is an instance of Controller).
So what I did was that I changedpublic class ListenFromServer extends Thread to a static. Which means public static class ListenFromServer extends Thread and now the problem that I'm getting
Error connecting to the server: java.net.ConnectException: connect: Address is invalid on local machine, or port is not valid on remote machine
Controller (Client logic)
package Server;
import java.io.*;
import java.net.*;
import java.util.*;
public class Controller {
private static ObjectInputStream input;
private static ObjectOutputStream output;
private static Socket socket;
private static ClientGUI clientgui;
private static String username;
private static String server;
private static int port;
public static boolean startClient(){
try{
socket = new Socket(server, port);
}catch (Exception ex){
System.out.print("Error connecting to the server: " + ex);
return false;
}
String message = "Connection is accepted; " + socket.getInetAddress() +" - "+ socket.getPort();
System.out.println(message);
try {
input=new ObjectInputStream(socket.getInputStream());
output =new ObjectOutputStream(socket.getOutputStream());
}
catch (IOException io) {
System.out.print("Exception creating new Input/Output Stream: "+ io);
return false;
}
**********new ListenFromServer().start();********* //The problem is here
try {
output.writeObject(username);
}
catch(IOException io) {
System.out.print("Exception doing login: " + io);
disconnect();
return false;
}
return true;
}
private void display(String message) {
if(clientgui == null)
System.out.println(message);
else
clientgui.append(message +"\n");
}
public static void sendMessage(Message message) {
try {
output.writeObject(message);
}
catch(IOException exd) {
System.out.print("Eceptionwritingtoserver: " + exd);
}
}
private static void disconnect() {
try {
if(input != null)
input.close();
}catch (Exception ex){}
try{
if(output != null)
output.close();
}catch(Exception ex){}
try{
if(socket != null)
socket.close();
}catch(Exception ex){};
if (clientgui != null)
clientgui.connectionFailed();
}
public class ListenFromServer extends Thread{
public void run() {
while(true){
try{
String message = (String) input.readObject();
if(clientgui == null){
System.out.println(message);
System.out.print(":");
}
else {
clientgui.append(message);
}
}
catch(IOException io){
System.out.print("Server has closed the connection");
if(clientgui != null)
clientgui.connectionFailed();
break;
}
catch(ClassNotFoundException classex){
}
}
}
}
}
ClientGUI
package Server;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/*
* The Client with its GUI
*/
public class ClientGUI extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JLabel lblusername;
private JTextField textfieldusername, textfieldserver, textfieldportnumber;
private JButton btnlogin, btnlogout, btnonline;
private JTextArea textareamessage;
private boolean connected;
private Client client;
private int defaultPort;
private String defaultHost;
ClientGUI(String host, int port) {
super("Chat Client");
defaultPort = port;
defaultHost = host;
JPanel northPanel = new JPanel(new GridLayout(2,2));
JPanel serverAndPort = new JPanel(new GridLayout(1,2, 2, 2));
JLabel lblserveraddress = new JLabel("Server Address: ");
JLabel lblchat = new JLabel(" #BallIsLife");
JLabel lblportnumber = new JLabel("Port Number: ");
textfieldserver = new JTextField(host);
textfieldserver.setHorizontalAlignment(SwingConstants.LEFT);
textfieldserver.setFont(new Font("Tahoma", Font.PLAIN, 20));
textfieldportnumber = new JTextField("" + port);
textfieldportnumber.setFont(new Font("Tahoma", Font.PLAIN, 20));
textfieldportnumber.setHorizontalAlignment(SwingConstants.LEFT);
lblserveraddress.setFont(new Font("Tahoma", Font.PLAIN, 19));
serverAndPort.add(lblserveraddress);
serverAndPort.add(textfieldserver);
serverAndPort.add(lblchat);
serverAndPort.add(lblportnumber);
serverAndPort.add(textfieldportnumber);
lblchat.setForeground(Color.RED);
lblportnumber.setFont(new Font("Tahoma", Font.PLAIN, 19));
northPanel.add(serverAndPort);
getContentPane().add(northPanel, BorderLayout.NORTH);
JPanel panelbtn = new JPanel();
northPanel.add(panelbtn);
btnlogin = new JButton("Login");
panelbtn.add(btnlogin);
btnlogin.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnlogin.addActionListener(this);
btnonline = new JButton("Online");
panelbtn.add(btnonline);
btnonline.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnonline.addActionListener(this);
btnonline.setEnabled(false);
btnlogout = new JButton("Logout");
panelbtn.add(btnlogout);
btnlogout.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnlogout.addActionListener(this);
btnlogout.setEnabled(false);
JButton btnPicture = new JButton("Picture");
btnPicture.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnPicture.setEnabled(false);
panelbtn.add(btnPicture);
textareamessage = new JTextArea("Welcome to the #BallIsLife Chat room.\n");
textareamessage.setFont(new Font("Monospaced", Font.PLAIN, 15));
textareamessage.setLineWrap(true);
textareamessage.setEditable(false);
JPanel centerPanel = new JPanel(new GridLayout(1,1));
JScrollPane scrollPane = new JScrollPane(textareamessage);
centerPanel.add(scrollPane);
getContentPane().add(centerPanel, BorderLayout.CENTER);
JPanel southPanel = new JPanel();
getContentPane().add(southPanel, BorderLayout.SOUTH);
lblusername = new JLabel("Enter your username", SwingConstants.CENTER);
lblusername.setFont(new Font("Tahoma", Font.PLAIN, 15));
southPanel.add(lblusername);
textfieldusername = new JTextField("Write your username here.");
textfieldusername.setFont(new Font("Tahoma", Font.PLAIN, 14));
textfieldusername.setColumns(50);
southPanel.add(textfieldusername);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(823, 665);
setVisible(true);
}
//Logiken
void append(String str) {
textareamessage.append(str);
textareamessage.setCaretPosition(textareamessage.getText().length() - 1);
}
void connectionFailed() {
btnlogin.setEnabled(true);
btnlogout.setEnabled(false);
btnonline.setEnabled(false);
lblusername.setText("Enter your username");
textfieldusername.setText("Write your username here");
textfieldportnumber.setText("" + defaultPort);
textfieldserver.setText(defaultHost);
textfieldserver.setEditable(false);
textfieldportnumber.setEditable(false);
textfieldusername.removeActionListener(this);
connected = false;
}
//
public void actionPerformed(ActionEvent e) {
Object button = e.getSource();
if(button == btnlogout) {
Controller.sendMessage(new Message("", Message.LOGOUT)); //Ändra till Chatmessage klass
btnlogin.setText("Login");
return;
}
if(button == btnonline) {
Controller.sendMessage(new Message("", Message.ONLINE)); //Ändra till Chatmessage klass
return;
}
if(connected) {
Controller.sendMessage(new Message(textfieldusername.getText(), Message.MESSAGE)); //Ändra till Chatmessage klass
textfieldusername.setText("");
return;
}
if(button == btnlogin) {
String username = textfieldusername.getText();
if(username.length() == 0)
return;
String server = textfieldserver.getText();
if(server.length() == 0)
return;
String portNumber = textfieldportnumber.getText();
if(portNumber.length() == 0)
return;
int port = 0;
try {
port = Integer.parseInt(portNumber);
}
catch(Exception en) {
return;
}
client = new Client(server, username, port, this);
if(!Controller.startClient())
return;
}
connected = true;
textfieldusername.setText("");
btnlogin.setText("Send message");
btnlogin.setEnabled(true);
btnlogout.setEnabled(true);
btnonline.setEnabled(true);
textfieldserver.setEditable(false);
textfieldportnumber.setEditable(false);
textfieldusername.addActionListener(this);
}
// to start the whole thing the server
public static void main(String[] args) {
new ClientGUI("localhost", 1500);
}
}
Server
package Server;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
/*
* The server that can be run both as a console application or a GUI
*/
public class Server {
// a unique ID for each connection
private static int uniqueId;
// an ArrayList to keep the list of the Client
private ArrayList<ClientThread> al;
// if I am in a GUI
private ServerGUI sg;
// to display time
private SimpleDateFormat sdf;
// the port number to listen for connection
private int port;
// the boolean that will be turned of to stop the server
private boolean keepGoing;
/*
* server constructor that receive the port to listen to for connection as parameter
* in console
*/
public Server(int port) {
this(port, null);
}
public Server(int port, ServerGUI sg) {
// GUI or not
this.sg = sg;
// the port
this.port = port;
// to display hh:mm:ss
sdf = new SimpleDateFormat("HH:mm:ss");
// ArrayList for the Client list
al = new ArrayList<ClientThread>();
}
public void start() {
keepGoing = true;
/* create socket server and wait for connection requests */
try
{
// the socket used by the server
ServerSocket serverSocket = new ServerSocket(port);
// infinite loop to wait for connections
while(keepGoing)
{
// format message saying we are waiting
display("Server waiting for Clients on port " + port + ".");
Socket socket = serverSocket.accept(); // accept connection
// if I was asked to stop
if(!keepGoing)
break;
ClientThread t = new ClientThread(socket); // make a thread of it
al.add(t); // save it in the ArrayList
t.start();
}
// I was asked to stop
try {
serverSocket.close();
for(int i = 0; i < al.size(); ++i) {
ClientThread tc = al.get(i);
try {
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
}
catch(IOException ioE) {
// not much I can do
}
}
}
catch(Exception e) {
display("Exception closing the server and clients: " + e);
}
}
// something went bad
catch (IOException e) {
String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
display(msg);
}
}
/*
* For the GUI to stop the server
*/
protected void stop() {
keepGoing = false;
// connect to myself as Client to exit statement
// Socket socket = serverSocket.accept();
try {
new Socket("localhost", port);
}
catch(Exception e) {
// nothing I can really do
}
}
/*
* Display an event (not a message) to the console or the GUI
*/
private void display(String msg) {
String time = sdf.format(new Date()) + " " + msg;
if(sg == null)
System.out.println(time);
else
sg.appendRoom(null,time + "\n");
}
/*
* to broadcast a message to all Clients
*/
private synchronized void broadcast(String message) {
// add HH:mm:ss and \n to the message
String time = sdf.format(new Date());
String messageLf = time + " " + message + "\n";
// display message on console or GUI
if(sg == null)
System.out.print(messageLf);
else
sg.appendRoom(messageLf,null); // append in the room window
// we loop in reverse order in case we would have to remove a Client
// because it has disconnected
for(int i = al.size(); --i >= 0;) {
ClientThread ct = al.get(i);
// try to write to the Client if it fails remove it from the list
if(!ct.writeMsg(messageLf)) {
al.remove(i);
display("Disconnected Client " + ct.username + " removed from list.");
}
}
}
// for a client who logoff using the LOGOUT message
synchronized void remove(int id) {
// scan the array list until we found the Id
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
// found it
if(ct.id == id) {
al.remove(i);
return;
}
}
}
/*
* To run as a console application just open a console window and:
* > java Server
* > java Server portNumber
* If the port number is not specified 1500 is used
*/
public static void main(String[] args) {
// start server on port 1500 unless a PortNumber is specified
int portNumber = 1500;
switch(args.length) {
case 1:
try {
portNumber = Integer.parseInt(args[0]);
}
catch(Exception e) {
System.out.println("Invalid port number.");
System.out.println("Usage is: > java Server [portNumber]");
return;
}
case 0:
break;
default:
System.out.println("Usage is: > java Server [portNumber]");
return;
}
// create a server object and start it
Server server = new Server(portNumber);
server.start();
}
/** One instance of this thread will run for each client */
class ClientThread extends Thread {
// the socket where to listen/talk
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
// my unique id (easier for deconnection)
int id;
// the Username of the Client
String username;
// the only type of message a will receive
Message cm;
// the date I connect
String date;
// Constructore
ClientThread(Socket socket) {
// a unique id
id = ++uniqueId;
this.socket = socket;
/* Creating both Data Stream */
System.out.println("Thread trying to create Object Input/Output Streams");
try
{
// create output first
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
// read the username
username = (String) sInput.readObject();
display(username + " just connected.");
}
catch (IOException e) {
display("Exception creating new Input/output Streams: " + e);
return;
}
// have to catch ClassNotFoundException
// but I read a String, I am sure it will work
catch (ClassNotFoundException e) {
}
date = new Date().toString() + "\n";
}
// what will run forever
public void run() {
// to loop until LOGOUT
boolean keepGoing = true;
while(keepGoing) {
// read a String (which is an object)
try {
cm = (Message) sInput.readObject();
}
catch (IOException e) {
display(username + " Exception reading Streams: " + e);
break;
}
catch(ClassNotFoundException e2) {
break;
}
// the messaage part of the ChatMessage
String message = cm.getMessage();
// Switch on the type of message receive
switch(cm.getType()) {
case Message.MESSAGE:
broadcast(username + ": " + message);
break;
case Message.LOGOUT:
display(username + " disconnected with a LOGOUT message.");
keepGoing = false;
break;
case Message.ONLINE:
writeMsg("List of the users connected at " + sdf.format(new Date()) + "\n");
// scan al the users connected
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
writeMsg((i+1) + ") " + ct.username + " since " + ct.date);
}
break;
}
}
// remove myself from the arrayList containing the list of the
// connected Clients
remove(id);
close();
}
// try to close everything
private void close() {
// try to close the connection
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {};
try {
if(socket != null) socket.close();
}
catch (Exception e) {}
}
/*
* Write a String to the Client output stream
*/
private boolean writeMsg(String msg) {
// if Client is still connected send the message to it
if(!socket.isConnected()) {
close();
return false;
}
// write the message to the stream
try {
sOutput.writeObject(msg);
}
// if an error occurs, do not abort just inform the user
catch(IOException e) {
display("Error sending message to " + username);
display(e.toString());
}
return true;
}
}
}
ServerGUI
package Server;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/*
* The server as a GUI
*/
public class ServerGUI extends JFrame implements ActionListener, WindowListener {
private static final long serialVersionUID = 1L;
// the stop and start buttons
private JButton stopStart, saveLog;
// JTextArea for the chat room and the events
private JTextArea chat;
// private JTextArea event;
// The port number
private JTextField tfPortNumber;
// my server
private Server server;
// server constructor that receive the port to listen to for connection as
// parameter
ServerGUI(int port) {
super("Chat Server");
server = null;
// in the NorthPanel the PortNumber the Start and Stop buttons
JPanel north = new JPanel();
north.add(new JLabel("Port number: "));
tfPortNumber = new JTextField("" + port);
north.add(tfPortNumber);
// to stop or start the server, we start with "Start"
stopStart = new JButton("Start");
stopStart.addActionListener(this);
saveLog = new JButton("Save log");
saveLog.addActionListener(this);
north.add(stopStart);
north.add(saveLog);
add(north, BorderLayout.NORTH);
// the event and chat room
JPanel center = new JPanel(new GridLayout());
chat = new JTextArea(120, 20);
chat.setEditable(false);
chat.setWrapStyleWord(true);
chat.setLineWrap(true);
appendRoom(null, "Chat room and Events log for server.\n");
center.add(new JScrollPane(chat));
// event = new JTextArea(80,80);
// event.setEditable(false);
// appendEvent("Events log.\n");
// center.add(new JScrollPane(event));
add(center);
// need to be informed when the user click the close button on the frame
addWindowListener(this);
setSize(450, 600);
setVisible(true);
}
public void writeLog() {
try {
JFileChooser chooser = new JFileChooser();
String content = chat.getText();
int actionDialog = chooser.showSaveDialog(this);
content = content.replaceAll("(?!\\r)\\n", "\r\n");
if (actionDialog == JFileChooser.APPROVE_OPTION) {
File file = new File(chooser.getSelectedFile() + ".txt");
// if file doesnt exists, then create it
// if (!file.exists()) {
// file.createNewFile();
// }
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
}
} catch (IOException ee) {
ee.printStackTrace();
}
// JFileChooser chooser = new JFileChooser();
// // chooser.setCurrentDirectory(new File("./"));
// int actionDialog = chooser.showSaveDialog(this);
// if (actionDialog == JFileChooser.APPROVE_OPTION) {
// File fileName = new File(chooser.getSelectedFile() + "");
// if (fileName == null)
// // return;
// if (fileName.exists()) {
// actionDialog = JOptionPane.showConfirmDialog(this,
// "Replace existing file?");
// if (actionDialog == JOptionPane.NO_OPTION)
// return;
// }
// try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
// new FileOutputStream(fileName), "ISO-8859-1"))) {
// bw.write(saveText);
// // bw.newLine();
// bw.flush();
// }
// }
}
// append message to the two JTextArea
// position at the end
void appendRoom(String chatStr, String eventStr) {
chat.append(chatStr);
chat.append(eventStr);
// chat.setCaretPosition(chat.getText().length() - 1);
}
// void appendEvent(String str) {
// event.append(str);
// event.setCaretPosition(chat.getText().length() - 1);
//
// }
// start or stop where clicked
public void actionPerformed(ActionEvent e) {
// if running we have to stop
if (e.getSource() == saveLog) {
writeLog();
} else if (e.getSource() == stopStart) {
if (server != null) {
server.stop();
server = null;
tfPortNumber.setEditable(true);
stopStart.setText("Start");
return;
}
// OK start the server
int port;
try {
port = Integer.parseInt(tfPortNumber.getText().trim());
} catch (Exception er) {
appendRoom(null, "Invalid port number");
return;
}
// ceate a new Server
server = new Server(port, this);
// and start it as a thread
new ServerRunning().start();
stopStart.setText("Stop");
tfPortNumber.setEditable(false);
}
}
/*
* A thread to run the Server
*/
class ServerRunning extends Thread {
public void run() {
server.start(); // should execute until if fails
// the server failed
stopStart.setText("Start");
tfPortNumber.setEditable(true);
appendRoom(null, "Server closed\n");
server = null;
}
}
// entry point to start the Server
public static void main(String[] arg) {
// start server default port 1500
new ServerGUI(1500);
}
/*
* If the user click the X button to close the application I need to close
* the connection with the server to free the port
*/
public void windowClosing(WindowEvent e) {
// if my Server exist
if (server != null) {
try {
server.stop(); // ask the server to close the conection
} catch (Exception eClose) {
}
server = null;
}
// dispose the frame
dispose();
System.exit(0);
}
// I can ignore the other WindowListener method
public void windowClosed(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
// /*
// * A thread to run the Server
// */
// class ServerRunning extends Thread {
// public void run() {
// server.start(); // should execute until if fails
// // the server failed
// stopStart.setText("Start");
// tfPortNumber.setEditable(true);
// appendRoom(null, "Server closed\n");
// server = null;
// }
// }
}
Message
package Server;
import java.io.Serializable;
//Klassen som kollar vad för typ av message
public class Message implements Serializable {
protected static final long serialVersionUID = 42L;
static final int ONLINE = 0;
static final int MESSAGE = 1;
static final int LOGOUT = 2;
private int SAVELOG = 3;
private String message;
private int type;
public Message(String message, int type){
this.type = type;
this.message = message;
}
public int getType(){
return type;
}
public String getMessage(){
return message;
}
}
Make your inner class ListenFromServer static, since you are referring to it from a static method
public class Controller {
...
public static class ListenFromServer {
...
}
}
I have a multi-thread chatroom that connects to one server. They all connect, login, and message independently of each other just fine, but when I log off with one of the clients (and the server does a socket.close() for that instance of the client) all clients are logged off. I looked at a bunch of other questions on stackoverflow before posting this, but none of them had the same issue as mine (that I found). Note: All the clients were running locally on my computer, 2+ of them, and that's how I encountered the bug. Could them being on the same IP (though everything is done on my localhost..) cause this to happen? Any help or insight as to what is causing this issue and how I could resolve it would be great. When the issue occurs it also outputs this to the console:
Socket: Socket[addr=localhost/127.0.0.1,port=4000,localport=55650]
Here is the code (how to recreate the bug is at the bottom):
Server class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
public class ChatServer {
private static final int PORT = 4000;
private static HashSet<String> names = new HashSet<String>();
private static HashSet<ObjectOutputStream> outputs =
new HashSet<ObjectOutputStream>();
public static void main(String[] args) throws IOException{
System.out.println("The chat server is running...");
ServerSocket listener = new ServerSocket(PORT);
while(true){
new Handler(listener.accept()).start();
}
}
private static class Handler extends Thread{
private String name;
private Socket socket;
private ObjectInputStream in;
private ObjectOutputStream out;
private boolean loggedOut;
public Handler(Socket socket){
this.socket = socket;
}
public void run(){
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
loggedOut = false;
while(true){
Message message = (Message) in.readObject();
System.out.println("Server recieved login message!");
if(message.getNumber() == 0){
name = message.getName();
synchronized(names){
if(!names.contains(name)){
names.add(name);
break;
}else{
Message nameTaken = new Message(null, 3);
sendMessage(out, nameTaken);
}
}
}
}
synchronized(outputs){
outputs.add(out);
}
for(ObjectOutputStream output: outputs){
Message response = new Message(name, name + " has logged on.", 0);
sendMessage(output, response);
}
while(true){
System.out.println("Waiting for message...");
Message message = (Message) in.readObject();
Message response = null;
if(message.getNumber() == 1 && message.getMessage() != null){
response = new Message(message.getName(),
message.getMessage(), 1);
}else if(message.getNumber() == 2){
response = new Message(message.getName(), message.getName() +
" has logged off.", 2);
loggedOut = true;
}
for(ObjectOutputStream output: outputs){
sendMessage(output, response);
}
if(loggedOut) break;
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
if(name != null) names.remove(name);
if(out != null) outputs.remove(out);
try{
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
private void sendMessage(ObjectOutputStream out, Message message){
ObjectOutputStream outPutMessage = out;
Message response = message;
try {
outPutMessage.writeObject(response);
outPutMessage.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
Client class:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ChatClient extends JFrame {
private JTextField inputField;
private JTextField nameField;
private JTextArea textArea;
private JButton loginButton;
private JButton logoutButton;
private JButton connectButton;
private JScrollPane textScroll;
private JScrollPane listScroll;
private JPanel textPanel;
private JPanel connectPanel;
private JPanel listPanel;
private JPanel inputPanel;
private JPanel namePanel;
private JPanel inputAndDisplayPanel;
private JPanel listAndLogoutPanel;
private ArrayList<String> stringList;
private JList list;
private final int CELL_WIDTH = 100;
private ObjectOutputStream out;
private ObjectInputStream in;
private JFrame chatFrame;
private ChatClient client;
private String name;
private final int PORT = 4000;
private boolean needServerData;
private boolean loggedIn;
private boolean previouslyLoggedIn;
private String serverAddress = null;
private Socket socket = null;
private void run() throws IOException, ClassNotFoundException{
needServerData = true;
loggedIn = true;
while(true){
//Loops before a user is logged in, verifies that the host is usable
while (socket == null) {
if (needServerData) {
try {
connectButton.setEnabled(false);
serverAddress = JOptionPane.showInputDialog(client,
"Enter server address: ", "Server Address",
JOptionPane.QUESTION_MESSAGE);
if(serverAddress == null){
JOptionPane.showMessageDialog(client,
"Click 'Connect' to re-enter server address.",
"Info", JOptionPane.PLAIN_MESSAGE);
needServerData = false;
connectButton.setEnabled(true);
}else if(serverAddress.equals("")){
JOptionPane.showMessageDialog(client,
"Invalid input! Enter a valid server address.",
"Error", JOptionPane.ERROR_MESSAGE);
}else {
socket = new Socket(serverAddress, PORT);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
loginButton.setEnabled(true);
logoutButton.setEnabled(false);
nameField.setEnabled(true);
connectButton.setEnabled(false);
}
} catch (UnknownHostException e1) {
JOptionPane.showMessageDialog(client,
"Error: Unknown host!", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
}
/*Loops after the user is logged in (will output to the textarea that that user logged in),
* reads in messages from server to append to the textarea and also determines if a user is
* logging out. Changes editable/enabled of buttons and text fields accordingly.
*/
if(loggedIn) {
Message message = (Message) in.readObject();
if (message.getNumber() == 1) {
textArea.append(message.getName() + ": "
+ message.getMessage() + "\n");
} else if (message.getNumber() == 0) {
inputField.setEditable(true);
textArea.append(message.getMessage() + "\n");
loginButton.setEnabled(false);
logoutButton.setEnabled(true);
} else if (message.getNumber() == 2) {
inputField.setText(null);
inputField.setEditable(false);
nameField.setText(null);
nameField.setEnabled(false);
connectButton.setEnabled(true);
logoutButton.setEnabled(false);
loggedIn = false;
previouslyLoggedIn = true;
textArea.append(message.getMessage() + "\n");
System.out.println("Socket: " + socket);
} else {
JOptionPane.showMessageDialog(client,
"Error: That name is taken!", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
}
}
private String getServerAddress(){
return JOptionPane.showInputDialog(client, "Enter server address: ",
"Server Address", JOptionPane.QUESTION_MESSAGE);
}
public static void main(String[] args) throws IOException, ClassNotFoundException{
ChatClient client = new ChatClient();
try {
client.run();
} catch (IOException e) {
e.printStackTrace();
}
}
public ChatClient(){
//GUI Formatting Stuff
inputField = new JTextField(30);
nameField = new JTextField(10);
textArea = new JTextArea(25, 30);
loginButton = new JButton("Login");
logoutButton = new JButton("Logout");
connectButton = new JButton("Connect");
textScroll = new JScrollPane(textArea,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
textPanel = new JPanel();
listPanel = new JPanel();
inputPanel = new JPanel();
namePanel = new JPanel();
connectPanel = new JPanel();
textArea.setEditable(false);
textPanel.add(textScroll);
stringList = new ArrayList<String>();
list = new JList(stringList.toArray());
list.setFixedCellWidth(CELL_WIDTH);
listScroll = new JScrollPane(list);
listPanel.add(listScroll);
listAndLogoutPanel = new JPanel(new BorderLayout());
listAndLogoutPanel.add(listPanel, BorderLayout.CENTER);
listAndLogoutPanel.add(logoutButton, BorderLayout.SOUTH);
listAndLogoutPanel.add(loginButton, BorderLayout.NORTH);
inputField.setEditable(false);
inputPanel.add(inputField);
inputAndDisplayPanel = new JPanel(new BorderLayout());
inputAndDisplayPanel.add(textPanel, BorderLayout.CENTER);
inputAndDisplayPanel.add(inputPanel, BorderLayout.SOUTH);
nameField.setEnabled(false);
loginButton.setEnabled(false);
logoutButton.setEnabled(false);
namePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
namePanel.add(new JLabel("Name: "));
namePanel.add(nameField);
connectPanel.add(connectButton);
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(namePanel, BorderLayout.WEST);
topPanel.add(connectPanel, BorderLayout.EAST);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(inputAndDisplayPanel, BorderLayout.CENTER);
centerPanel.add(topPanel, BorderLayout.NORTH);
JPanel eastPanel = new JPanel(new BorderLayout());
eastPanel.add(listAndLogoutPanel, BorderLayout.CENTER);
setLayout(new BorderLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
add(centerPanel, BorderLayout.CENTER);
add(eastPanel, BorderLayout.EAST);
pack();
setLocationRelativeTo(null);
//Listeners
loginButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
name = nameField.getText();
if(name.trim().length() < 3 || name.length() > 15 || name == null){
JOptionPane.showMessageDialog(client,
"Error: Name must be between 3 and 15 characters long.", "Error",
JOptionPane.ERROR_MESSAGE);
}else{
Message message = new Message(name, 0);
try {
out.writeObject(message);
out.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
loggedIn = true;
}
}
});
connectButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
needServerData = true;
if(previouslyLoggedIn) socket = null;
}
});
inputField.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
Message message = new Message(name, inputField.getText(), 1);
try {
out.writeObject(message);
out.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
inputField.setText(null);
}
});
logoutButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
Message message = new Message(name, 2);
try {
out.writeObject(message);
out.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
inputField.setText(null);
}
});
}
}
Message class:
import java.io.Serializable;
public class Message implements Serializable{
private int number;
private String message;
private String name;
public Message(String name, int number){
this.name = name;
this.number = number;
}
public Message(String name, String message, int number){
this.message = message;
this.number = number;
this.name = name;
}
public boolean isLogin(){
if(number == 0) return true;
return false;
}
public boolean isMessage(){
if(number == 1) return true;
return false;
}
public boolean isLogout(){
if(number == 2) return true;
return false;
}
public int getNumber() {
return number;
}
public String getMessage() {
return message;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I know this is a big block of code and not that neatly documented/formatted, so I apologize for that. I'm just posting the whole thing so you can duplicate the problem by running the code in it's entirety. Additionally, ignore the JList as I haven't gotten to that yet since I encountered and haven't been able to resolve the logging off/socket issue. To recreate the bug, go through the following steps:
Run the Server class
Run a client class, enter "localhost" as the server address, then enter a name and click log-in
Run another client class and follow step 2
Click log-off on one of the client classes, and you'll see the other is also logged off.
Thanks in advance for any help, I appreciate it!
In your ChatClient class, you need to change the line
} else if (message.getNumber() == 2) {
to
} else if (message.getNumber() == 2 && message.getName().equals(name)) {
Because the way it is currently, each chat client receives the message that a client has been logged out, and each client is responding to that by logging out. You will need to handle the additional case afterwards that message.getNumber() == 2, because as it stands now you will assume that it means the name was taken.
I found this code in the book Java 2 : Exam Guide by Barry Boone and William R Stanek.
This code is giving me the internal IP 127.0.0.1
But I want something like 115.245.12.61.
How could I get this.
I am providing my code below
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class SingleChat extends Panel {
Socket sock;
TextArea ta_RecText;
private GridBagConstraints c;
private GridBagLayout gridBag;
private Frame frame;
private Label label;
public int port = 5001;
private TextField tf_Send;
private DataOutputStream remoteOut;
static String szUserName = "";
public static void main (String [] args){
final Frame f = new Frame("Waiting For Connection...");
String s = null;
Color fore , back;
fore = new java.awt.Color(255, 255, 255);
back = new java.awt.Color(0, 173, 232);
if (args.length > 0)
s = args[0];
SingleChat chat = new SingleChat(f);
Panel pane = new Panel(), butPane = new Panel();
Label l_Label = new Label("//RADconnect");
l_Label.setForeground(fore);
l_Label.setBackground(back);
l_Label.setFont(new java.awt.Font("Lucida Console", 0, 24));
pane.add(l_Label);
f.setForeground(fore);
f.setBackground(back);
f.add("North", pane);
f.add("Center", chat);
Button but = new Button("EXIT");
but.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
f.dispose();
System.exit(0);
}
});
but.setBackground(fore);
but.setForeground(back);
butPane.add(but);
f.add("South", butPane);
f.setSize(450, 350);
f.show();
if (s == null){
chat.server();
}
else{
chat.client(s);
}
}
public SingleChat (Frame f){
frame = f;
frame.addWindowListener(new WindowExitHandler());
Insets insets = new Insets (10, 20, 5, 10);
gridBag = new GridBagLayout();
setLayout(gridBag);
c = new GridBagConstraints();
c.insets = insets;
c.gridx = 0;
c.gridx = 0;
label = new Label("Text To Send:");
gridBag.setConstraints(label, c);
add(label);
c.gridx = 1;
tf_Send = new TextField(40);
tf_Send.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
//Intercept Messages And Send Them
String msg = tf_Send.getText();
remoteOut.writeUTF(szUserName+": "+msg);
tf_Send.setText("");
ta_RecText.append(szUserName+": "+msg+"\n");
} catch (IOException x) {
displayMsg(x.getMessage()+": Connection to Peer Lost");
}
}
});
gridBag.setConstraints(tf_Send, c);
add(tf_Send);
c.gridy = 1;
c.gridx = 0;
label = new Label("Text Recived:");
gridBag.setConstraints(label, c);
add(label);
c.gridx = 1;
ta_RecText = new TextArea(5, 40);
gridBag.setConstraints(ta_RecText, c);
add(ta_RecText);
ta_RecText.setForeground(Color.BLACK);
tf_Send.setForeground(Color.BLACK);
}
private void server(){
ServerSocket sv_Sock = null;
try {
InetAddress sv_Addr = InetAddress.getByName(null);
displayMsg("Waiting For Connection on "+sv_Addr.getHostAddress()+":"+port);
sv_Sock = new ServerSocket(port, 1);
sock = sv_Sock.accept();
displayMsg("Accepted Connection From "+sock.getInetAddress().getHostName());
remoteOut = new DataOutputStream(sock.getOutputStream());
new SingleChatRecive(this).start();
} catch (IOException x){
displayMsg(x.getMessage()+": Falied to connect to client");
}
finally {
if (sv_Sock != null){
try{
sv_Sock.close();
} catch (IOException x){
}
}
}
}
private void client(String sv_Name){
try {
if (sv_Name.equals("local")){
sv_Name = null;
}
InetAddress sv_Addr = InetAddress.getByName(sv_Name);
sock = new Socket(sv_Addr.getHostName(), port);
remoteOut = new DataOutputStream(sock.getOutputStream());
displayMsg("Connected to Server "+sv_Addr.getHostName()+":"+sock.getPort());
new SingleChatRecive(this).start();
} catch (IOException e){
displayMsg(e.getMessage()+": Failed to connect to server");
}
}
void displayMsg(String sz_Title){
frame.setTitle(sz_Title);
}
protected void finalize() throws Throwable {
try {
if (remoteOut != null){
remoteOut.close();
}
if (sock != null){
sock.close();
}
} catch (IOException e){
}
super.finalize();
}
class WindowExitHandler extends WindowAdapter{
public void windowClosing(WindowEvent e){
Window w = e.getWindow();
w.setVisible(false);
w.dispose();
System.exit(0);
}
}
void saveData(){
}
}
class SingleChatRecive extends Thread {
private SingleChat chat;
private DataInputStream remoteIn;
private boolean listening = true;
public SingleChatRecive(SingleChat chat){
this.chat = chat;
}
public synchronized void run(){
String s;
try {
remoteIn = new DataInputStream(chat.sock.getInputStream());
while (listening) {
s = remoteIn.readUTF();
chat.ta_RecText.append(s+"\n");
}
} catch (IOException e){
chat.displayMsg(e.getMessage()+": Connection to Peer Lost!");
} finally {
try {
if (remoteIn != null) {
remoteIn.close();
}
} catch (IOException e){
}
}
}
}
What changes could be done to avoid getting 127.0.0.1
THANKS
From your code:
InetAddress sv_Addr = InetAddress.getByName(null);
From the javadoc: "If the host is null then an InetAddress representing an address of the loopback interface is returned."
The IP address of the loopback interface is 127.0.0.1.
To get other IP addresses you must exchange null with a valid host name. Your local machine name could do if that is where you are running your server, but any valid host name should work.
InetAddress sv_Addr = InetAddress.getByName("myserver.mydomain.com");
Consider the following class that just gets an IP and port number :
package view;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
/**
* Server side
* #author X
*
*/
class ServerConnector implements ActionListener
{
private JFrame m_frame = null;
private JTextField m_serverIP;
private JTextField m_serverPort; // you can use also JPasswordField
private JButton m_submitButton;
// location of the jframe
private final int m_centerX = 500;
private final int m_centerY = 300;
// dimensions of the jframe
private final int m_sizeX = 1650;
private final int m_sizeY = 150;
private String m_ip;
private String m_port;
private boolean ready = false;
/**
* Ctor
*/
ServerConnector()
{
m_frame = new JFrame("Sever Side Listener");
m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
m_serverIP = new JTextField(20);
m_serverPort = new JTextField(20);
JPanel gui = new JPanel(new BorderLayout(3,3));
gui.setBorder(new EmptyBorder(5,5,5,5));
gui.setSize(m_sizeX , m_sizeY);
m_frame.setContentPane(gui);
JPanel labels = new JPanel(new GridLayout(0,1));
JPanel controls = new JPanel(new GridLayout(0,1));
gui.add(labels, BorderLayout.WEST);
gui.add(controls, BorderLayout.CENTER);
labels.add(new JLabel("Server IP: "));
controls.add(m_serverIP);
labels.add(new JLabel("Server Port: "));
controls.add(m_serverPort);
m_submitButton = new JButton("Start Listening");
m_submitButton.addActionListener(this);
gui.add(m_submitButton, BorderLayout.SOUTH);
m_frame.setLocation(m_centerX , m_centerY);
m_frame.setSize(m_sizeX , m_sizeY);
m_frame.pack();
m_frame.setVisible(true);
}
public static void main(String[] args) {
new ServerConnector();
}
#Override
public void actionPerformed(ActionEvent event) {
Object object = event.getSource();
if (object == this.m_submitButton)
{
// grab all values from the connection box
// if one of them is missing then display an alert message
String ip = this.m_serverIP.getText().trim();
String port = this.m_serverPort.getText().trim();
if (ip.length() == 0)
{
JOptionPane.showMessageDialog(null, "Please enter IP address !");
return;
}
if (port.length() == 0)
{
JOptionPane.showMessageDialog(null, "Please enter Port number!");
return;
}
int s_port = 0;
try
{
// try parse the Port number
// throws exception when an incorrect IP address
// is entered , and caught in the catch block
s_port = Integer.parseInt(port);
}
catch(Exception exp)
{
JOptionPane.showMessageDialog(null, "Port number is incorrect!");
return;
}
try
{
// try parse the IP address
// throws exception when an incorrect IP address
// is entered , and caught in the catch block
InetAddress.getByName(ip);
}
catch(Exception exp)
{
JOptionPane.showMessageDialog(null, "IP address is incorrect!");
return;
}
m_frame.dispose();
this.m_ip = ip;
this.m_port = port;
ready = true;
// new ServerGUI(ip , s_port);
}
}
public boolean isReady()
{
return this.ready;
}
/**
*
* #return
*/
public String[] getIPandPort()
{
String[] ipPort = new String[2];
ipPort[0] = this.m_ip;
ipPort[1] = this.m_port;
return ipPort;
}
}
And the would be controller class
public class ServerController {
String m_ip;
int m_port;
public static void main(String args[])
{
ServerConnector sc = new ServerConnector();
while (!sc.isReady())
{
// run
}
// get IP and port
String[] ipPort = sc.getIPandPort();
System.out.println("IP is :" + ipPort[0] + " and port is :" + ipPort[1]);
}
}
For now ServerController is in a while(true) loop , until the user has entered the IP and Port.
How can I avoid this kind of dependency (avoid the while loop) ?
First of all, get rid of the while (true) loop as its only purpose will be to mess your code up.
A general solution is to get the information from the user in code that blocks program flow. A problem occurs, though if this is needed in a GUI that cannot have its event thread blocked.
One Swing solution is as we have discussed previously in your previous question: use a modal dialog to get the information. The modality of the dialog will halt the program flow in the calling code until the dialog is handled.
If you want to avoid use of modal dialogs, then another general event-driven solution is to use a observer design pattern -- have one object be notified by another when information or state has changed. This can be achieved easily with use of PropertyChangeSupport and PropertyChangeListeners, although there are other ways as well, including using the XxxxListeners available in the Swing library.
For example of listener use and MVC with Swing:
Modifying independent JPanels from the JFrame
Java keeps adding buttons! - JFrames
Edit
For example, changes marked with a // !! comment:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.InetAddress;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.SwingPropertyChangeSupport;
public class ServerController {
String m_ip;
int m_port;
private static String[] ipPort;
public static void main(String args[]) {
final ServerConnector sc = new ServerConnector();
sc.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (ServerConnector.READY.equals(evt.getPropertyName())) {
if (sc.isReady()) {
ipPort = sc.getIPandPort();
System.out.println("IP is :" + ipPort[0] + " and port is :" + ipPort[1]);
}
}
}
});
}
}
class ServerConnector implements ActionListener {
public static final String READY = "ready"; //!!
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this); //!!
private boolean ready = false;
private JFrame m_frame = null;
private JTextField m_serverIP;
private JTextField m_serverPort; // you can use also JPasswordField
private JButton m_submitButton;
// location of the jframe
private final int m_centerX = 500;
private final int m_centerY = 300;
// dimensions of the jframe
private final int m_sizeX = 1650;
private final int m_sizeY = 150;
private String m_ip;
private String m_port;
/**
* Ctor
*/
ServerConnector() {
m_frame = new JFrame("Sever Side Listener");
m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
m_serverIP = new JTextField(20);
m_serverPort = new JTextField(20);
JPanel gui = new JPanel(new BorderLayout(3, 3));
gui.setBorder(new EmptyBorder(5, 5, 5, 5));
gui.setSize(m_sizeX, m_sizeY);
m_frame.setContentPane(gui);
JPanel labels = new JPanel(new GridLayout(0, 1));
JPanel controls = new JPanel(new GridLayout(0, 1));
gui.add(labels, BorderLayout.WEST);
gui.add(controls, BorderLayout.CENTER);
labels.add(new JLabel("Server IP: "));
controls.add(m_serverIP);
labels.add(new JLabel("Server Port: "));
controls.add(m_serverPort);
m_submitButton = new JButton("Start Listening");
m_submitButton.addActionListener(this);
gui.add(m_submitButton, BorderLayout.SOUTH);
m_frame.setLocation(m_centerX, m_centerY);
m_frame.setSize(m_sizeX, m_sizeY);
m_frame.pack();
m_frame.setVisible(true);
}
public static void main(String[] args) {
new ServerConnector();
}
#Override
public void actionPerformed(ActionEvent event) {
Object object = event.getSource();
if (object == this.m_submitButton) {
// grab all values from the connection box
// if one of them is missing then display an alert message
String ip = this.m_serverIP.getText().trim();
String port = this.m_serverPort.getText().trim();
if (ip.length() == 0) {
JOptionPane.showMessageDialog(null, "Please enter IP address !");
return;
}
if (port.length() == 0) {
JOptionPane.showMessageDialog(null, "Please enter Port number!");
return;
}
int s_port = 0;
try {
// try parse the Port number
// throws exception when an incorrect IP address
// is entered , and caught in the catch block
s_port = Integer.parseInt(port);
}
catch (Exception exp) {
JOptionPane.showMessageDialog(null, "Port number is incorrect!");
return;
}
try {
// try parse the IP address
// throws exception when an incorrect IP address
// is entered , and caught in the catch block
InetAddress.getByName(ip);
}
catch (Exception exp) {
JOptionPane.showMessageDialog(null, "IP address is incorrect!");
return;
}
m_frame.dispose();
this.m_ip = ip;
this.m_port = port;
setReady(true); //!!
// !! ready = true;
// new ServerGUI(ip , s_port);
}
}
// !! added
public void setReady(boolean ready) {
boolean oldValue = this.ready;
boolean newValue = ready;
this.ready = ready;
pcSupport.firePropertyChange(READY, oldValue, newValue);
}
//!! added
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
//!! added
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public boolean isReady() {
return this.ready;
}
/**
*
* #return
*/
public String[] getIPandPort() {
String[] ipPort = new String[2];
ipPort[0] = this.m_ip;
ipPort[1] = this.m_port;
return ipPort;
}
}
I'm working on the client side application of the client/server chat I'm doing for learning experience. My problem is I can't seem to get the socket and swing,both to run at the same time.
What I want to is, when the user opens a JOpionsPane and enters the hostname and port number, clicks okay, then they are connected. When the socket information was hardcoded it worked fine, but now I'm trying to get the users input for it.
What's meant to happen is, action listener is supposed to create the new SocketManager object that handles communication. Event though it says it's connected, it doesn't run. When I create the new SocketManager object and run it on a new thread it connects and revives messages form the server, but then the swings freezes and I have to end the process to shut it down.
Should I start it on a new worker thread or something? Maybe it's just because I'm tired, but I'm out of ideas.
EDIT
I updated my ActLis.class and SocketManager.class with the suggestion of adding a new thread for my SocketManager object 'network'. When I try and use 'network' though it returns null for some reason.
ActLis.clss
package com.client.core;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class ActLis implements ActionListener {
private Main main = new Main();;
private JTextField ipadress = new JTextField(),
portnumber = new JTextField(),
actionField;
private String username;
final JComponent[] ipinp = new JComponent[]{new JLabel("Enter Hostname (IP Adress): "),
ipadress,
new JLabel("Enter Port number: "), portnumber};
private SocketManager network;
private Window win;
public ActLis(){
}
public ActLis(JTextField t, Window w){
actionField = t;
win = w;
}
#Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if(cmd == "Exit"){
System.exit(0);
} else if(cmd == "Connect to IP"){
try{
JOptionPane.showMessageDialog(null, ipinp, "Connect to IP", JOptionPane.PLAIN_MESSAGE);
if(network != null){
network.close();
}
network = new SocketManager(ipadress.getText(),Integer.parseInt(portnumber.getText()));
network.setGUI(win);
Thread t = new Thread(network);
t.start();
JOptionPane.showMessageDialog(null, "Connected to chat host successfully!","Connected", JOptionPane.INFORMATION_MESSAGE);
}catch(Exception ee){
JOptionPane.showMessageDialog(null, "Could not connect. Check IP adress or internet connection","Error - Could not connect", JOptionPane.ERROR_MESSAGE);
ee.printStackTrace();
}
} else if (cmd == "chatWriter"){
if( actionField.getText() != ""){
try{
network.send(actionField.getText());
win.updateChat(actionField.getText());
actionField.setText("");
actionField.requestFocus();
}catch(Exception ex){
JOptionPane.showMessageDialog(null, "You are not connected to a host. (File -> Connect to IP)","Error - Not Connected", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
} else if (cmd == "setUsername"){
username = actionField.getText();
network.send("USERNAME:" + username);
}
}
}
Main.class
package com.client.core;
import javax.swing.JFrame;
public class Main extends JFrame{
private SocketManager network;
public static void main(String[] args){
Main main = new Main();
main.run();
}
private void run(){
Window win = new Window();
win.setVisible(true);
}
}
SocketManager.class
package com.client.core;
import java.io.*;
import java.net.*;
public class SocketManager implements Runnable {
private Socket sock;
private PrintWriter output;
private BufferedReader input;
private String hostname;
private int portnumber;
private String message;
private Window gui;
public SocketManager(String ip, int port){
try{
hostname = ip;
portnumber = port;
}catch(Exception e){
System.out.println("Client: Socket failed to connect.");
}
}
public synchronized void send(String data){
try{
//System.out.println("Attempting to send: " + data);
output.println(data);
output.flush();
//System.out.println("Message sent.");
}catch(Exception e){
System.out.println("Message could not send.");
}
}
public synchronized void setGUI(Window w){
gui = w;
}
public synchronized void connect(){
try{
sock = new Socket(hostname,portnumber);
}catch(Exception e){
}
}
public synchronized Socket getSocket(){
return sock;
}
public synchronized void setSocket(SocketManager s){
sock = s.getSocket();
}
public synchronized void close(){
try{
sock.close();
}catch(Exception e){
System.out.println("Could not close connection.");
}
output = null;
input = null;
System.gc();
}
public synchronized boolean isConnected(){
return (sock == null) ? false : (sock.isConnected() && !sock.isClosed());
}
public synchronized void listenStream(){
try {
while((message = input.readLine()) != null){
System.out.println("Server: " + message);
gui.updateChat(message);
}
} catch (Exception e) {
}
}
#Override
public void run() {
try {
sock = new Socket(hostname,portnumber);
output = new PrintWriter(sock.getOutputStream(),true);
input = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
while(true){
listenStream();
}
} catch (Exception e) {
System.out.println("Run method fail. -> SocketManager.run()");
}finally{
try {
sock.close();
} catch (Exception e) {
}
}
}
}
Window.class
package com.client.core;
import java.awt.*;
import javax.swing.*;
public class Window extends JFrame{
private int screenWidth = 800;
private int screenHeight = 600;
private SocketManager network;
private JPanel window = new JPanel(new BorderLayout()),
center = new JPanel(new BorderLayout()),
right = new JPanel(new BorderLayout()),
display = new JPanel( new BorderLayout()),
chat = new JPanel(),
users = new JPanel(new BorderLayout());
private JTextArea chatBox = new JTextArea("Welcome to the chat!", 7,50),
listOfUsers = new JTextArea("None Online");
private JTextField chatWrite = new JTextField(),
userSearch = new JTextField(10),
username = new JTextField();
private JScrollPane userList = new JScrollPane(listOfUsers),
currentChat = new JScrollPane(chatBox);
private JMenuBar menu = new JMenuBar();
private JMenu file = new JMenu("File");
private JMenuItem exit = new JMenuItem("Exit"),
ipconnect = new JMenuItem("Connect to IP");
private JComponent[] login = new JComponent[]{new JLabel("Username:"), username};
public Window(){
//Initial Setup
super("NAMEHERE - Chat Client Alpha v0.0.1");
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenWidth,screenHeight);
//Panels
listOfUsers.setLineWrap(true);
listOfUsers.setEditable(false);
display.setBackground(Color.black);
chat.setLayout(new BoxLayout(chat, BoxLayout.Y_AXIS));
chat.setBackground(Color.blue);
users.setBackground(Color.green);
//TextFields
addChatArea();
//Menu bar
addMenuBar();
//Adding the main panels.
addPanels();
//Listeners
addListeners();
for(int x = 0; x < 1; x++){
login();
}
}
private void login(){
JOptionPane.showMessageDialog(null, login, "Log in", JOptionPane.PLAIN_MESSAGE);
}
private void addChatArea(){
chatBox.setEditable(false);
userList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
currentChat.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
users.add(userList);
users.add(userSearch, BorderLayout.NORTH);
chat.add(currentChat);
chat.add(chatWrite);
chat.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
}
private void addMenuBar(){
file.add(ipconnect);
file.add(exit);
menu.add(file);
}
private void addPanels(){
right.add(users);
center.add(display, BorderLayout.CENTER);
center.add(chat, BorderLayout.SOUTH);
window.add(center, BorderLayout.CENTER);
window.add(right, BorderLayout.EAST);
window.add(menu, BorderLayout.NORTH);
add(window);
}
private void addListeners(){
username.addActionListener(new ActLis(username, this));
chatWrite.addActionListener(new ActLis(chatWrite, this));
username.setActionCommand("setUsername");
chatWrite.setActionCommand("chatWriter");
ipconnect.addActionListener(new ActLis());
exit.addActionListener(new ActLis());
}
public void setNetwork(SocketManager n){
network = n;
}
public void updateChat(String s){
chatBox.setText(chatBox.getText() + "\n" + s);
}
}
Ok #Zexanima you have create a Socket class for socket manager. Something like this:
public class YouSocketClass {
static public Socket socket = null;
static public InputStream in = null;
static public OutputStream out = null;
public YouSocketClass() {
super();
}
public static final Socket getConnection(final String ip, final int port, final int timeout) {
try {
socket = new Socket(ip, port);
try {
socket.setSoTimeout(timeout);
} catch(SocketException se) {
log("Server Timeout");
}
in = socket.getInputStream();
out = socket.getOutputStream();
} catch(ConnectException e) {
log("Server name or server ip is failed. " + e.getMessage());
e.printStackTrace();
} catch(Exception e) {
log("ERROR Socket: " + e.getMessage() + " " + e.getCause());
e.printStackTrace();
}
return socket;
}
public static void closeConnection() {
try {
if(socket != null) {
if(in != null) {
if(out != null) {
socket.close();
in.close();
out.close();
}
}
}
} catch(Exception e2) {
e2.printStackTrace();
}
}
private static Object log(Object sms) {
System.out.println("Test Socket1.0: " + sms);
return sms;
}
}
I hope that serve. :)