Как проверить JLabel в Swing при использовании FTPClient - PullRequest
1 голос
/ 15 марта 2012

Я хочу обновлять JLabel каждый раз с именем файла, который я загружаю с использованием FTPClient. Я пытался repaint(), validate(), revalidate(), first invalidate() and immediately validate()/revalidate(), но все равно ничего не работает.

Мой код выглядит следующим образом:

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

Ответы [ 2 ]

3 голосов
/ 15 марта 2012

Предложения:

  • Не используйте == для сравнения строк.Вместо этого используйте методы equals(...) или equalsIgnoreCase(...).Оператор == возвращает true, если два объекта String одинаковы, но это не имеет значения для вас, а вместо этого вы хотите проверить, содержат ли обе строки одинаковыесимволы в том же порядке, и это то, что проверяют два вышеописанных метода.
  • В настоящее время вы загружаете свои файлы в поток рассылки событий Swing или EDT, и это не только помешает обновлению JLabel, но итакже заставьте ваш графический интерфейс зависать, поскольку этот поток отвечает за отрисовку всей графики Swing, включая ее собственные компоненты, и за взаимодействие Swing с пользователем.
  • Вызов repaint(), revalidate(), invalidate() и т. Д. ... ничего не сделает для решения этой проблемы.
  • Чтобы решить эту проблему, выполните загрузку или любой длительный процесс вфоновый поток.Один из способов сделать это - создать новый поток, загрузить его с помощью Runnable и вызвать start, но есть лучший способ, разработанный специально для Swing GUI, который заключается в создании объекта SwingWorker и выполнении фонового кодирования в его * 1021.* метод. SwingWorker поможет вам понять, как это сделать, и если вы застряли в своей попытке, вернитесь с вашим кодом.
  • Вы, вероятно, не захотите упоминатьваша срочность, поскольку это часто имеет противоположный эффект.Пожалуйста, помните, что мы все являемся добровольцами, что ваша срочность действительно ваша срочность, а не наша, и что никто не любит испытывать поспешное или вынужденное что-то делать для кого-то другого, особенно добровольцев.

    Удачи и добро пожаловать в stackoverflow.

    Edit
    Поскольку вы видели пример использования простых потоков, я решил опубликовать пример того, какэто с объектом SwingWorker может выглядеть так:

      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: исправлено в соответствии с предложением Клеопатры

2 голосов
/ 15 марта 2012

@ 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();
};
...