FTP 客户端方法正在执行时按钮保持按下状态

Button remains pressed while the FTP client method is under execution

我正在尝试创建一个支持协议 ftp 和 sftp 的 ftp 客户端。我有两种方法 startFTP() 用于 ftp 和 startSFTP() 用于 sftp。连接参数从配置文件加载。

当我单击执行两种方法之一的按钮时,所有 JButton、JCombobox 和菜单保持向下并且在执行 FTP 客户端方法时无法单击,我无法停止或退出程序。

这是我的代码:

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();

    }

}

对于长 运行 任务,您必须在 GUI 线程之外执行它们,即在后台线程上执行。否则它会占用您的 GUI,就像您在这里遇到的那样。

看看SwingWorker class。请参阅此答案以了解如何使用它:

How do I use SwingWorker in Java?