2012-03-15 10 views
1

FTPClientを使用してダウンロードしているファイルの名前で毎回JLabelを更新したいとします。試しましたrepaint()validate()revalidate()first invalidate() and immediately validate()/revalidate()まだ何も動作していません。次のようにFTPClientの使用中にSwingでJLabelを検証する方法

マイコードが行く:

if(ae.getActionCommand()=="Download"){ 

    int[] row_indexes=table.getSelectedRows(); 

    notifylb.setText("Downloading files"); 
    this.validate(); 

    for(int i=0;i<row_indexes.length;i++) 
    { 
     String fn=table.getValueAt(row_indexes[i], 0).toString(); 

     notifylb.setText("Downloading: "+fn); // fn contains filename 
     this.validate(); 

     this.downloadFtpfile(fn); 

    } 

    notifylb.setText("SUCCESSFULLY DOWNLOADED FILE(s) !"); 
    this.validate(); 
} 
+1

[EDT](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html)でラベルを更新してください。また、[AWTとスイングの絵画](http://java.sun.com/products/jfc/tsc/articles/painting/index.html)も読んでください。 – tenorsax

+0

@マックス:私はEDTのラベルを更新することについてのあなたの提案に強く同意しますが、彼はすでにこれをやっていると思いますが、彼の問題は彼がEDTでも他のすべてをやっているということです。また、上の彼の問題は、AWTとSwingの絵画とはまったく関係がありません。これはEDTでも行われています。 –

+0

「AWTとスイングのペインティング」の意図は、repaint()、validate()、revalidate()などの組み合わせのゲームを推測するのを止めることです。 – tenorsax

答えて

2

@ Hovercraft-Full-Of-Eelsは非常に明確ですが、コードが必要な場合はここに記述してください。

final JButton finalButton = button; // this is your button will trigger download 
final JLabel finalLabel = finalLabel; 
final JTable finalTable = table; 


if(ae.getActionCommand().equals("Download")) 
{ 
    finalButton.setEnabled(false); //disable button, so user can not start it for twice until ftp finished. 
    Thread thread = new Thread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      int[] row_indexes = finalTable.getSelectedRows(); 

      SwingUtilities.invokeLater(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        finalLabel.setText("Downloading files"); 
       } 
      }); 

      for(int i = 0; i < row_indexes.length; i++) 
      { 
       final String fn = finalTable.getValueAt(row_indexes[i], 0).toString(); 

       SwingUtilities.invokeLater(new Runnable() 
       { 
        @Override 
        public void run() 
        { 
         finalLabel.setText("Downloading: " + fn); // fn contains filename 
        } 
       }); 

       this.downloadFtpfile(fn); 
      } 

      SwingUtilities.invokeLater(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        finalLabel.setText("SUCCESSFULLY DOWNLOADED FILE(s) !"); 
        finalButton.setEnabled(true); //enable the button 
       } 
      }); 
     } 
    }); 
    thread.start(); 
}; 
+0

ありがとう、トンchenyi1976。あなたのコードはあまりにもうまくいった!! –

+0

これはどんなものでも書かれているようです SwingUtilities.invokeLater(新しいRunnable()はバックグラウンドで実行されます..つまり小さな小さなスレッドのように.. –

+0

はい、スイングはスレッドセーフではありません。あなたはSwingUtilitiesを使用する必要があります.invokeLater()は、後でそれを更新することを意味します。詳細については、こちらを参照してください。http://java.sun.com/products/jfc/tsc/tsc/articles/threads/threads1.html – chenyi1976

3

提案:

  • は、文字列を比較するために==を使用しないでください。代わりにequals(...)またはequalsIgnoreCase(...)メソッドを使用します。 ==演算子は、2つの文字列オブジェクトが同じである場合はtrueを返しますが、これはあなたにとって重要ではなく、両方のStringが同じ文字を同じ順序で保持しているかどうかを確認する必要があります。上記の2つの方法がチェックされます。
  • 現在、SwingイベントディスパッチスレッドまたはEDTにファイルをダウンロードしています。これによりJLabelの更新が妨げられるだけでなく、このスレッドが独自のSwingグラフィックスを描画するためGUIがフリーズしますコンポーネントと、ユーザーとのスイングのやりとりに使用します。
  • repaint()revalidate()invalidate()などを呼び出すことは、これを解決するために何もしません。
  • これを解決するには、バックグラウンドスレッドでダウンロードや長期実行プロセスを実行します。これを行う1つの方法は、新しいスレッドを作成し、それにRunnableをロードし、startを呼び出すことです。SwingWorkerオブジェクトを作成し、そのdoInBackground()メソッドでバックグラウンドコーディングを行う方法があります。 。 SwingWorker tutorialsは、これを行う方法を理解する手助けをすることができます。あなたが試行錯誤している場合は、コードに戻ってください。
  • 緊急性については言及したくないかもしれませんが、これはしばしば反対の効果を意図しているためです。私たちはすべてボランティアであり、あなたの緊急性は本当に緊急性であり、他人、特にボランティアのために何かをやるように急いで感じたり、圧力を感じたりすることを好きではないことを忘れないでください。

最高の運と歓迎のstackoverflow。

if (ae.getActionCommand().equalsIgnoreCase("Download")) { 
    final int[] row_indexes = table.getSelectedRows(); 
    notifylb.setText("Downloading files"); 

    final List<String> fileNames = new ArrayList<String>(); 
    for (int i = 0; i < row_indexes.length; i++) { 
     fileNames.add(table.getValueAt(row_indexes[i], 0).toString()); 
    } 
    SwingWorker<String, String> downloadSwingWorker = new SwingWorker<String, String>(){ 
     @Override 
     protected String doInBackground() throws Exception { 
      for (String fileName : fileNames) { 
       publish("Downloading: " + fileName); 
       downloadFtpfile(fileName); 
      } 
      return "SUCCESSFULLY DOWNLOADED FILE(s) !"; 
     } 

     @Override 
     protected void process(List<String> chunks) { 
      for (String text : chunks) { 
       notifylb.setText(text); 
      } 
     } 

     @Override 
     protected void done() { 
      try { 
       String text = get(); 
       notifylb.setText(text); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 

    downloadSwingWorker.execute(); 
    } 

編集2:

編集あなたはプレーンなスレッドを使用しての例を見てきましたので
、私は次のようになりSwingWorkerのオブジェクトでこれを行うものの例を掲載したい考え出し:kleopatraの提案に基づいて修正されました

+0

お返事ありがとうございます。ファイルやすべてのもののダウンロードはうまくいきますが、問題は更新GUIだけです。私はSwingイベントのディスパッチスレッドとEDTについてあまり知らない。私はあなたのリンクでそれを試してみてください。 –

+0

@ KapilJituri:注意SwingWorkerの例 –

+1

注意:doInBackground内の同期されていないSwingコンポーネントのプロパティにはアクセスしないでください。安全側にいるためには、選択した細胞の_values_(それらの指標に対する)を事前に収集することがあります。 – kleopatra

関連する問題