Как обновить JLabel, пока процесс, запускаемый щелчком в JButton, все еще обрабатывается?

#java #swing #user-interface #jframe #jbutton

#java #swing #пользовательский интерфейс #jframe #jbutton

Вопрос:

Я кодирую простую Java-программу. Для этого требуется три параметра. Папка, содержащая изображения, желаемая папка вывода и файл водяного знака изображения. Программы копируют изображение с водяными знаками каждого изображения из входной папки в выходную папку.

Я пишу простой графический интерфейс. Пользователь вводит три параметра и нажимает кнопку. Программа работает, но я хочу предоставить обратную связь пользователю. Я хочу иметь возможность обновлять поле JLabel каждый раз, когда обрабатывается изображение.

В моем классе WatermarkFolders я использую этот фрагмент кода, чтобы показать пользователю некоторую обратную связь:

 Gui.FEEDBACK.setText(text);
  

Проблема в том, что JLabel не обновляется при каждой обработке изображения. Он просто обновляется со 100% завершенным выводом, когда обработка завершена.
Есть ли простой способ обновить это синхронно. Спасибо за ответы.

 import javax.swing.*;

import java.awt.event.*;
import java.awt.*;
import java.util.*;


public class Gui extends JPanel {
    JButton button; 
    JFileChooser chooser;
    JLabel  inputLabel  = new JLabel("Directorio donde estan las imagenes");
    JTextField  inputField  = new JTextField(15);
    JLabel  outputLabel  = new JLabel("Directorio donde guardar las copias con marca de agua");
    JTextField  outputField  = new JTextField(15);
    JLabel  watermarkLabel  = new JLabel("Archivo marca de agua (gif transparente)");
    JTextField  watermarkField  = new JTextField(15);
public static JLabel FEEDBACK  = new JLabel("Número de Imágenes: ");
    JProgressBar pb;

    public Gui() {}

    public void go() {
        JFrame frame = new JFrame("Añadir Marcas de Agua a todas las imágenes de un directorio");
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        JButton button = new JButton("Añadir Marca de Agua a las imágenes");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                String input = inputField.getText();
                String output = outputField.getText();
                String watermark = watermarkField.getText();
                if(!input.equals("") amp;amp; !output.equals("") amp;amp; !watermark.equals("")) {
                    WatermarkFolders wm = new WatermarkFolders(input, output, watermark);
                    wm.run();       
                }   
            }
        });
        panel.add(inputLabel);
        panel.add(inputField);      
        panel.add(outputLabel);
        panel.add(outputField);
        panel.add(watermarkLabel);
        panel.add(watermarkField);      
        panel.add(button);
        panel.add(FEEDBACK);
        frame.getContentPane().add(BorderLayout.WEST,panel);
        frame.setVisible(true);
        frame.pack(); 
    }

    public static void main(String s[]) {
        Gui gui = new Gui();
        gui.go();
    }
}
  

Ответ №1:

Да, процессы, которые требуют времени, не должны выполняться в EDT. Вместо этого используйте класс SwingWorker для выполнения длительной задачи, одновременно внося обновления в графический интерфейс.

Вы можете использовать метод SwingUtilities.invokeLater() для обновления GUI из другого потока, или вы могли бы использовать таймер Swing для проверки состояния задачи и обновления GUI, пока она все еще выполняется.