Java Socket not allowing swing frame to show up - java

Hey all I am at a loss as to why its doing this. If I just run the server and standalone client it works just fine. However, once I use my code for the client it seems to get stuck...
static JTextField textField = null;
static JTextArea messageArea = null;
static String serverAddress = "localhost";
static UFTtrack window = null;
public static JFrame frame;
public ImageIcon[] images;
static JTable table;
Date lastUpdate;
static Timer timer;
static Scanner in;
static PrintWriter out;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#SuppressWarnings({ "static-access" })
public void run() {
try {
UIManager.setLookAndFeel(new MaterialLookAndFeel());
} catch (UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
try {
window = new UFTtrack();
placeChatOnScreen();
createTable();
SystemTrayz.createTray();
centreWindow(frame);
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public UFTtrack() {
initialize();
}
private void initialize() {
frame = new JFrame("UFTtrack");
frame.setTitle("UFT Tracker");
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setSize(1308, 900);
frame.setBounds(100, 100, 450, 300);
frame.setMinimumSize(new Dimension(1308, 900));
frame.setPreferredSize(new Dimension(1308, 900));
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
#SuppressWarnings({ "resource", "unused" })
private static void placeChatOnScreen() {
try {
textField = new JTextField();
textField.setFont(new Font("Segoe UI", Font.PLAIN, 13));
textField.setDragEnabled(true);
textField.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
textField.setBounds(338, 838, 954, 22);
frame.getContentPane().add(textField);
messageArea = new JTextArea();
messageArea.setEditable(false);
messageArea.setFont(new Font("Segoe UI", Font.PLAIN, 13));
messageArea.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
messageArea.setDragEnabled(true);
messageArea.setName("chatArea");
messageArea.setWrapStyleWord(true);
messageArea.setBounds(338, 648, 954, 181);
frame.getContentPane().add(messageArea);
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
out.println(textField.getText());
textField.setText("");
}
});
Socket socket = new Socket("localhost", 8877);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
while (in.hasNextLine()) {
String line = in.nextLine();
if (line.startsWith("SUBMITNAME")) {
out.println(getName());
} else if (line.startsWith("NAMEACCEPTED")) {
textField.setEditable(true);
} else if (line.startsWith("MESSAGE")) {
messageArea.append(line.substring(8) + "\n");
}
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
It does fine until it gets to the "NAMEACCEPTED" else if condition and it just steps out of the while loop and then nothing happens. No error of any kind. It just doesn't how the swing frame!
If I comment out:
/*while (in.hasNextLine()) {
String line = in.nextLine();
if (line.startsWith("SUBMITNAME")) {
out.println(getName());
} else if (line.startsWith("NAMEACCEPTED")) {
textField.setEditable(true);
} else if (line.startsWith("MESSAGE")) {
messageArea.append(line.substring(8) + "\n");
}
}*/
and run it the swing frame loads up just fine. But my Socket (which I am wanting in my swing app) keeps it for some reason passing.
window = new UFTtrack();
placeChatOnScreen();
createTable();
SystemTrayz.createTray();
centreWindow(frame);
window.frame.setVisible(true);
To sum all this up - the above code hits the window = new UFTtrack(); and placeChatOnScreen() but after it exits the While loop in the placeChatOnScreen() it never continues to createTable(); What's the deal???
Also posted here:
http://www.javaprogrammingforums.com/whats-wrong-my-code/41820-java-socket-not-allowing-swing-frame-show-up.html#post165295
https://coderanch.com/t/708072/java/Java-Socket-allowing-swing-frame
https://www.dreamincode.net/forums/topic/415549-java-socket-not-allowing-swing-frame-to-show-up/
Java Socket not allowing swing frame to show up

As mentioned in the comments read and accept operations typically block on a Socket.
You could create an own Thread which is waiting for Message from your Socket and then modify the GUI. Keep in mind that Swing is not Thread safe.
If I need to create an own Thread, I use the Runnable interface. You could achieve it like this:
public class MySocketListener implements Runnable {
private final GUIClass guiClass;
private final ServerSocket serverSocket;
private Socket clientSocket;
public MySocketListener(GUIClass guiClass, ServerSocket serverSocket) {
this.guiClass = guiClass;
this.serverSocket = serverSocket;
}
/* Everything that happens in this method, is done on another Thread. */
#Override
public void run() {
try{
this.clientSocket = this.serverSocket.accept();
Scanner sc = new Scanner(this.clientSocket.getInputStream());
while(true) {
/* Blocking operations */
this.guiClass.doSomething();
}
} catch(IOException ex) {
ex.printStackTrace();
}
}
}
The Thread can then be started easily:
Thread socketListenerThread = new Thread(new MySocketListener(this, serverSocket));
socketListenerThread.start();
For more information have a look at the Thread and Socket documentation.

Related

The readObject() Method of objectOutputStream is not receiving the object written on the inputStream to the Client?

The aim is to transfer the coordinates from one Client(who is drawing) to all the Clients Connected to the Server and then draw on their respective Panels, but the readObject() in Client never seems to fetch the data. The Input Does go to the Server Properly but from Server, the Other CLients Couldn't Listen to it.
When using BufferedStream or DataInput/OutputStream any Other the input seems to lag or misbehaving. So preferring ObjectOutputStream. Snapshot of the Program.
The Client listens for the input in a background Thread listenData.
The Client Code -
public class Clients extends JFrame {
private static final long serialVersionUID = 1L;
private Coordinates crdntsToSend;
private Coordinates crdntsReceived;
private JPanel contentPane;
private Socket socket;
private ObjectOutputStream toServerPipe;
private ObjectInputStream fromServerPipe;
private JPanel paintPanel;
public Clients(String name,int port,String ip) {
setResizable(false);
setTitle("Skribbl");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600,550);
createConnection(ip,port);
listen();
}
private void createConnection(String ip,int port)
{
try {
socket = new Socket(ip,port);
toServerPipe = new ObjectOutputStream(socket.getOutputStream());
fromServerPipe = new ObjectInputStream(socket.getInputStream());
toServerPipe.flush();
userInterfaceSetter();
} catch (IOException e) {
System.out.println("Port Not Found!!!");
return;
}
}
private void userInterfaceSetter()
{
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e1) {
e1.printStackTrace();
}
getContentPane().setLayout(null);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[] {0, 0};
gbl_contentPane.rowHeights = new int[]{0, 0, 0};
gbl_contentPane.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gbl_contentPane.rowWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
contentPane.setLayout(gbl_contentPane);
paintPanel = new JPanel();
paintPanel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
drawOnPanel(e.getX(),e.getY());
}
});
paintPanel.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
drawOnPanel(e.getX(),e.getY());
}
});
paintPanel.setBackground(new Color(175, 238, 238));
GridBagConstraints gbcPaintPanel = new GridBagConstraints();
gbcPaintPanel.insets = new Insets(10, 10, 10, 10);
gbcPaintPanel.fill = GridBagConstraints.BOTH;
gbcPaintPanel.gridx = 0;
gbcPaintPanel.gridy = 0;
contentPane.add(paintPanel, gbcPaintPanel);
JLabel lblScore = new JLabel("Score: ");
GridBagConstraints gbclblScore = new GridBagConstraints();
gbclblScore.insets = new Insets(0, 0, 10, 0);
gbclblScore.anchor = GridBagConstraints.WEST;
gbclblScore.gridx = 0;
gbclblScore.gridy = 1;
contentPane.add(lblScore, gbclblScore);
}
private void drawOnPanel(int x,int y)
{
Graphics g = paintPanel.getGraphics();
g.fillOval(x, y, 7, 7);
sendData(x,y);
}
private void sendData(int x, int y) {
try {
crdntsToSend = new Coordinates(x,y);
toServerPipe.writeObject(crdntsToSend);
toServerPipe.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void listen()
{
SwingWorker<Void, String> listenData = new SwingWorker<Void, String>() {
boolean go = true;
String[] receivedData;
String str;
#Override
protected Void doInBackground() throws Exception {
while(go)
{
crdntsReceived = (Coordinates) fromServerPipe.readObject();
str= crdntsReceived.toString();
publish(str);
}
return null;
}
#Override
protected void process(List<String> chunks) {
receivedData = str.split(" ");
drawOnPanel(Integer.parseInt(receivedData[0]),Integer.parseInt(receivedData[1]));
}
};
listenData.execute();
}
}
ServerHandler Code(Server Thread) -
package theskribbl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class HandleClient implements Runnable
{
private Socket[] socket;
private ObjectInputStream fromClients;
private ObjectOutputStream toClients;
private static int count = 0;
private int temp;
public HandleClient(Socket[] socket, int count)
{
HandleClient.count = count;
temp=count;
this.socket=socket;
try
{
fromClients = new ObjectInputStream(socket[count].getInputStream());
toClients = new ObjectOutputStream(socket[count].getOutputStream());
toClients.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
}
#Override
public void run()
{
int i;
Coordinates coordinate;
while(true)
{
i=0;
try
{
coordinate = (Coordinates) fromClients.readObject();
System.out.println(coordinate.toString());
while(i<=count)
{
if(i!=temp)
{
toClients = new ObjectOutputStream(socket[i].getOutputStream());
toClients.writeObject(coordinate);
toClients.flush();
}
i++;
}
}
catch (Exception e)
{
System.out.println("Something Went Wrong");
return;
}
}
}
}
code of Client - https://repl.it/#GirirajSingh/skribbl#Clients.java
code for Logging into Client - https://repl.it/#GirirajSingh/skribbl#Login.java
code for Handling the Client(Server Side) - https://repl.it/#GirirajSingh/skribbl#HandleClient.java
code of Server - https://repl.it/#GirirajSingh/skribbl#ServerClass.java
The headers that you're saying is not matching, actually they are matching because they've been initialised via the same Socket.
The same process works using DataOutputStream/DataInputStream(write()/read() ) but in this the data is getting leaked because if the mouse's dragged fast the data gets lost in between. so that's why i want to use read/writeObject() of ObjectOutputStream.
ObjectOutputStream and ObjectInputStream constructor calls must be matched - when an ObjectOutputStream is created, it sends a header which must be received when creating an ObjectInputStream.
I have no time to study the code, but it looks like the output streams are being constructed in a loop every time something is being sent by the server. Are the clients reopening the input every time they received a coordinate?
Check the documentation of ObjectOutputStream and ObjectInputStream for better explanation. Better start with a (very) simple prototype: one server, one client, and just sending a couple of (test = fixed) coordinates.
There is probably an Exception being thrown by doInBackGround() (inside the SwingWorker)! It is advised to check for this by calling the get() method after the SwingWorker terminates (inside its overridden done()) - this will thrown an ExecutionException if the computation threw an exception, which will have information about the Exception.
Add some code like the following to the SwingWorker:
#Override
protected void done() {
try {
get();
} catch (Exception ex) {
ex.printStackTrace();
}
}
ATTENTION: this code is not intended to solve the problem, only to show a possible error

Simple Client-Server program using Swing GUI

I'm making a simple, no thread Client-Server program where GUI has one button on both server and client side. When client presses button it changes text on a button to "C" and sends to server "C" string, so the button on the server side changes text to "C". Server works similarly to client but sends "S" instead of "C". They work in turns: when it's the client's turn, server's button is locked and he cannot change his button. Client always starts first.
When client presses button it works fine, but when server presses button it changes button to "S" on the server side but not on client's side. I know what I'm doing wrong.
Server code:
public class Serv implements ActionListener
{
private JButton button;
private boolean myTurn;
private ServerSocket sock;
private Socket s;
private BufferedReader input;
private PrintStream output;
public Serv() throws UnknownHostException, IOException
{
button = new JButton();
myTurn = false;
sock = new ServerSocket(9001);
s = null;
button = new JButton();
}
public void createGUI()
{
JFrame frame = new JFrame("TicTacToe - Server");
JPanel mainPanel = new JPanel();
mainPanel.setPreferredSize(new Dimension(100, 100));
button = new JButton("");
button.setPreferredSize(new Dimension(100, 100));
button.setFont(new Font(button.getFont().getName(), button.getFont().getStyle(), 70));
button.setActionCommand("1");
button.addActionListener(this);
mainPanel.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void startMyGame() throws IOException
{
createGUI();
s = sock.accept();
input = new BufferedReader(new InputStreamReader(s.getInputStream()));
output = new PrintStream(s.getOutputStream(), true);
while(true)
{
if(myTurn == false)
{
myTurn = true;
String out = input.readLine();
button.setText(out);
}
}
}
public static void main(String args[])
{
Serv tc = null;
try
{
tc = new Serv();
tc.startMyGame();
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
try
{
tc.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
private void close() throws IOException
{
this.sock.close();
this.input.close();
this.output.close();
}
#Override
public void actionPerformed(ActionEvent e)
{
if(myTurn == true)
{
if(e.getActionCommand().equals("1"))
{
JButton b = (JButton) e.getSource();
b.setText("S");
output.println("S");
myTurn = false;
}
}
}
}
Client code:
public class Cli implements ActionListener
{
private JButton button;
private boolean myTurn;
private Socket sock;
private BufferedReader input;
private PrintStream output;
public Cli() throws UnknownHostException, IOException
{
button = new JButton();
myTurn = true;
sock = new Socket("127.0.0.1", 9001);
input = new BufferedReader(new InputStreamReader(sock.getInputStream()));
output = new PrintStream(sock.getOutputStream(), true);
}
public void createGUI()
{
JFrame frame = new JFrame("TicTacToe - Client");
JPanel mainPanel = new JPanel();
mainPanel.setPreferredSize(new Dimension(100, 100));
button = new JButton("");
button.setPreferredSize(new Dimension(100, 100));
button.setFont(new Font(button.getFont().getName(), button.getFont().getStyle(), 70));
button.setActionCommand("1");
button.addActionListener(this);
mainPanel.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void startMyGame() throws IOException
{
createGUI();
while(true)
{
if(myTurn == false)
{
myTurn = true;
String out = input.readLine();
button.setText(out);
}
}
}
private void close() throws IOException
{
this.sock.close();
this.input.close();
this.output.close();
}
public static void main(String args[])
{
Cli tc = null;
try
{
tc = new Cli();
tc.startMyGame();
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
try
{
tc.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
#Override
public void actionPerformed(ActionEvent e)
{
if(myTurn == true)
{
if(e.getActionCommand().equals("1"))
{
JButton b = (JButton) e.getSource();
if(!b.getText().equals("X") || !b.getText().equals("O"))
{
b.setText("C");
output.println("C");
myTurn = false;
}
}
}
}
}
I have deleted imports so the codes would be shorter.
Current issues with your code:
You're creating a Swing GUI and running it off of the Swing event dispatch thread or EDT. GUI's should be started on the event thread so that all Swing code is guaranteed to run on a single thread.
You've got a long-running while loop, and it is making Swing mutational calls, updating the state of a JButton. If this code were running on the Swing event thread, it would block/freeze the GUI. This block should be explicitly called in a background thread that is not the EDT, and all Swing calls should be queued onto the event thread as per the Lesson: Concurrency in Swing tutorial.
You're using a non-volatile boolean in different threads, risking the variable not being changed when it should be changed
You appear to be closing your streams immediately, preventing adequate communication between concerns.
Working on a cleaner example.......
For example:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.*;
public class SimpleServerClient {
private static final int PORT = 9001;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
try {
SimpleServer server = new SimpleServer(PORT, "Server", false);
SimpleClient client = new SimpleClient(PORT, "Client", true);
server.createGui();
client.createGui();
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
interface SimpleGui {
void sendLine(String nextLine);
}
// background thread handles listening to the Scanner
// which scans a Socket's InputStream
class MyWorker extends SwingWorker<Void, Void> {
public static final String LINE = "line";
private Scanner inputScanner;
private SimpleGui gui;
private String line = "";
public MyWorker(Scanner inputScanner, SimpleGui gui) {
this.inputScanner = inputScanner;
this.gui = gui;
}
#Override
protected Void doInBackground() throws Exception {
while (inputScanner.hasNext()) {
// get line from Scanner
// use the setter method in case we want to use a PropertyChangeListener later
setLine(inputScanner.nextLine());
// send line to the GUI
gui.sendLine(getLine());
}
return null;
}
public String getLine() {
return line;
}
// again rigged up to allow use of PropertyChangeListeners
public void setLine(String line) {
this.line = line;
firePropertyChange(LINE, null, line);
}
}
// code that both the client and server GUI classes share
abstract class DefaultGui implements SimpleGui {
// this guy ***must**** be volitile!
private volatile boolean myTurn;
protected Scanner inputScanner;
protected PrintStream out;
protected JButton button = new JButton("Blank");
protected Socket socket;
protected String name;
protected int port;
public DefaultGui(int port, String name, boolean myTurn) {
this.port = port;
this.name = name;
this.myTurn = myTurn;
}
#Override
public void sendLine(String nextLine) {
button.setText(nextLine);
myTurn = true;
}
public void createGui() {
button.addActionListener(e -> actionPerformed(e));
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(300, 300));
panel.add(button);
JFrame frame = new JFrame(getName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
protected void actionPerformed(ActionEvent e) {
if (!myTurn) {
return;
}
out.println(getName());
button.setText(getName());
myTurn = false;
}
public String getName() {
return name;
}
}
class SimpleServer extends DefaultGui {
private ServerSocket serverSocket;
public SimpleServer(int port, String name, boolean myTurn) throws IOException {
super(port, name, myTurn);
serverSocket = new ServerSocket(port);
new Thread(() -> {
try {
// accept() blocks the current thread, so must be called on a background thread
socket = serverSocket.accept();
inputScanner = new Scanner(socket.getInputStream());
out = new PrintStream(socket.getOutputStream(), true);
new MyWorker(inputScanner, this).execute();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
class SimpleClient extends DefaultGui {
public SimpleClient(int port, String name, boolean myTurn) throws IOException {
super(port, name, myTurn);
socket = new Socket("localhost", port);
inputScanner = new Scanner(socket.getInputStream());
out = new PrintStream(socket.getOutputStream());
new MyWorker(inputScanner, this).execute();
}
}

JOptionPane.showMessageDialog not showing text

I seem to be having some issues when using the JOptionPane.showMessageDialog() method.
When I use the method the only thing that is set up correctly is the dialogs title. It doesn't want to display the text that I provide.
Here's the code that I'm using to try and create an alert:
JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
The code above provides the image below:
If someone could tell me what I'm doing wrong or if there is a different method that I'm supposed to be using, I would much appreciate it.
Edit:
My main class:
This creates a GUI where the user enters information "Host" and "DisplayName". When they click "Connect" a new thread is created (the ClientConnectSocket).
public class Main extends JFrame {
public static JPanel contentPane;
private JTextField hostTxt;
public static JTextField displayNameTxt;
JLabel lblDisplayName = new JLabel("Display Name:");
JButton btnConnect = new JButton("Connect");
JLabel lblHost = new JLabel("Host:");
public static String username = "None :(";
public static String host = "localhost";
public static boolean connected = false;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setType(Type.UTILITY);
setTitle("Java Chat Client - v0.1");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 390, 200);
contentPane = new JPanel();
this.setResizable(false);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
lblHost.setBounds(60, 11, 56, 19);
contentPane.add(lblHost);
hostTxt = new JTextField();
hostTxt.setBounds(165, 10, 103, 20);
contentPane.add(hostTxt);
hostTxt.setColumns(10);
btnConnect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (hostTxt.getText() == null || displayNameTxt.getText() == null){
}else{
Thread ccs = new ClientConnectSocket(hostTxt.getText(), displayNameTxt.getText());
ccs.start();
while (!connected){
//System.out.println("Not connected yet..");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Yey, connected");
username = displayNameTxt.getText();
host = hostTxt.getText();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Chat frame = new Chat();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
dispose();
}
}
});
btnConnect.setBounds((this.getWidth()/2)- 70, 76, 89, 23);
contentPane.add(btnConnect);
displayNameTxt = new JTextField();
displayNameTxt.setColumns(10);
displayNameTxt.setBounds(165, 45, 103, 20);
contentPane.add(displayNameTxt);
lblDisplayName.setBounds(60, 41, 95, 29);
contentPane.add(lblDisplayName);
this.getRootPane().setDefaultButton(btnConnect);
}
ClientConnectSocket class:
public class ClientConnectSocket extends Thread{
String host;
String name;
public ClientConnectSocket(String host, String displayName){
this.host = host;
this.name = displayName;
}
boolean b = true;
public void run(){
try{
while (b){
Socket server = new Socket(host, 6969);
System.out.println("Sending info to try and connect.");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
out.write("method=connect:displayName="+ name);
out.flush();
Thread.sleep(500);
InputStream in = server.getInputStream();
StringBuffer sb = new StringBuffer();
byte[] buffer = new byte[1024];
int buf;
while ((buf = in.read(buffer)) != -1){
String line = new String(buffer, 0, buf);
sb.append(line);
}
in.close();
System.out.println(sb.toString() + " || " + sb.toString().equalsIgnoreCase("connect"));
if (sb.toString().equalsIgnoreCase("connect")){
//Allow them to connect
Main.connected = true;
}else if(sb.toString().equalsIgnoreCase("invalid:Username")){
//Tell them they have username already taken;
JOptionPane.showMessageDialog(null, "alert", "alert", JOptionPane.ERROR_MESSAGE);
b = false;
}
server.close();
out.close();
in.close();
b = false;
}
}catch (Exception e){
System.exit(2);
e.printStackTrace();
}
}
Your posted code snippet suggests that you're running into a Swing threading issue. If your program is a Swing GUI, then most of the above code needs to be called off of the Swing EDT or Event Dispatch Thread, while any Swing calls, including displaying the JOptionPane should be called on the EDT. For more specific help, consider telling and showing more about your code and your use of background threading.
Edit
OK, so that code is in a background thread. So now you must take care to show your JOptionPane on the EDT. Consider making these changes:
} else if(sb.toString().equalsIgnoreCase("invalid:Username")) {
b = false;
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JOptionPane.showMessageDialog(null, "alert", "alert",
JOptionPane.ERROR_MESSAGE);
}
});
}
Note: code not tested by compiling or by running. Please be wary of typos.
Edit 2
As an aside, you've got other issues including that the connected variable should not be static. You also have threading issues:
btnConnect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (hostTxt.getText() == null || displayNameTxt.getText() == null) {
} else {
// .........
// ********** you should not have this type of code on the EDT
while (!connected) {
// ........
}
// ...............
}
}
});

error with DataOutputStream

I keep getting an NullPointerException, and I dont know why. what the class is supposed to do, is to send whatever I write in my jtextfield as writeUTF, but I keep getting a NullPointerException at
dos = new DataOutputStream(socket.getOutputStream());
The GUI code:
public class GUI {
private JFrame frame = new JFrame("Dryck & Ingrediens"); // GUI
private JTextField jtf = new JTextField();// GUI
private JTextArea jl1 = new JTextArea();// GUI
private JList jl = new JList();// GUI
private JScrollPane js = new JScrollPane(jl);// GUI
private DataOutputStream dos;// ServerHandler
private JLabel lab = new JLabel("Ange dryck");//GUI
private JLabel lab1 = new JLabel("Walid Shams");
private JLabel lab2 = new JLabel("Kushtrim Brahimi");
private HashMap<String, ArrayList<String>> drinkar = null;//Controller
private DataInputStream dis;
private Socket socket;
private ServerHandler serverH;
public GUI() {
frame.getContentPane().setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(50, 300, 420, 400);
frame.setResizable(false);
frame.setVisible(true);
js.add(jl);
js.add(jl1);
jl1.setEditable(false);
lab.setBounds(170, 20, 130, 20);
lab1.setBounds(300, 310, 130, 20);
lab2.setBounds(300, 330, 130,20);
jtf.setBounds(130, 40, 150, 40);
jl.setBounds(50, 90, 150, 200);
jl1.setBounds(210, 90, 150, 200);
Container con = frame.getContentPane();
con.setBackground(Color.cyan);
This is where the error accures and where i get the nullpointerexception everytime i type something in my jtextfield.
jtf.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
if (dos == null) {
if (jtf.getText().length() > 0) {
try {
dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(jtf.getText());
} catch (IOException ex) {
Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
String[] empty = new String[]{""};
jl.setListData(empty);
}
}
}
}
);
jl.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (jl.getSelectedIndex() != -1) {
String item = (String) jl.getSelectedValue();
jl1.setText("");
for (String ingrediens : drinkar.get(item)) {
jl1.append(ingrediens + "\n");
}
}else{
jl1.setText("");
}
}
});
frame.add(jtf);
frame.add(jl);
frame.add(jl1);
frame.add(lab);
frame.add(lab1);
frame.add(lab2);
frame.add(js);
}
// tar emot arrayen, lagrar i ny array och visar i JList
public void getArrayList() {
String[] arr = null;
for(int i = 0; i < arr.length; i++){
arr = serverH.setList();
}
jl.setListData(arr);
}
public static void main(String[] args) {
GUI g = new GUI();
}
}
Regarding:
dos = new DataOutputStream(socket.getOutputStream());
The only variable that can throw an NPE on this line is socket which begs the question: where do you initialize socket?
Answer: you don't.
Solution: fix this.
Please always check the variables on the line that throws the NPE as that will show you the cause for the error 99% of the time. You haven't appeared to have tried to do this yet.
You define an instance variable »serverH«
private ServerHandler serverH;
but don't assign any object to it. Therefore you should be facing the NullPointerException. You should assign an object to it, e.g.
serverH = new ServerHandler();
This should solve your problem regarding the NullPointerException.

Building a simple chat client

Im building a simple chat client which is only supposed to be able to send and receive messages.
Im using a server running on my own computer that sends back whatever message is sent to it, to all the user that's connected to the server.
When I send messages to the server by clicking my "send button", the server isn't sending back the message to me as it's supposed to. So either my output stream isn't working, or my listener for input messages isn't working but can't figure out what is wrong.
I might add, that i don't get any error messages/exceptions and connecting to the server works
public class Chatt extends JFrame implements Runnable{
private JPanel topPanel = new JPanel();
private JPanel bottomPanel = new JPanel();
private JTextArea chattArea = new JTextArea();
private JButton sendButton = new JButton("Skicka");
private JLabel chattPerson = new JLabel("Du chattar med: ");
private JTextField chattField = new JTextField(15);
private Thread thread;
private int port;
private String ip;
private DataInputStream in;
private DataOutputStream out;
private Socket s;
public Chatt(String ip, int port){
this.ip=ip;
this.port=port;
Konstruktor();
}
public Chatt(){
ip="127.0.0.1";
port=2000;
Konstruktor();
}
public Chatt(String ip){
this.ip=ip;
port=2000;
Konstruktor();
}
public void Konstruktor(){
setLayout(new BorderLayout());
chattArea.setSize(70, 50);
add(chattArea, BorderLayout.CENTER);
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
bottomPanel.add(sendButton);
bottomPanel.add(chattField);
sendButton.addActionListener(new sendListener());
add(bottomPanel, BorderLayout.SOUTH);
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
topPanel.add(chattPerson);
add(topPanel, BorderLayout.NORTH);
try {
//s = new Socket("atlas.dsv.su.se", 9494);
s=new Socket(ip, port);
}
catch (UnknownHostException e) {
System.out.println("Connection failed");
}
catch (IOException e) {
}
try{
in= new DataInputStream(new BufferedInputStream(s.getInputStream()));
out= new DataOutputStream(new BufferedOutputStream(s.getOutputStream()));
}
catch(UnknownHostException e){
System.out.println("Host unknown");
}
catch(IOException e){
}
thread = new Thread(this);
thread.start();
setTitle("Connected to "+ip+" på port "+port);
chattArea.setEditable(false);
setSize(400, 500);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void run() {
while(true){
System.out.println("tråden igång");
try {
String temp = in.readUTF();
System.out.println(temp);
chattArea.append(temp);
} catch (IOException e) {
}
}
}
public class sendListener implements ActionListener{
public void actionPerformed(ActionEvent e){
String chattString = chattField.getText();
try {
out.writeUTF(chattString);
out.flush();
}
catch (IOException e1) {
}
chattArea.append("Du: "+chattString+"\n");
chattField.setText("");
}
}
public static void main(String[] args){
//new Chatt("127.0.0.1", 2000);
//new Chatt();
new Chatt("127.0.0.1");
}
}
I can confirm that the chatserver wasn't working correctly. I did build my own server and sending/reciving messages works fine, so nothing wrong with my code.

Categories