I am trying to build a LAN communication software where the process should be like this, when the user is logged in then networking between the client and server should start.
The problem that I am facing is that whenever I put my startRunning()(this is the method that starts the networking) method inside the addactionlistener of the button the whole software freezes but if I put the method outside of addactionlistener the networking starts fine. The problem is in the btnNewButton.addActionListener .If the count is 1 then it should call the startrunning() method which it doesn't and the whole software freezes.
Every method starting from the startRunning() method to down below is working perfectly.The database is also capable of checking whether the given username and password is correct or not. This software runs well when the startRunning method is in the constructor but not inside the btnNewButton.addActionListener.
public class Server extends JFrame {
private JTextField userText;
private JTextArea chatWindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
Connection dbconnection = null;
private JTextField textField_1;
private JPasswordField passwordField_1;
public Server() {
super("Communication system");
dbconnection = sqliteConnection.dbConnector();
setupFrame();
}
private void setupFrame() {
setBounds(100, 100, 450, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
JLabel lblNewLabel = new JLabel("UserName");
lblNewLabel.setBounds(10, 11, 81, 14);
getContentPane().add(lblNewLabel);
JLabel lblNewLabel_1 = new JLabel("Password");
lblNewLabel_1.setBounds(10, 36, 59, 14);
getContentPane().add(lblNewLabel_1);
JButton btnNewButton = new JButton("Login");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
String query = "SELECT * FROM EmplyeeInfo WHERE Username=? and password=?";
PreparedStatement pst = dbconnection
.prepareStatement(query);
pst.setString(1, textField_1.getText());
pst.setString(2, passwordField_1.getText());
ResultSet rs = pst.executeQuery();
int count = 0;
while (rs.next()) {
count++;
}
if (count == 1) {
textField_1.setText("");
passwordField_1.setText("");
JOptionPane.showMessageDialog(null,
"Correct Username and Password");
startRunning();
} else {
textField_1.setText("");
passwordField_1.setText("");
JOptionPane.showMessageDialog(null, "Wrong try again");
}
rs.close();
pst.close();
} catch (Exception e) {
// TODO: handle exception
JOptionPane.showMessageDialog(null, e);
}
}
});
btnNewButton.setBounds(335, 7, 89, 23);
getContentPane().add(btnNewButton);
textField_1 = new JTextField();
textField_1.setBounds(101, 8, 224, 20);
getContentPane().add(textField_1);
passwordField_1 = new JPasswordField();
passwordField_1.setBounds(101, 33, 224, 20);
getContentPane().add(passwordField_1);
userText = new JTextField();
userText.setBounds(10, 230, 330, 20);
userText.setEditable(false);
userText.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
// TODO Auto-generated method stub
sendMessage(event.getActionCommand());
userText.setText("");
}
});
getContentPane().add(userText);
userText.setColumns(10);
chatWindow = new JTextArea();
chatWindow.setBounds(10, 75, 330, 144);
getContentPane().add(chatWindow);
setVisible(true);
}
// set up and run the server
public void startRunning() {
try {
server = new ServerSocket(6789, 100);
while (true) {
try {
waitForConnection();
setupStreams();
whileChatting();
} catch (EOFException eofException) {
// TODO: handle exception
showMessage("\nServer Ended the conection!");
} finally {
closeCrap();
}
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
// wait for the connection, then display connection
private void waitForConnection() throws IOException {
showMessage("Waiting for someone to connect... \n");
connection = server.accept();
showMessage(" Now connected to "
+ connection.getInetAddress().getHostName());
}
// get stream to send and receive data
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\n Streams are now Setup \n");
}
// during the chat conversation
private void whileChatting() throws IOException {
String message = " You are now connected";
sendMessage(message);
ableToType(true);
do {
// have a conversation
try {
message = (String) input.readObject();
showMessage("\n" + message);
} catch (ClassNotFoundException classNotFoundException) {
showMessage("\n I don't know what the user send");
}
} while (!message.equals("CLIENT - END"));
}
// closing the streams and sockets after done chatting
private void closeCrap() {
showMessage("\n closing connections...\n");
ableToType(false);
try {
output.close();
input.close();
connection.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
// send message to a client
private void sendMessage(String message) {
try {
output.writeObject("SERVER - " + message);
output.flush();
showMessage("\nSERVER -" + message);
} catch (IOException ioException) {
chatWindow.append("\n Error : can't send the message");
}
}
// updates chat window
private void showMessage(final String text) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
chatWindow.append("" + text);
}
});
}
// allowing user to type stuff in the box
private void ableToType(final boolean tof) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
userText.setEditable(tof);
}
});
}
}
You may have to put it in a different thread - you can localize the thread to include only the startRunning method or what you want:
public void actionPerformed(ActionEvent arg0) {
Thread th=new Thread() {
public void run() {
try {
String query = "SELECT * FROM EmplyeeInfo WHERE Username=? and password=?";
PreparedStatement pst = dbconnection
.prepareStatement(query);
pst.setString(1, textField_1.getText());
pst.setString(2, passwordField_1.getText());
ResultSet rs = pst.executeQuery();
int count = 0;
while (rs.next()) {
count++;
}
if (count == 1) {
textField_1.setText("");
passwordField_1.setText("");
JOptionPane.showMessageDialog(null,
"Correct Username and Password");
startRunning();
} else {
textField_1.setText("");
passwordField_1.setText("");
JOptionPane.showMessageDialog(null, "Wrong try again");
}
rs.close();
pst.close();
} catch (Exception e) {
// TODO: handle exception
JOptionPane.showMessageDialog(null, e);
}
}
};
th.start();
});
Related
I have a server project and a client project (2 clients, a customer and an admin, from the customer GUI/Frame you can go to the admin GUI and move between GUIs as needed).
I have a button on each GUI/Frame which just sends a String to the server when it's clicked. I'm printing out the threads that are being created and I know that SwingWorkers Thread pool defaults to 10, and then it starts reusing threads.
I've noticed that once the created Threads hit 10, then the buttons to send requests to the server do not seem to send any data because the Thread pool is fully occupied.
I wanted to know how I can prevent this so a user can switch between the GUIs for x amount of time.
--
Server
public class Testserver {
private ServerSocket serverSocket;
private Socket client;
private final int PORT = 5432;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
public Testserver() {
System.out.println(Thread.currentThread().getName());
try {
serverSocket = new ServerSocket(PORT);
System.out.println("Waiting for connection");
} catch (IOException ex) {
Logger.getLogger(Testserver.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void listenForClients() {
try {
while (true) {
client = serverSocket.accept();
System.out.println("client connected");
objectOutputStream = new ObjectOutputStream(client.getOutputStream());
objectInputStream = new ObjectInputStream(client.getInputStream());
processClient();
}
} catch (IOException ex) {
Logger.getLogger(Testserver.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Testserver().listenForClients();
});
}
private void processClient() {
SwingWorker worker = new SwingWorker<>() {
#Override
protected Void doInBackground() throws Exception {
System.out.println(Thread.currentThread().getName());
do {
try {
String messageFromClient = (String) objectInputStream.readObject();
System.out.println("[CLIENT] " + messageFromClient);
} catch (IOException ex) {
Logger.getLogger(Testserver.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Testserver.class.getName()).log(Level.SEVERE, null, ex);
}
} while (true);
}
};
worker.execute();
}
}
Customer Client
public class CustomerGUI extends JFrame implements ActionListener{
private Socket server;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
private JButton btnAdminGUI,btnAddCustomer;
private final int PORT = 5432;
public CustomerGUI() {
btnAdminGUI = new JButton("Go to Admin GUI");
btnAddCustomer = new JButton("Add customer");
try {
server = new Socket("localhost", PORT);
System.out.println("Connected to server");
objectOutputStream = new ObjectOutputStream(server.getOutputStream());
objectInputStream = new ObjectInputStream(server.getInputStream());
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
}
btnAdminGUI.addActionListener(this);
btnAddCustomer.addActionListener(this);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new CustomerGUI().setGUI();
});
}
public void setGUI() {
setLayout(new GridLayout(2,1));
add(btnAdminGUI);
add(btnAddCustomer);
setSize(300, 400);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnAdminGUI) {
new AdminGUI().setGUI();
dispose();
} else if(e.getSource() == btnAddCustomer) {
try {
objectOutputStream.writeObject("Added a customer");
objectOutputStream.flush();
} catch (IOException ex) {
Logger.getLogger(AdminGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Admin Client(Pretty much the same as Customer)
public class AdminGUI extends JFrame implements ActionListener{
private Socket server;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
private JButton btnCustomerGUI, btnAddAdmin;
private final int PORT = 5432;
public AdminGUI() {
btnCustomerGUI = new JButton("Go to Customer GUI");
btnAddAdmin = new JButton("Add admin");
try {
server = new Socket("localhost", PORT);
System.out.println("Connected to server");
objectOutputStream = new ObjectOutputStream(server.getOutputStream());
objectInputStream = new ObjectInputStream(server.getInputStream());
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
}
btnAddAdmin.addActionListener(this);
btnCustomerGUI.addActionListener(this);
}
public void setGUI() {
setLayout(new GridLayout(2,1));
add(btnCustomerGUI);
add(btnAddAdmin);
setSize(300, 400);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnCustomerGUI) {
new CustomerGUI().setGUI();
dispose();
} else if(e.getSource() == btnAddAdmin) {
try {
objectOutputStream.writeObject("Added an admin");
objectOutputStream.flush();
} catch (IOException ex) {
Logger.getLogger(AdminGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
EDIT
Updated working method code using FixedThreadPool
private void processClient() {
System.out.println("cores: " + Runtime.getRuntime().availableProcessors());
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
executor.execute(() -> {
System.out.println(Thread.currentThread().getName());
do {
try {
String messageFromClient = (String) objectInputStream.readObject();
System.out.println("[CLIENT] " + messageFromClient);
if (messageFromClient.equalsIgnoreCase("Exit")) {
System.out.println("closed connection to " + client);
closeConnections();
System.exit(0);
}
} catch (IOException ex) {
//JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
//JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
System.out.println("ClassNotFoundException in process client: " + ex.getMessage());
} catch (Exception ex) {
ex.printStackTrace();
//JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
System.out.println("Exception in process client: " + ex.getMessage());
}
} while (true);
});
executor.shutdown();
}
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 problem with listening to my server output. I would like to be able to print something to the console as soon as one of the quoted command. The problem that I face is that it seems to be listening but then not go along with the rest of the program. So when I try to click on a button on my GUI, it get stuck.
public class MainFrame implements Runnable {
//declare Jpanel
private static JFrame frmHome;
// The client socket
private static Socket clientSocket = null;
// The output stream
static ObjectOutputStream os;
// The input stream
static ObjectInputStream is;
private static BufferedReader inputLine = null;
private static boolean closed = false;
public static void main(String[] args) throws IOException{
// The default port.
int portNumber = 3333;
// The default host.
String host = "localhost";
/*
* Open a socket on a given host and port. Open input and output streams.
*/
try {
clientSocket = new Socket(host, portNumber);
is = new ObjectInputStream(clientSocket.getInputStream());
os = new ObjectOutputStream(clientSocket.getOutputStream());
os.flush();
System.out
.println("CONNECTED TO SERVER\n"
+ "Now using host=" + host + ", portNumber=" + portNumber);
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + host);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to the host "
+ host);
}
/*
* If everything has been initialized then we want to write some data to the
* socket we have opened a connection to on the port portNumber.
*/
if (clientSocket != null && os != null && is != null) {
/* Create a thread to read from the server. */
new Thread(new MainFrame()).start();
os.writeObject("Home");
os.flush();
}
}
public void run() {
/*
* Keep on reading from the socket till we receive "Bye" from the
* server. Once we received that then we want to break.
*/
MainFrame window = new MainFrame();
MainFrame.frmHome.setVisible(true);
String responseLine;
try {
while (!closed) {
Here is where I try to create my buffer reader. The 2 commands "Modify,OK" and "AdStudent ok", are coming after other parts of the GUI have successfully performed a task.
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String line;
try {
while((line = br.readLine()) != null){
if (br.readLine().contains("Modify,OK")
|| br.readLine().contains("AddSudent ok")){
System.out.println("did it");
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} finally{
try {
is.close();
os.close();
clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public MainFrame() {
initialize();
}
//function to make window visible
void setVisible() throws IOException {
main(null);
}
private void initialize() {
//Initialise Main window with 3 options.
frmHome = new JFrame();
frmHome.setTitle("Home");
frmHome.setBounds(100, 100, 300, 372);
frmHome.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmHome.getContentPane().setLayout(null);
frmHome.setResizable(false);
JLabel lblWelcomeToSrs = new JLabel("Welcome to SRS");
lblWelcomeToSrs.setFont(new Font("Tahoma", Font.PLAIN, 14));
lblWelcomeToSrs.setBounds(86, 183, 112, 14);
frmHome.getContentPane().add(lblWelcomeToSrs);
//initialise all buttons and labels of window.
JButton btnAdStu = new JButton("Add a student");
btnAdStu.setBounds(10, 207, 126, 23);
btnAdStu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
AddStudentFrame adus;
try {
try {
adus = new AddStudentFrame();
adus.setVisible();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
frmHome.setVisible(false);
} catch (ParseException e) {
e.printStackTrace();
}
}
});
frmHome.getContentPane().add(btnAdStu);
JButton btnCheckStud = new JButton("Search / Modify");
btnCheckStud.setBounds(146, 207, 127, 23);
btnCheckStud.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
SearchFrame searchFrame;
searchFrame = new SearchFrame();
searchFrame.setVisible();
}
});
frmHome.getContentPane().add(btnCheckStud);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setBounds(0, 0, 0, 0);
frmHome.getContentPane().add(lblNewLabel);
JLabel lblCreatedByRmi = new JLabel("Created by R\u00E9mi Tuyaerts");
lblCreatedByRmi.setBounds(147, 318, 184, 14);
frmHome.getContentPane().add(lblCreatedByRmi);
JButton btnNewButton = new JButton("Complete List of Students");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
CompleteListFrame studentList = new CompleteListFrame();
studentList.setVisible();
}
});
btnNewButton.setBounds(52, 241, 184, 23);
frmHome.getContentPane().add(btnNewButton);
// wonderful pictures of his excellence design by Yasser
JLabel lblNewLabel_1 = new JLabel("");
Image img = new ImageIcon(frmHome.getClass().getResource("/michaelchung.jpg")).getImage();
lblNewLabel_1.setIcon(new ImageIcon(img));
lblNewLabel_1.setBounds(80, 11, 120, 148);
frmHome.getContentPane().add(lblNewLabel_1);
}
}
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) {
// ........
}
// ...............
}
}
});
I wanted to authenticate a user.
For this I am using mysql connection.
The following is the code :
JTextField txt_Username= new JTextField();
String Username;
txt_Username.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent arg0) {
{
Username= txt_Username.getText();
}
});
Similarly there is code for password.
Now I want this username and password outside of its local scope so that clicking on the JButton will fire the sql databse and authenticate with the above username and password.
I am a naive in Java. Could anybody please help in here ?
I have the full code here . Please I need to understand where I am going wrong :
import java.awt.EventQueue;
public class Frame{
private private JFrame frame1;
private JTextField textFieldUserName;
private JTextField txtPassword;
public String textUserValue;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Frame window = new Frame();
window.frame1.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
* #throws SQLException
*/
public multipleFrame() throws SQLException {
initialize();
}
/**
* Initialize the contents of the frame.
* #throws SQLException
*/
private void initialize() throws SQLException {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setIcon(new ImageIcon("C:\\sad.jpg"));
lblNewLabel.setBounds(10, 36, 196, 187);
frame.getContentPane().add(lblNewLabel);
JLabel lbl_Password = new JLabel("PASSWORD");
lbl_Password.setBackground(new Color(128, 128, 128));
lbl_Password.setOpaque(true);
lbl_Password.setBounds(217, 140, 75, 14);
frame.getContentPane().add(lbl_Password);
final Connection con =DriverManager.getConnection("jdbc:mysql://localhost:3306/schema","user","pwd");
final JTextField textFieldUserName = new JTextField();
textFieldUserName.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent arg0) {
String textUserValue = textFieldUserName.getText();
System.out.println(textUserValue+" hi");
String textUserValue1 =textUserValue;
}
});
System.out.println(textUserValue+" HI");
textFieldUserName.setBounds(324, 79, 108, 20);
frame.getContentPane().add(textFieldUserName);
textFieldUserName.setColumns(10);
System.out.println();
JLabel label = new JLabel("USERNAME");
label.setOpaque(true);
label.setBackground(Color.GRAY);
label.setBounds(216, 82, 75, 14);
frame.getContentPane().add(label);
txtPassword = new JTextField();
txtPassword.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent arg0) {
String textPasswordValue = txtPassword.getText();
System.out.println(textPasswordValue+" hi");
}
});
txtPassword.setColumns(10);
txtPassword.setBounds(324, 137, 108, 20);
frame.getContentPane().add(txtPassword);
JButton btnLogin = new JButton("LOGIN");
btnLogin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
}
});
btnLogin.setBounds(262, 200, 91, 23);
frame.getContentPane().add(btnLogin);
PreparedStatement stmt1 = null;
try {
stmt1 = con.prepareStatement("select username from LOGIN_TABLE where username='"+textUserValue+"'");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ResultSet result1 = null;
try {
result1 = stmt1.executeQuery();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
while (result1.next()) {
String user_name_db=result1.getString("username");
System.out.println(user_name_db);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Turn your Username variable into public. And place it just inside the class, not in any method.
Example:
public String Username;
Or if you want to retain its privacy you can create a .getMethod for it.
public String getUsername(){
return Username;
}
You can just create a model class with getters and setters:
class UserModel.java
public String Username;
public String getUserName()
{
return Username;
}
public void setUserName(String USER_NAME)
{
this.Username = USER_NAME;
}
In the main.java,
UserModel userObj = new UserModel();
txt_Username.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent arg0) {
{
userObj.setUserName(txt_Username.getText());
//Username= txt_Username.getText();
}
});
To retrieve it anywhere in main.java, use
String userName = userObj.getUserName();