Hello everyone,
Actually I want to learn more about thread, can we have more than one "run" for thread in a program ?

package ignisftpv20;

import javax.swing.JFileChooser;
import java.io.*;
import java.net.*;
import javax.swing.JOptionPane;

public class FTPClient extends javax.swing.JFrame implements Runnable {




    
JFileChooser fileChooser = new JFileChooser();
File fileUpload;
ObjectInputStream input;
ObjectOutputStream output;



    FileInputStream fis;
    FileOutputStream fout;

    File file;







    public FTPClient() {
        initComponents();
        new Thread( this ).start();
    }









    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        btnBrowse = new javax.swing.JButton();
        btnSend = new javax.swing.JButton();
        btnConnect = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("FTP Client");

        btnBrowse.setText("Browse");
        btnBrowse.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnBrowseActionPerformed(evt);
            }
        });

        btnSend.setText("Send File");
        btnSend.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSendActionPerformed(evt);
            }
        });

        btnConnect.setText("Connect");
        btnConnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConnectActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(91, 91, 91)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnSend)
                    .addComponent(btnBrowse)
                    .addComponent(btnConnect))
                .addContainerGap(107, Short.MAX_VALUE))
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btnBrowse, btnConnect, btnSend});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(65, 65, 65)
                .addComponent(btnConnect)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(btnBrowse)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnSend, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(113, Short.MAX_VALUE))
        );

        layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {btnBrowse, btnConnect, btnSend});

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-281)/2, (screenSize.height-327)/2, 281, 327);
    }// </editor-fold>











//browse
    private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt) {
        int flag = fileChooser.showOpenDialog(FTPClient.this);

        if (flag == JFileChooser.APPROVE_OPTION) {
            fileUpload = fileChooser.getSelectedFile();

        }



}



//connect
    private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {
       try{

            Socket s = new Socket ("127.0.0.1" , 5555);
            input = new ObjectInputStream(s.getInputStream());
            output = new ObjectOutputStream(s.getOutputStream());
            JOptionPane.showMessageDialog(null, "OK Houston");
            }catch(Exception e){e.printStackTrace();}


    }

    
    
//send file
    private void btnSendActionPerformed(java.awt.event.ActionEvent evt) {

           new Thread(this).start();
    }


    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FTPClient().setVisible(true);
            }
        });
    }

public void run(){

        sendBytes();

}


public void sendBytes(){
        try{
            fis = new FileInputStream(fileUpload.getName());


            byte[] buffer = new byte[1024];
            int bytes = 0;

            while((bytes = fis.read(buffer))!=-1)
            {
                output.write(buffer,0,bytes);

            }




        }catch(Exception e){e.printStackTrace();}

}
    

    // Variables declaration - do not modify
    private javax.swing.JButton btnBrowse;
    private javax.swing.JButton btnConnect;
    private javax.swing.JButton btnSend;
    // End of variables declaration

}

I want to run everything in button Connect, btnConnect

//connect
private void btnConnectActionPerformed
.
.
.

in a new thread.

How to do that, thanks.

Recommended Answers

All 26 Replies

Not certain that I understand the Q, but you can only have 1 run() in a class, so if there are other things you want to start new threads for you need an additional small Runnable class to do it. You can use an anonymous inner class (Google it if unfamiliar) for this, like this:

new Thread(new Runnable() {
  public void run() {
      // call a method in your main class to do the work 
  }
}).start();

Hello,
Thanks for the answer. I am having another problem. My application freeze. I have done a similar application, chat and it was working, now i applied the same logic for the ftp and its freezing. Can someone help me please.

This is the server class:

package ignisftpv20;

import java.net.*;
import java.io.*;
import javax.swing.JOptionPane;


public class FTPServer extends javax.swing.JFrame implements Runnable {





    public FTPServer() {
        initComponents();
    }



    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        btnServer = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("FTP Server");

        btnServer.setText("Start Server");
        btnServer.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnServerActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(78, 78, 78)
                .addComponent(btnServer)
                .addContainerGap(96, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(52, Short.MAX_VALUE)
                .addComponent(btnServer, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(38, 38, 38))
        );

        pack();
    }// </editor-fold>






    private void btnServerActionPerformed(java.awt.event.ActionEvent evt) {
       
        new Thread (this).start();

    }



    public void run(){

        waitForConnection();
    }



public void waitForConnection(){
            try{
                ServerSocket ss = new ServerSocket(5555);

                    while(true){
                        Socket soc = ss.accept();
                        JOptionPane.showMessageDialog(null, "I got a connection!");
                        System.out.println("Connected from: "+ soc.getInetAddress().getHostName()+"..." );

                        new FTPServerReceiver( this, soc );
                         new Thread (this).start();

                    }
            
            }catch(Exception e){ e.printStackTrace();}

}




    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FTPServer().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JButton btnServer;
    // End of variables declaration

}

You start the server on the Swing event thread, and in that you wait for the connection, thus blocking the Swing thread.

Yes,in the waitForConnection, it was a mistake.

But " start the server on the Swing event thread", you mean on the button?

When you have GUI applications, they usually should run on the Event Dispatch Thread. The EDT is what James is talking about when he says the Swing thread. Since you are waiting for a connection on the EDT, you are blocking the thread, since a Thread can only do one task at once. (Think of it like this: when you run any old program, the code executes in order, so the later code has to wait for the earlier code to execute). If you read the first page of the link, you'll gain a better understanding of the event dispatch thread. Also, there is a link in there on the first page to "memory consistency errors". I personally think it is interesting, you may want to check that out also, although it is slightly off topic.

Hello ... thanks for the answer, i read it but still can't solve the problem, its not working when I removed the tread from the constructor.

The message "OK Houston" does not appears which means that the blocking situation is over there.

Thanks in advance.

Without an up-to-date code listing there's not a lot I can do, but...
Maybe you should take a few moments to clarify your architecture in terms of its threading. You need 3+ threads, (1) The "swing" or "EDT" thread where you do all your user interface stuff. (2) The server thread where you wait for new connections and (3) the connection handler thread(s) that you create to handle each connection as it's made.
So in your main(...) method I would expect to see a call to set up the GUI (which if you want to be pedantic you should schedule on the Swing thread, but few people would bother), and a new Thread to start the server. Judging by the code you posted, I suspect you may be getting problems because you have mixed the server code in with the GUI code - they really should be separate.

Hello,
I am sending you the modified one, please put a comment for me to understand this.

Thanks in advance.

package ignisftpv20;

import javax.swing.JFileChooser;
import java.io.*;
import java.net.*;
import javax.swing.JOptionPane;

public class FTPClient extends javax.swing.JFrame implements Runnable {




    
JFileChooser fileChooser = new JFileChooser();
File fileUpload;
ObjectInputStream input;
ObjectOutputStream output;



    FileInputStream fis;
    FileOutputStream fout;

    File file;







    public FTPClient() {
        initComponents();
       
     


    }









    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        btnBrowse = new javax.swing.JButton();
        btnSend = new javax.swing.JButton();
        btnConnect = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("FTP Client");

        btnBrowse.setText("Browse");
        btnBrowse.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnBrowseActionPerformed(evt);
            }
        });

        btnSend.setText("Send File");
        btnSend.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSendActionPerformed(evt);
            }
        });

        btnConnect.setText("Connect");
        btnConnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConnectActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(91, 91, 91)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnSend)
                    .addComponent(btnBrowse)
                    .addComponent(btnConnect))
                .addContainerGap(107, Short.MAX_VALUE))
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btnBrowse, btnConnect, btnSend});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(65, 65, 65)
                .addComponent(btnConnect)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(btnBrowse)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnSend, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(113, Short.MAX_VALUE))
        );

        layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {btnBrowse, btnConnect, btnSend});

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-281)/2, (screenSize.height-327)/2, 281, 327);
    }// </editor-fold>                        











//browse
    private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt) {                                          
        int flag = fileChooser.showOpenDialog(FTPClient.this);

        if (flag == JFileChooser.APPROVE_OPTION) {
            fileUpload = fileChooser.getSelectedFile();

        }



}                                         



//connect
    private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {                                           

        connectToServer();


    }                                          


    
    
//send file
    private void btnSendActionPerformed(java.awt.event.ActionEvent evt) {                                        

           new Thread(this).start();
    }                                       


    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FTPClient().setVisible(true);
            }
        });
    }


public void run(){
        connectToServer();
        sendBytes();

}


public void connectToServer(){

           try{
                Socket s = new Socket ("127.0.0.1" , 5555);
                input = new ObjectInputStream(s.getInputStream());
                output = new ObjectOutputStream(s.getOutputStream());
                JOptionPane.showMessageDialog(null, "OK Houston");
            }catch(Exception e){e.printStackTrace();}
}





public void sendBytes(){
        try{
            fis = new FileInputStream(fileUpload.getName());


            byte[] buffer = new byte[1024];
            int bytes = 0;

            while((bytes = fis.read(buffer))!=-1)
            {
                output.write(buffer,0,bytes);

            }




        }catch(Exception e){e.printStackTrace();}

}
    

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnBrowse;
    private javax.swing.JButton btnConnect;
    private javax.swing.JButton btnSend;
    // End of variables declaration                   

}
package ignisftpv20;

import java.net.*;
import java.io.*;
import javax.swing.JOptionPane;


public class FTPServer extends javax.swing.JFrame implements Runnable {





    public FTPServer() {
        initComponents();
        new Thread (this).start();
    }



    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        btnServer = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("FTP Server");

        btnServer.setText("Start Server");
        btnServer.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnServerActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(78, 78, 78)
                .addComponent(btnServer)
                .addContainerGap(96, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(52, Short.MAX_VALUE)
                .addComponent(btnServer, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(38, 38, 38))
        );

        pack();
    }// </editor-fold>                        






    private void btnServerActionPerformed(java.awt.event.ActionEvent evt) {                                          
       
        

    }                                         



    public void run(){

        waitForConnection();
    }



public void waitForConnection(){
            try{
                ServerSocket ss = new ServerSocket(5555);

                    while(true){
                        Socket soc = ss.accept();
                        JOptionPane.showMessageDialog(null, "I got a connection!");
                        System.out.println("Connected from: "+ soc.getInetAddress().getHostName()+"..." );

                        new FTPServerReceiver( this, soc );
                      

                    }
            
            }catch(Exception e){ e.printStackTrace();}

}




    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FTPServer().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnServer;
    // End of variables declaration                   

}



[code]



package ignisftpv20;

import java.io.*;
import java.net.*;

public class FTPServerReceiver implements Runnable{


    FTPServer ftpServer;
    Socket thesocket;
    Byte bt;
    ObjectInputStream input;
    FileOutputStream fout;

    String directoryName = "C:/Documents and Settings/Host Intruder/Desktop/Complete Download";




    public FTPServerReceiver(FTPServer ftpServer, Socket s){

        this.ftpServer = ftpServer;
        this.thesocket = s;
        new Thread( this ).start();
    }

//read and write file
    public void run(){

        try{
            while(true){


            input = new ObjectInputStream(thesocket.getInputStream());
            byte[] buffer = new byte[1024];
            int bytes = 0;
            
            //input.read(buffer,0,bytes);

            File f = new File(directoryName,"file1");
            fout = new FileOutputStream(f);


            fout.write(input.read(buffer,0,bytes));







            }

        }catch(Exception e){e.printStackTrace();}



    }
}

[/code]

Don't have time to read all code now, but it looks like you're still starting the server in the Swing thread!

Thanks for the answer but where James. You mean here:

public FTPServer() {
        initComponents();
        new Thread (this).start();
    }

should be like this:

public FTPServer() {
        initComponents();
        //remove
    }

I have tried but its still not working.

(sorry man, need to go offline now, will get back tomorrow with any luck)

Its OK ... thanks.

Thanks for the info, but my problem is still unsolved.. can't get it to work.

I can't add much to what I said in post 9. I would separate the GUI, the server, and the connection handler into 3 classes, and make sure each is started in its own thread. This really looks like the code "just grew" to the point where it's too hard to work with, you have to go back and do a bit of design!

Okie .. thanks for the answers James, I will work it out and let you know if I am having any problems, thanks for the info BJSJC. ;)

Thanks a lot James, I followed your instructions and its working fine. I've just separated the user interface from the business logic. But still can't understand the logic, I will not mark this thread as solve yet as I got some questions.

Thanks a lot.

OK neutralfox, stick with it! (ps what time zone are you in, if you don't mind saying?)

Okie .. thanks for the answers James, I will work it out and let you know if I am having any problems, thanks for the info BJSJC. ;)

You're welcome, but I don't know how much you got out of that (unless you went on to read other articles on the topic), because I'm finding myself feeling like I know less and less about the topic as I read more. I'll be back to ask questions about it on this forum though (not the definition of mvc, but the application of it), so maybe we can all learn something.

:)

Yeppp, we never stop to learn. Thanks a lot for all your help ... GMT+4 and you.

GMT+2 (including summer time). I'm certainly up for discussions on design patterns. I've spent many years teaching and consulting on OO design with companies such as IBM and HP, so it's a real passion of mine.
For starters, let me suggest that MVC in Swing really doesn't fit. It's painful to try to separate the view from the controller in a typical Swing UI. In practice it almost always compacts down to a UI / Business Objects(s) 2-layer model. You only need full MVC where there are many business objects and you need some kind of overall "process control" to marshal them.
Or maybe we should take this to a new thread?
J

GMT-5

Wow, you get up early!

It's painful to try to separate the view from the controller in a typical Swing UI. In practice it almost always compacts down to a UI / Business Objects(s) 2-layer model.
J

It seems to be practically the same thing with three tiered architecture. At least for small applications.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.