I am trying to create an ftp client which supports both protocols ftp and sftp. I have two methods startFTP()
for ftp and startSFTP()
for sftp. The connection parameters are loaded from a configuration file.
When I click on the button which execute one of two methods all JButton, JCombobox stays and menus stay down and are not clickable while the FTP client method is under execution, and I can't stop or exit the program.
Here is my code:
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
import static javafx.application.Platform.exit;
import javax.swing.JTextArea;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
public class FtpInfo {
static Properties props;
static String outmsg = null;
/**
* @return the outmsg
*/
public String getOutmsg() {
return outmsg;
}
public boolean startFTP(String chooseddate, String serverAddresss, String userIdd, String passwordd, String remoteDirectoryy, String localDirectoryy) {
try {
outmsg = " APPLICATION" + "\n" + "=====================" + "\n";
String serverAddress = serverAddresss;
String userId = userIdd;
String password = passwordd;
String remoteDirectory = remoteDirectoryy;
String localDirectory = localDirectoryy;
//new ftp client
FTPClient ftp = new FTPClient();
//try to connect
ftp.connect(serverAddress);
//login to server
if (!ftp.login(userId, password)) {
System.out.println("Login failed! Please check login and password.");
outmsg += "- Error: Login failed! Please check login and password.";
ftp.logout();
return false;
}
int reply = ftp.getReplyCode();
//FTPReply stores a set of constants for FTP reply codes.
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
System.out.println("Error: Connexion failed!");
outmsg += "- Error: Connexion failed!" + "\n";
return false;
}
//enter passive mode
ftp.enterLocalPassiveMode();
//get system name
System.out.println("Remote system is " + ftp.getSystemType() + "\n");
//change current directory
ftp.changeWorkingDirectory(remoteDirectory);
System.out.println("Current directory is " + ftp.printWorkingDirectory());
outmsg += "Remote system is " + ftp.getSystemType() + "\n";
outmsg += "- Output: Remote directory is \"" + ftp.printWorkingDirectory() + "\"\n";
outmsg += "- Output: Local directory is \"" + localDirectory + "\"\n";
//get list of filenames
FTPFile[] ftpFiles = ftp.listFiles();
outmsg += "--------------------------------------------------------------------------------------------------------------------------------\n";
if (ftpFiles != null && ftpFiles.length > 0) {
//loop through files
for (FTPFile file : ftpFiles) {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
if (!file.isFile() || !sdf.format(file.getTimestamp().getTime()).equals(chooseddate)) {
continue;
}
System.out.println("File is " + file.getName() + "\n" + sdf.format(file.getTimestamp().getTime()) + "=>" + sdf.format(new Date().getTime()));
//get output stream
OutputStream output;
output = new FileOutputStream(localDirectory + "/" + file.getName());
//get the file from the remote system
ftp.retrieveFile(file.getName(), output);
//close output stream
outmsg += "- Output: File name => \"" + file.getName() + "\" And Last modified date => \"" + sdf.format(file.getTimestamp().getTime()) + " \"\n";
output.close();
outmsg += "--------------------------------------------------------------------------------------------------------------------------------\n";
//delete the file
//ftp.deleteFile(file.getName());
}
}
ftp.logout();
ftp.disconnect();
exit();
} catch (Exception ex) {
return false;
}
return true;
}
public void startSFTP(String cchooseddate, String sserverAddresss, String uuserIdd, String ppasswordd, String rremoteDirectoryy, String llocalDirectoryy) throws JSchException, SftpException {
outmsg = " APPLICATION" + "\n" + "=====================" + "\n";
String remote_dir = rremoteDirectoryy;
String local_dir = llocalDirectoryy;
String[] files = {};
files = "*".split(",");
JSch jsch = new JSch();
Session session = jsch.getSession(uuserIdd, sserverAddresss);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(ppasswordd);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
sftpChannel.cd(remote_dir);
outmsg += "Connexion..." + "\n";
for (int i = 0; i < files.length; i++) {
String filename = files[i].trim();
Vector<ChannelSftp.LsEntry> list = sftpChannel.ls(filename);
Iterator<LsEntry> itr = list.iterator();
while (itr.hasNext()) {
ChannelSftp.LsEntry ls = (ChannelSftp.LsEntry) itr.next();
try {
filename = ls.getFilename();
SimpleDateFormat sdf2 = new SimpleDateFormat("dd/MM/yyyy");
String lastModif = sftpChannel.lstat(filename).getMtimeString();
DateFormat parser = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzzz yyyy");
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String lastModified = formatter.format(parser.parse(lastModif));
System.out.println(filename + " " + lastModified);
if (!filename.isEmpty() && lastModified.equals(cchooseddate)) {
sftpChannel.get(filename, local_dir + filename);
System.out.println("- " + "\"" + remote_dir + "/" + filename + "\" " + " copied."+ "\n");
outmsg += "- " + "\"" + remote_dir + filename + "\" " + " copied."+ "\n";
}
} catch (Exception e) {
System.out.println(remote_dir + filename + " not transfered!");
outmsg += "- " + remote_dir + filename + " not transfered!"+ "\n";
System.err.println("Caught IOException: " + e.getMessage());
}
}
}
sftpChannel.exit();
session.disconnect();
}
}
For long running tasks, you must execute them off the GUI thread, i.e. on a background thread. Otherwise it will tie up your GUI, as you are experiencing here.
Take a look at the SwingWorker class. See this answer on how to use it: