chat app: it freezes when creating a new socket - java

I have created a short java chat app. 3 classes: the GUI, the server and the client.
The gui has its own getters so that they are talked to by the objects of the other classes.
When I try to create the socket, it first popped me up the Firewall saying that it had blocked an app from trying to open a port in my computer, alright, I clicked on "allow app" and I further even expressly put it on the list of allowed apps of Firewall. The problem now is that when I click on the Menu to create the socket, it Freezes the app completely and you can't do anything but abort it.
The app, of course,is based on Threads, and every time I wanto to create a socket such as when I click on the menu item
if(ae.getSource() == servertalkstogui.getCreate()){
it then starts a Thread that is run at its Run method. But at that point it freezes. I dont know if I am on an infinite loop or what. Also, I dont like using a "sleep" in a Loop, but so far I dont know any other alternative, but the most important thing is to detect the bug that freezes the App
package backend;
import frontend.Gui;
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.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Alvarito
*/
public class Server implements ActionListener, Runnable {
private ServerSocket ss;
private Socket s;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Gui servertalkstogui;
public Server(Gui in) {
servertalkstogui = in;
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == servertalkstogui.getCreate()) {
servertalkstogui.getAreachat().append("hola");
System.out.println("creado");
Thread t = new Thread(this);
t.run();
}
if (ae.getSource() == servertalkstogui.getButton()) {
String linea = servertalkstogui.getTextField().getText();
writeLine(linea);
}
}
#Override
public void run() {
try {
ss = new ServerSocket(9999);
s = ss.accept();
oos = new ObjectOutputStream(s.getOutputStream());
ois = new ObjectInputStream(s.getInputStream());
}
catch (IOException e) {
try {
this.closeServer();
}
catch (IOException ex) {
System.out.println("se jodio");
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
e.getLocalizedMessage();
}
}
public void writeLine(String linea) {
try {
oos.writeObject(linea);
servertalkstogui.getAreachat().append(linea);
}
catch (IOException e) {
e.getLocalizedMessage();
}
}
public void readLine() throws InterruptedException {
try {
while (true) {
Object aux = ois.readObject();
if (aux != null && aux instanceof String) {
servertalkstogui.getAreachat().append((String) aux);
}
}
}
catch (IOException | ClassNotFoundException e) {
}
}
public void closeServer() throws IOException {
try {
oos.close();
s.close();
ss.close();
}
catch (Exception e) {
e.addSuppressed(e);
}
}
}
Now the Client class
package backend;
import frontend.Gui;
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.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Alvarito
*/
public class Client implements ActionListener, Runnable {
private Socket s;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Gui clienttalkstogui;
public Client(Gui in) {
clienttalkstogui = in;
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == clienttalkstogui.getConnect()) {
Thread t = new Thread(this);
t.run();
clienttalkstogui.getAreachat().append("me he conectado");
System.out.println("hola");
}
}
public void writeLine(String linea) {
try {
oos.writeObject(linea);
clienttalkstogui.getAreachat().append(linea);
}
catch (IOException e) {
e.getLocalizedMessage();
}
}
public void readLine() throws InterruptedException {
try {
while (true) {
Object aux = ois.readObject();
if (aux != null && aux instanceof String) {
clienttalkstogui.getAreachat().append((String) aux);
}
}
}
catch (IOException | ClassNotFoundException e) {
}
}
public void run() {
try {
s = new Socket("localhost", 9999);
oos = new ObjectOutputStream(s.getOutputStream());
ois = new ObjectInputStream(s.getInputStream());
}
catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void close() {
try {
ois.close();
oos.close();
s.close();
}
catch (Exception e) {
e.getLocalizedMessage();
}
}
}
Now the Gui class:
package frontend;
import backend.Client;
import backend.Server;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
*
* #author Alvarito
*/
public class Gui extends JFrame {
private JMenuBar bar;
private JMenu menu;
private JMenuItem connect, create, exit;
private JTextArea areachat;
private JTextField campochat;
private JButton botonchat;
private JScrollPane scroll;
/* WE CREATE INSTANTIATED OBJECTS OF CLASSES INTERACTING WITH THE GUI */
Server servidor = new Server(this);
Client cliente = new Client(this);
/* CREATING THE CONSTRUCTOR */
public Gui() {
super("CHAT WINDOW");
this.setSize(400, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/* INSTANTIATE THE OBJECTS */
bar = new JMenuBar();
menu = new JMenu("Menu");
connect = new JMenuItem("Conectar");
create = new JMenuItem("Crear");
exit = new JMenuItem("Salir");
areachat = new JTextArea();
campochat = new JTextField(20);
botonchat = new JButton("Send");
scroll = new JScrollPane(areachat);
/* THE BAR IS PLACED IN THE JFRAME WINDOW */
this.setJMenuBar(bar);
/* THE MENU IS ADDED TO THE BAR */
bar.add(menu);
/* THE ITEMS ARE ADDED TO THE MENU */
menu.add(connect);
menu.add(create);
menu.add(exit);
/* MAKE ITEMS LISTEN TO THE EVENT FROM THE CODE CLASSES */
create.addActionListener(servidor);
connect.addActionListener(cliente);
exit.addActionListener(servidor);
exit.addActionListener(cliente);
botonchat.addActionListener(cliente);
botonchat.addActionListener(servidor);
/* CREATING THE LAYOUTS */
/* AREACHAT */
this.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
this.add(scroll, gbc);
/* TEXTFIELD */
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.weighty = 0;
this.add(campochat, gbc);
/* BOTON */
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 0;
gbc.weighty = 0;
this.add(botonchat, gbc);
this.setVisible(true);
}
/* CREATING THE GETTERS AND SETTERS */
/* GETTERS */
public JTextArea getAreachat() {
return areachat;
}
public JMenuItem getCreate() {
return create;
}
public JMenuItem getConnect() {
return connect;
}
public JTextField getTextField() {
return campochat;
}
public JButton getButton() {
return botonchat;
}
/* SETTERS */
public static void main(String [] args) {
Gui objeto = new Gui();
}
}

You should use start() instead of run() in order to start a thread.
Calling run() just call the run method, without starting a thread. And you then block in the ui thread

Related

How do I put a Server class on my website so my Client class can communicate with it from different computers?

I have a server client application working just how I want it locally. I need to get the server online so the client program can be used from different computers. Not sure how to do this. I have my own website that I thought I could just put the Server on in the background.
Is this possible or am I just looking at this the wrong way.
Server.java
package core;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
public class Server {
public static void main(String[] args) throws IOException {
ArrayList<ClientHandler> clients = new ArrayList<>();
ServerSocket serverSocket = null;
int clientNum = 1; // keeps track of how many clients were created
// 1. CREATE A NEW SERVERSOCKET
try {
serverSocket = new ServerSocket(4444); // provide MYSERVICE at port
// 4444
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
// 2. LOOP FOREVER - SERVER IS ALWAYS WAITING TO PROVIDE SERVICE!
while (true) {
Socket clientSocket = null;
try {
// 2.1 WAIT FOR CLIENT TO TRY TO CONNECT TO SERVER
System.out.println("Waiting for client " + clientNum + " to connect!");
clientSocket = serverSocket.accept();
clientNum++;
ClientHandler c = new ClientHandler(clientSocket, clients);
clients.add(c);
// 2.2 SPAWN A THREAD TO HANDLE CLIENT REQUEST
Thread t = new Thread(c);
t.start();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
// 2.3 GO BACK TO WAITING FOR OTHER CLIENTS
// (While the thread that was created handles the connected client's
// request)
} // end while loop
} // end of main method
} // end of class MyServer
class ClientHandler implements Runnable {
Socket s; // this is socket on the server side that connects to the CLIENT
ArrayList<ClientHandler> others;
Scanner in;
PrintWriter out;
ClientHandler(Socket s, ArrayList<ClientHandler> others) throws IOException {
this.s = s;
this.others = others;
in = new Scanner(s.getInputStream());
out = new PrintWriter(s.getOutputStream());
}
/*
* (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
public void run() {
// 1. USE THE SOCKET TO READ WHAT THE CLIENT IS SENDING
while (true) {
String clientMessage = in.nextLine();
// System.out.println(clientMessage);
new Thread(new Runnable() {
#Override
public void run() {
try (PrintWriter fileWriter = new PrintWriter(new FileOutputStream(new File("chat.txt"), true));) {
fileWriter.println(clientMessage);
fileWriter.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println(others.size());
for (ClientHandler c : others) {
// System.out.println(c.toString());
c.sendMessage(clientMessage);
}
}
}).start();
}
}
private void sendMessage(String str) {
out.println(str);
out.flush();
}
} // end of class ClientHandler
ClientSide.java
package core;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.BoxLayout;
import javax.swing.JTextArea;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class ClientSide extends JFrame {
private JPanel contentPane;
private JTextField textField;
private String name;
private JTextArea textArea;
private Thread serverListener;
private Socket socket;
private Scanner in;
private PrintWriter out;
// /**
// * Launch the application.
// */
// public static void main(String[] args) {
// EventQueue.invokeLater(new Runnable() {
// public void run() {
// try {
// ClientSide frame = new ClientSide();
// frame.setVisible(true);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// });
// }
/**
* Create the frame.
*
* #throws IOException
*/
public ClientSide(String myName) {
try {
socket = new Socket("localhost", 4444);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
serverListener = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
String clientMessage = in.nextLine();
try {
System.out.println("Receiving before dec: " + clientMessage);
clientMessage = Crypto.decrypt(clientMessage, "key");
System.out.println("Receiving after dec: " + clientMessage);
addLine(clientMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
serverListener.start();
name = myName;
setTitle("Client Side");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
JPanel topPanel = new JPanel();
FlowLayout flowLayout = (FlowLayout) topPanel.getLayout();
flowLayout.setAlignment(FlowLayout.LEFT);
contentPane.add(topPanel);
textArea = new JTextArea();
textArea.setEditable(false);
textArea.setColumns(20);
textArea.setRows(7);
topPanel.add(textArea);
JPanel bottomPanel = new JPanel();
contentPane.add(bottomPanel);
bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
JLabel lblMessage = new JLabel("Message");
bottomPanel.add(lblMessage);
textField = new JTextField();
bottomPanel.add(textField);
textField.setColumns(10);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// send string/message to server
String clientMessage;
try {
clientMessage = Crypto.encrypt(name + ": > " + textField.getText(), "key");
System.out.println("Sending: " + clientMessage);
out.println(clientMessage);
out.flush();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
bottomPanel.add(btnSend);
}
public void addLine(String text) {
textArea.setText(textArea.getText() + text + "\n");
}
}
Provided your ClientSide class connects with your server applicztion on port 4444, you can do the following:
Package your client as jar file and run on each computer you want to distribute it to.
Ensure, each of those computers have JRE installed.
3 Package your Server module as jar file
You should own your server or have admin right. So you can install Java if not there.
Depending on OS, SSH skill might be required
Ensure PORT 4444 is enabled on your host server. firewall
Get the public IP address of your server and use it in your ClideSide code.

Game with server and multiple client, make sure only one game object is created

I'm trying to write a poker server and client program, I create the game in the server class and my client class takes the output and displays them. However, when ever i do this, there seem to be two game objects created, the first player gets the input that is consistent with the object that is shown in the console, the second player always displays cards that are not shown in the sysout method, and I can not seem to find where I created the second game object.
server class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashSet;
public class PokerServer {
/**
* The port that the server listens on.
*/
private static final int PORT = 9050;
// keeps track of all the names
private static ArrayList<String> names = new ArrayList<String>();
// broadcast messages
private static ArrayList<PrintWriter> writers = new ArrayList<PrintWriter>();
private boolean bothPlayersConnected = false;
/**
* The appplication main method, which just listens on a port and spawns
* handler threads.
*/
public static void main(String[] args) throws Exception {
System.out.println("The poker server is running.");
ServerSocket listener = new ServerSocket(PORT);
try {
while (true) {
new GameThread(listener.accept()).start();
}
} finally {
listener.close();
}
}
private static class GameThread extends Thread {
private String name;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private Game game;
public GameThread(Socket socket) {
this.socket = socket;
}
/**
* Services this thread's client by repeatedly requesting a screen name
* until a unique one has been submitted, then acknowledges the name and
* registers the output stream for the client in a global set, then
* repeatedly gets inputs and broadcasts them.
*/
public void run() {
try {
System.out.println("get to this part");
// Create character streams for the socket.
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// get the name of the player
out.println("SUBMITNAME");
name = in.readLine();
names.add(name);
while(names.size()<2){
out.println("MESSAGE waiting for opponent to connect");
}
// Now that a successful name has been chosen, add the
// socket's print writer to the set of all writers so
// this client can receive broadcast messages.
// out.println("NAMEACCEPTED");
// writers.add(out);
game = new Game(names.get(0), names.get(1), 1000);
game.dealToPlayers();
out.println(names.get(0) + game.getPlayer1().getHand()[0].transferStr());
out.println(names.get(0) + game.getPlayer1().getHand()[1].transferStr());
out.println(names.get(1) + game.getPlayer2().getHand()[0].transferStr());
out.println(names.get(1) + game.getPlayer2().getHand()[1].transferStr());
// Accept messages from this client and broadcast them.
// Ignore other clients that cannot be broadcasted to.
while (true) {
String input = in.readLine();
if (input == null) {
return;
} else if (input.startsWith(names.get(0))) {
}
for (PrintWriter writer : writers) {
writer.println("MESSAGE " + name + ": " + input);
}
}
} catch (IOException e) {
System.out.println(e);
} finally {
// This client is going down! Remove its name and its print
// writer from the sets, and close its socket.
if (name != null) {
names.remove(name);
}
if (out != null) {
writers.remove(out);
}
try {
socket.close();
} catch (IOException e) {
}
}
}
}
}
Client class
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class PokerClient {
BufferedReader in;
PrintWriter out;
String playerName = "Poker";
JFrame frame = new JFrame(playerName);
JPanel playerHandPanel, controlPanel, bottomPanel, topPanel, messageBoard;
JButton check, fold;
JTextField textField = new JTextField(10);
JLabel firstLine = new JLabel("");
String serverAddress = "localhost";
Card playerHand1, playerHand2;
public PokerClient() {
// Layout GUI
frame.setSize(1100, 700);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
playerHandPanel = new JPanel(new GridLayout(1, 0));
playerHandPanel.setPreferredSize(new Dimension(600, 300));
playerHandPanel.setVisible(true);
topPanel = new JPanel(new GridLayout(1, 0));
topPanel.setPreferredSize(new Dimension(900, 300));
topPanel.setVisible(true);
messageBoard = new JPanel(new GridLayout(0, 1));
messageBoard.add(firstLine);
controlPanel = new JPanel();
controlPanel.setPreferredSize(new Dimension(600, 40));
controlPanel.setVisible(true);
topPanel.add(messageBoard);
check = new JButton("Check");
check.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
out.println(playerName+"CHECK");
}
});
fold = new JButton("fold");
fold.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
out.println(playerName+"FOLD");
}
});
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(isInt(textField.getText())){
out.println(textField.getText());
textField.setText("");
} else{
JFrame frame = new JFrame("Not a number");
frame.setSize(600, 70);
frame.setLocation(400, 250);
frame.setResizable(false);
JLabel label = new JLabel("You must enter a number in order to raise");
frame.add(label);
frame.setVisible(true);
frame.toFront();
frame.repaint();
textField.setText("");
}
}
});
controlPanel.add(check);
controlPanel.add(fold);
controlPanel.add(new JLabel(" Raise:"));
controlPanel.add(textField);
bottomPanel = new JPanel();
bottomPanel.add(controlPanel, BorderLayout.SOUTH);
bottomPanel.add(playerHandPanel, BorderLayout.NORTH);
frame.add(topPanel, BorderLayout.NORTH);
frame.add(bottomPanel, BorderLayout.SOUTH);
//frame.add(firstLine, "SOUTH");
frame.setVisible(true);
}
private static boolean isInt(String s)
{
try
{ int i = Integer.parseInt(s); return true; }
catch(NumberFormatException er)
{ return false; }
}
/**
* Prompt for and return the desired screen name.
*/
private String getName() {
return JOptionPane.showInputDialog(
frame,
"Choose a screen name:",
"Screen name selection",
JOptionPane.PLAIN_MESSAGE);
}
private Card constructCard(String line){
int seperator = line.indexOf('/');
int cardNum = Integer.parseInt(line.substring(0, seperator));
Card card;
if(line.substring(seperator+1).startsWith("S")){
card = new Card(cardNum, Suit.SPADE);
} else if(line.substring(seperator+1).startsWith("C")){
card = new Card(cardNum, Suit.CLUB);
} else if(line.substring(seperator+1).startsWith("D")){
card = new Card(cardNum, Suit.DIAMOND);
} else{
card = new Card(cardNum, Suit.HEART);
}
System.out.println(card.toString());
return card;
}
/**
* Connects to the server then enters the processing loop.
*/
private void run() throws IOException {
Socket socket = new Socket(serverAddress, 9050);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Process all messages from server, according to the protocol.
while (true) {
String line = in.readLine();
System.out.println(line);
if (line.startsWith("SUBMITNAME")) {
String name = getName();
playerName = name;
out.println(name);
frame.setTitle(playerName);
} else if (line.startsWith(playerName)) {
playerHandPanel.add(new CardComponent(constructCard(line.substring(playerName.length()))));
playerHandPanel.revalidate();
playerHandPanel.repaint();
} else if(line.startsWith("CARD")){
topPanel.add(new CardComponent(constructCard(line.substring(4))));
topPanel.revalidate();
topPanel.repaint();
} else if(line.startsWith("MESSAGE")){
firstLine.setText(line.substring(7));
}
}
}
public static void main(String[] args) throws Exception {
PokerClient client = new PokerClient();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setVisible(true);
client.run();
}
}

issue in sending the socket output to GUI

I wrote this simple multi threaded chatroom, and I am trying to send the client/server output to GUI to display it in chatroom text area but I get null pointer exception at the following line:
output.write(line + "\n");
here is the full code for GUI:
import java.awt.*;
import javax.swing.*;
import javax.swing.JTextField;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import javax.swing.JButton;
import java.io.Writer;
public class GUI {
private JFrame frame;
private JButton btnSend, btnConnect;
private JTextArea txtChat;
private JTextField fldText, fldName;
private JList clientList;
private DefaultListModel listModel;
private JScrollPane sc, scClients;
private JPanel jpS2All, jpS2Client, jpS2Text;
private String Name;
private JLabel lblErr;
private Writer output;
public GUI(String Name, Writer output) {
this.Name = Name;
this.output = output;
}
public GUI() {
}
class handler implements ActionListener, MouseListener {
handler(String Name) {
}
handler() {
}
#Override
public void actionPerformed(ActionEvent e) {
clients(); //it seems this line made the error because it creates the
listModel.addElement(Name);//gui and sends the output to textSend actionlistener
//to display it in gui
//while the output is empty, right?
//is there any way to handle this?
}
#Override
public void mouseClicked(MouseEvent e) {
fldName.setText("");
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
} //end of handler
class textSend implements ActionListener {
textSend(String Name, Writer output) {
}
#Override
public void actionPerformed(ActionEvent e) {
String line = fldText.getText();
try {
output.write(line + "\n"); // the null exception error shows the
output.flush(); // error source at this line!
} catch (IOException ioe) {
txtChat.append("Other party hung up!");
}
String contenet = Name + ":" + output;
txtChat.append(contenet);
fldText.setText("");
}
}//end of textSend
public void creatServer() {
frame = new JFrame("enter");
frame.setBounds(50, 50, 300, 200);
btnConnect = new JButton("connect");
lblErr = new JLabel();
lblErr.setText("");
frame.add(btnConnect, BorderLayout.EAST);
fldName = new JTextField();
fldName.setText("enter your name");
fldName.addMouseListener(new handler());
btnConnect.addActionListener(new handler(getName()));
frame.add(fldName, BorderLayout.CENTER);
frame.setVisible(true);
}
public void clients() { //to create the chatroom GUI
frame = new JFrame("friends");
frame.setBounds(100, 100, 400, 400);
jpS2All = new JPanel();
txtChat = new JTextArea();
txtChat.setRows(25);
txtChat.setColumns(25);
txtChat.setEditable(false);
sc = new JScrollPane(txtChat);
jpS2All.add(sc);
frame.add(jpS2All, BorderLayout.WEST);
jpS2Text = new JPanel();
////////////////////////
fldText = new JTextField();
fldText.setColumns(34);
fldText.setHorizontalAlignment(JTextField.RIGHT);
fldText.addActionListener(new textSend(getName(), output));
jpS2Text.add(fldText);
frame.add(jpS2Text, BorderLayout.SOUTH);
/////////
jpS2Client = new JPanel();
listModel = new DefaultListModel();
clientList = new JList(listModel);
clientList.setFixedCellHeight(14);
clientList.setFixedCellWidth(100);
scClients = new JScrollPane(clientList);
frame.add(jpS2Client.add(scClients), BorderLayout.EAST);
/////////
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
}//end of clients
public String getName() {
Name = fldName.getText();
return Name;
}
public void appendText(final String message) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
txtChat.append(message);
}
});
}
}
server code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class server {
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(1234);
while (true) {
Socket socket = serverSocket.accept();
ClientThread t = new ClientThread(socket);
t.start();
}
}
public static void main(String[] args) throws IOException {
server server = new server();
server.start();
}
class ClientThread extends Thread {
Socket socket;
InputStream sInput;
OutputStream sOutput;
GUI gui = new GUI();
String Name;
ClientThread(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
BufferedReader sInput
= new BufferedReader(new InputStreamReader(socket.getInputStream()));
Writer sOutput = new OutputStreamWriter(socket.getOutputStream());
Name = gui.getName();
gui = new GUI(Name, sOutput);
try {
String line;
while ((line = sInput.readLine()) != null) {
gui.appendText(line);
}
} catch (IOException ex) {
Logger.getLogger(client.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException e) {
}
}
}
}
client side:
import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class client {
private Socket s;
private String Name;
private GUI gui;
private Writer output;
private BufferedReader input;
public void start() {
try {
s = new Socket("127.0.0.1", 1234);
} catch (IOException ex) {
}
try {
input = new BufferedReader(new InputStreamReader(s.getInputStream()));
output = new OutputStreamWriter(s.getOutputStream());
} catch (IOException eIO) {
}
Name = gui.getName();
new GUI(Name, output);
new ListenFromServer().start();
}
public static void main(String[] args) {
client cl = new client();
GUI gui = new GUI();
gui.creatServer();
}
class ListenFromServer extends Thread {
public void run() {
try {
String line;
while ((line = input.readLine()) != null) {
gui.appendText(line);
}
} catch (IOException ex) {
Logger.getLogger(client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
I know my question is a bit cumbersome but I really appreciate to help me handle this issue!
I am looking at your code and it is obvious that output is null when you attempt output.write(line + "\n"); Therefore I went and looked for the possible path of execution that could leave output un-initialized. This is where debugging comes in very handy.
Here is your execution path:
In your main method of client you create a new GUI and then call gui.creatServer();
public static void main(String[] args) {
client cl = new client();
GUI gui = new GUI();
gui.creatServer();
}
output has not been assigned and is still null
in the creatServer(); method you have this line:
fldName.addMouseListener(new handler());
which the actionPerformed method of handler calls the clients(); method which has the line:
fldText.addActionListener(new textSend(getName(), output));
note output is still null
(now your textSend class doesn't even do anything inside the constructor but that aside even if it did you are still using the output variable from the GUI class)
you have the actionPerformed method in the textSend class that has the line:
output.write(line + "\n");
Without ever initializing output it is still null, which gives you the NullPointer
Please see What is a NullPointerException, and how do I fix it? as #markspace linked in the comments. In addition you should really learn how to debug small programs.
See the following links:
http://ericlippert.com/2014/03/05/how-to-debug-small-programs/
http://blogs.msdn.com/b/smallbasic/archive/2012/10/09/how-to-debug-small-basic-programs.aspx
Again in addition, consider using Anonymous classes to ease up on those lines of code, which also makes the code easier to debug and more readable.
One last thought, remember to use standard Naming Conventions for the language you are using. your code currently has a lot of incorrect lowercase classes and some uppercase methods/properties.
the error message shows that one of the variable used in the expression was null. This may be either output or line.
As chancea already mentioned, you are calling the GUI() constructor with no arguments, so the output field is not initialized. You should remove the constructor with no arguments when you have no way to initialize the output field in it and only leave the one with arguments.

Chat program freezes JFrame

I'm writing a simply chat client and am moving it over to a nice GUI. The constructor for the server side (client side is android) contains a list that's in the JFrame, and the first part of the server runs, but then the entire frame locks up. Does anyone see the issue? Sorry for the relatively disorganized, not cleanly commented code...
Server:
import java.awt.List;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class ChatServer {
private final int CHAT_PORT = 4453;
ServerSocket sSocket;
Socket cSocket;
PrintWriter pWriter;
BufferedReader bReader;
InetAddress localAddr;
List messageList;
public ChatServer(List entList)
{
messageList = entList;
}
public synchronized void run()
{
messageList.add("Chat Server Starting...");
try {
localAddr = InetAddress.getLocalHost();
} catch (UnknownHostException e1) {
messageList.add("InnetAddress error");
}
while(true)
{
try {
sSocket = new ServerSocket(CHAT_PORT);
sSocket.setReuseAddress(true);
messageList.add("Server has IP:" + localAddr.getHostAddress());
messageList.add("Server has hostname:" + localAddr.getHostName());
messageList.add("Server has port:" + CHAT_PORT);
} catch (IOException e) {
//ERRORS
if(cSocket.isConnected())
{
messageList.add("User disconnected\n");
try {
cSocket.close();
} catch (IOException e1) {
messageList.add("Error closing client socket");
}
}
else
{
messageList.add("ERROR CREATING SOCKET\n");
}
}
try {
cSocket = sSocket.accept();
cSocket.setReuseAddress(true);
messageList.add("INFO: socket connected");
} catch (IOException e) {
messageList.add("Client Socket Error");
System.exit(-1);
}
try {
pWriter = new PrintWriter(cSocket.getOutputStream(), true);
messageList.add("INFO: Print writer opened");
} catch (IOException e) {
messageList.add("PrintWriter error");
}
try {
bReader = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
messageList.add("INFO: buffered reader opened");
} catch (IOException e) {
messageList.add("BufferedReader error");
}
String inputLine;
try {
while((inputLine = bReader.readLine()) != null)
{
messageList.add(inputLine);
if(inputLine.equals("close"))
{
close();
}
}
} catch (IOException e) {
messageList.add("Buffered Reader error");
}
}
}
public synchronized void close()
{
messageList.add("****Server closing****");
try {
sSocket.close();
} catch (IOException e) {
messageList.add("Error closing server socket");
}
try {
cSocket.close();
} catch (IOException e) {
messageList.add("Error closing client socket");
}
pWriter.close();
try {
bReader.close();
} catch (IOException e) {
messageList.add("Error closing buffered reader");
}
messageList.add("****It's been fun, but I've got to go.****\n****Server has shut down.****");
System.exit(0);
}
}
GUI:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.List;
import java.awt.Toolkit;
#SuppressWarnings("serial")
public class ClientGUI extends JFrame {
private JPanel contentPane;
private JTextField txtEnterTextHere;
private JMenuBar menuBar;
private List messageList;
private JMenu mnOptions;
private JMenu mnHelp;
private JMenuItem mntmStartServer;
private JMenuItem mntmStopServer;
private JMenuItem mntmConnectionInfo;
private JMenuItem mntmEmailDeveloper;
private static String userName;
private ChatServer cServer;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ClientGUI frame = new ClientGUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ClientGUI() {
setTitle("Ben's Chat Client");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mnFile = new JMenu("File");
menuBar.add(mnFile);
JMenuItem mntmExit = new JMenuItem("Exit");
mntmExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showConfirmDialog(null, "Are you sure you want to exit?");
}
});
mnFile.add(mntmExit);
mnOptions = new JMenu("Options");
menuBar.add(mnOptions);
mntmStartServer = new JMenuItem("Start Server");
mntmStartServer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
ChatServer cServer = new ChatServer(messageList);
cServer.run();
}
});
mnOptions.add(mntmStartServer);
mntmStopServer = new JMenuItem("Stop Server");
mnOptions.add(mntmStopServer);
mntmConnectionInfo = new JMenuItem("Connection Info");
mnOptions.add(mntmConnectionInfo);
mnHelp = new JMenu("Help");
menuBar.add(mnHelp);
mntmEmailDeveloper = new JMenuItem("Email Developer");
mnHelp.add(mntmEmailDeveloper);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
txtEnterTextHere = new JTextField();
txtEnterTextHere.setBounds(10, 220, 334, 20);
txtEnterTextHere.setText("Enter text here...");
contentPane.add(txtEnterTextHere);
txtEnterTextHere.setColumns(10);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
messageList.add(userName + ": " + txtEnterTextHere.getText().toString());
}
});
messageList = new List();
btnSend.setBounds(349, 219, 85, 23);
contentPane.add(btnSend);
messageList.setBounds(10, 10, 424, 204);
contentPane.add(messageList);
}
public static String getUsername()
{
return userName;
}
public static void setUsername(String entName)
{
userName = entName;
}
}
Thanks!
It looks like you're starting the server on the Swing thread (see: The Event Dispatch Thread). As soon as you call cServer.run(); in the ActionListener, you are blocking the EDT from doing anything else (such as updating your JFrame and responding to events). Start your server in a background thread instead:
new Thread(new Runnable()
{
#Override
public void run()
{
// start your server
}
}).start();

How to display shell command output on a jtextarea in java?

How to display shell command output on a jtextarea in java?
Kindly help
Thanks
You can get shell command output below snippet code, set jtextarea on while loop.
try {
String cmd = "java"; // Set shell command
Process child = Runtime.getRuntime().exec(cmd);
InputStream lsOut = child.getInputStream();
InputStreamReader r = new InputStreamReader(lsOut);
BufferedReader in = new BufferedReader(r);
// read the child process' output
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
// You should set JtextArea
}
} catch (Exception e) { // exception thrown
System.err.println("Command failed!");
}
You need to read the standard output as the process input stream and update the JTextArea using the event queue from another thread. See the example code below:
public class OutputDisplayer implements Runnable {
protected final JTextArea textArea_;
protected Reader reader_ = null;
public OutputDisplayer(JTextArea textArea) {
textArea_ = textArea;
}
public void commence(Process proc) {
InputStream in = proc.getInputStream();
reader_ = new InputStreamReader(in);
Thread thread = new Thread(this);
thread.start();
}
public void run() {
StringBuilder buf = new StringBuilder();
try {
while( reader_ != null ) {
int c = reader_.read();
if( c==-1 ) return;
buf.append((char) c);
setText( buf.toString() );
}
} catch ( IOException ioe ) {
buf.append("\n\nERROR:\n"+ioe.toString());
setText( buf.toString() );
} finally {
try {
reader_.close();
} catch ( IOException ioe ) {
ioe.printStackTrace();
}
}
}
private void setText(final String text) {
EventQueue.invokeLater(new Runnable() {
public void run() {
textArea_.setText(text);
}
});
}
}
In addition to my two links in my comments above, I created and used a TextAreaOutputStream that helps to redirect output stream data to a textarea:
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class TextAreaOutputStream extends OutputStream {
private final JTextArea textArea;
private final StringBuilder sb = new StringBuilder();
private String title;
public TextAreaOutputStream(final JTextArea textArea, String title) {
this.textArea = textArea;
this.title = title;
sb.append(title + "> ");
}
#Override
public void flush() {
}
#Override
public void close() {
}
#Override
public void write(int b) throws IOException {
if (b == '\r')
return;
if (b == '\n') {
final String text = sb.toString() + "\n";
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(text);
}
});
sb.setLength(0);
sb.append(title + "> ");
}
sb.append((char) b);
}
}
import java.io.OutputStream;
import javax.swing.JTextArea;
/**
* This class extends from OutputStream to redirect output to a JTextArrea
* #author www.codejava.net
*
*/
public class CustomOutputStream extends OutputStream {
private JTextArea textArea;
public CustomOutputStream(JTextArea textArea) {
this.textArea = textArea;
}
#Override
public void write(int b) throws IOException {
// redirects data to the text area
textArea.append(String.valueOf((char)b));
// scrolls the text area to the end of data
textArea.setCaretPosition(textArea.getDocument().getLength());
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package guiconsoleoutput;
/**
*
* #author root
*/
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
public class TextAreaLogProgram extends JFrame {
/**
* The text area which is used for displaying logging information.
*/
private JTextArea textArea;
private JButton buttonStart = new JButton("Start");
private JButton buttonClear = new JButton("Clear");
private PrintStream standardOut;
public TextAreaLogProgram() {
super(" CONSOLE ");
textArea = new JTextArea(50, 10);
textArea.setEditable(false);
PrintStream printStream = new PrintStream(new CustomOutputStream(textArea));
// keeps reference of standard output stream
standardOut = System.out;
// re-assigns standard output stream and error output stream
System.setOut(printStream);
System.setErr(printStream);
// creates the GUI
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 0;
constraints.insets = new Insets(10, 10, 10, 10);
constraints.anchor = GridBagConstraints.WEST;
add(buttonStart, constraints);
constraints.gridx = 1;
add(buttonClear, constraints);
constraints.gridx = 0;
constraints.gridy = 1;
constraints.gridwidth = 2;
constraints.fill = GridBagConstraints.BOTH;
constraints.weightx = 1.0;
constraints.weighty = 1.0;
add(new JScrollPane(textArea), constraints);
// adds event handler for button Start
buttonStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
printLog();
}
});
// adds event handler for button Clear
buttonClear.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
// clears the text area
try {
textArea.getDocument().remove(0,
textArea.getDocument().getLength());
standardOut.println("Text area cleared");
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(480, 320);
setLocationRelativeTo(null); // centers on screen
}
/**
* Prints log statements for testing in a thread
*/
private void printLog() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Time now is " + (new Date()));
System.out.println("lol ");
String s = null;
/*try {
// run the Unix "ps -ef" command
// using the Runtime exec method:
Process p = Runtime.getRuntime().exec("dir");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}*/
try {
String cmd = "cmd /c ping 8.8.8.8"; // Set shell command
Process child = Runtime.getRuntime().exec(cmd);
InputStream lsOut = child.getInputStream();
InputStreamReader r = new InputStreamReader(lsOut);
BufferedReader in = new BufferedReader(r);
// read the child process' output
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
// You should set JtextArea
}
} catch (Exception e) { // exception thrown
System.err.println("Command failed!");
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
});
thread.start();
}
/**
* Runs the program
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TextAreaLogProgram().setVisible(true);
}
});
}
}

Categories