0

私は Java にまったく慣れていないので、以下の質問に答えていただければ幸いです。

FTP サーバーに接続するアプリケーションがあります。接続中に、サーバーから受信した各メッセージを jtextpane に表示したいと考えています。

私が遭遇している問題は、接続ボタンをクリックすると、アプリケーションがフリーズし、メッセージ全体が一度に表示されることです。swingutilies.invokelater を試しましたが、うまくいきません。以下のコードを参照してください。

btnConnect.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub

                try {

                    if(validation())
                    {

                        ftpServer = new FTPServer(txtusername.getText(), txtPassword.getText());
                        ftpServer.connectServer(txtSysMsg);

                    }



                } catch (BadLocationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }


            }
        });


import java.io.IOException;

import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

public class FTPServer
{
    String username;
    String password;
    FTPClient ftpClient;

    String error;
    String errorType;

    DisplayMessage displayMessage = new DisplayMessage();

    FTPTandem(String user, String pass)
    {

        username = user;
        password = pass;

    }


    public void connectServer(JTextPane txtSys) throws BadLocationException
    {

        ftpClient = new FTPClient();
        try
        {

            ftpClient.connect("xxx.xxx.xxx.xxx", 21);
            displayMessage.writeDoc(txtSys, "Connecting to xxx.xxx.xxx.xxx" +":"+ftpClient.getRemotePort()+")", "status");


            if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))
            {
                displayMessage.writeDoc(txtSys, "Connection established, waiting for welcome message...", "status");
                displayMessage.writeDoc(txtSys, ftpClient.getReplyString(), "response");
                displayMessage.writeDoc(txtSys, "USER "+username, "command");
                displayMessage.writeDoc(txtSys, "PASS "+password.replaceAll("[\\w\\W]", "*"), "command");

                if(ftpClient.login(username, password))
                {
                    displayMessage.writeDoc(txtSys, ftpClient.getReplyString(), "response");
                    displayMessage.writeDoc(txtSys, "SYST", "command");
                    displayMessage.writeDoc(txtSys,ftpClient.getSystemType(),"response");
                    displayMessage.writeDoc(txtSys,"PASV","command");
                    ftpClient.enterRemotePassiveMode();
                    displayMessage.writeDoc(txtSys,ftpClient.getReplyString(),"response");


                    ftpClient.logout();
                    ftpClient.disconnect();

                }
                else
                {
                    displayMessage.writeDoc(txtSys, ftpClient.getReplyString(), "error");
                    ftpClient.logout();
                    ftpClient.disconnect();

                }

            }
            else
            {
                ftpClient.disconnect();
                displayMessage.writeDoc(txtSys, "FTP server connection refused", "error");

            }



        } 
        catch (IOException e) 
        {
            if(ftpClient.isConnected())
            {
                try 
                {
                    ftpClient.logout();
                    ftpClient.disconnect();

                } 
                catch (IOException e1) 
                {

                }

            }

            displayMessage.writeDoc(txtSys, "Cannot connect", "error");

        }

    }




}

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;


public class DisplayMessage
{

    public SimpleAttributeSet styleDisplay(String type)
    {
        SimpleAttributeSet style = new SimpleAttributeSet();

        if (type.equalsIgnoreCase("error"))
        {
            StyleConstants.setForeground(style, Color.RED); 
            StyleConstants.setFontSize(style, 14);
            StyleConstants.setFontFamily(style, "Cambria");
            StyleConstants.setBold(style, false);

        }
        else if (type.equalsIgnoreCase("response"))
        {
            StyleConstants.setForeground(style, new Color(0,90,0) );
            StyleConstants.setFontSize(style, 14);
            StyleConstants.setFontFamily(style, "Cambria");
            StyleConstants.setBold(style, false);
        }
        else if (type.equalsIgnoreCase("status"))
        {
            StyleConstants.setForeground(style, Color.BLACK);   
            StyleConstants.setFontSize(style, 14);
            StyleConstants.setFontFamily(style, "Cambria");
            StyleConstants.setBold(style, false);
        }
        else if (type.equalsIgnoreCase("command"))
        {
            StyleConstants.setForeground(style, Color.blue);    
            StyleConstants.setFontSize(style, 14);
            StyleConstants.setFontFamily(style, "Cambria");
            StyleConstants.setBold(style, false);
        }

        return style;
    }

    public String messagePrefix(String meg, String type)
    {
        String reply = new String();

        if (type.equalsIgnoreCase("error"))
        {
            reply = "Error:\t"+meg+"\n";

        }
        else if (type.equalsIgnoreCase("response"))
        {
            reply = "Response:\t"+meg+"\n";
        }
        else if (type.equalsIgnoreCase("status"))
        {
            reply = "Status:\t"+meg+"\n";
        }
        else if (type.equalsIgnoreCase("command"))
        {
            reply = "Command:\t"+meg+"\n";
        }

        return reply;

    }

    public void writeDoc(JTextPane txtSys, String message, String type) throws BadLocationException
    {

            StyledDocument doc = txtSys.getStyledDocument();        
            doc.insertString(doc.getLength(), messagePrefix(message,type), styleDisplay(type));


    }

}
4

1 に答える 1

3

BackSlash のコメントは正しいです。コードが終了するまでUIを「フリーズ」させるため、GUIスレッドでコードを実行することは避けてください。あなたの場合、リモート サーバーへの接続は潜在的に時間のかかる操作です。そのため、UI がハングします。Swing スレッド モデル、イベント ディスパッチ スレッド (EDT)、および関連する概念について理解する必要があります。オラクル自身のドキュメンテーションから始めて、 Filthy Rich Clientsという書籍の最初の章をお勧めします。この書籍は、Swing に関するすべての入門章を含む、リッチ クライアント アプリケーションの優れた書籍です。

質問のために、 and を拡張SwingWorkerして実装する新しいクラスを作成します。UI をブロックしないように EDT の外部で実行され、タスクが完了すると done が呼び出されます。ドキュメントから:doInBackgrounddonedoInBackground

final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
    @Override
    public String doInBackground() {
        return findTheMeaningOfLife();
    }

    @Override
    protected void done() {
        try { 
            label.setText(get());
        } catch (Exception ignore) {
        }
    }
}

(new MeaningOfLifeFinder()).execute();

おそらくfindTheMeaningOfLife、潜在的に時間のかかる操作です。これは EDIT の外で実行され、実行が完了すると、 を実行してラベル テキストを結果で更新しますdone

于 2013-09-09T16:16:03.630 に答える