6 Multihilo¶
Introducción¶
Crear una aplicación Swing que soporte múltiples hilos (multithreading) implica manejar correctamente las actualizaciones de la interfaz de usuario para evitar problemas de concurrencia y asegurar una experiencia de usuario fluida. Swing no es seguro para el uso de hilos, lo que significa que todas las actualizaciones de la interfaz de usuario deben realizarse en el Event Dispatch Thread (EDT).
EL EDT es el hilo donde se deben ejecutar todas las actualizaciones de la interfaz de usuario. Manipular componentes de Swing desde cualquier otro hilo puede causar problemas impredecibles.
El SwingWorker
es una clase conveniente para realizar tareas en segundo plano sin bloquear el EDT. Permite ejecutar tareas en un hilo separado y actualizar la interfaz de usuario de forma segura.
SwingUtilities.invokeLater()
es un método útil para ejecutar código en el EDT.
Proyecto Multithreading¶
public class MultithreadingExample {
private JFrame frame;
private JButton startButton;
private JLabel statusLabel;
private JProgressBar progressBar;
public MultithreadingExample() {
// Crear el marco
frame = new JFrame("Multithreading in Swing");
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setLayout(new FlowLayout());
// Crear componentes
startButton = new JButton("Start Task");
statusLabel = new JLabel("Status: Waiting");
progressBar = new JProgressBar(0, 100);
// Agregar acción al botón
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
startBackgroundTask();
}
});
// Agregar componentes al marco
frame.add(startButton);
frame.add(statusLabel);
frame.add(progressBar);
}
private void startBackgroundTask() {
SwingWorker<Void, Integer> worker = new SwingWorker<>() {
@Override
protected Void doInBackground() throws Exception {
for (int i = 0; i <= 100; i++) {
Thread.sleep(50); // Simula una tarea pesada
publish(i); // Envía el progreso
}
return null;
}
@Override
protected void process(java.util.List<Integer> chunks) {
int progress = chunks.get(chunks.size() - 1);
progressBar.setValue(progress);
statusLabel.setText("Status: " + progress + "% completed");
}
@Override
protected void done() {
statusLabel.setText("Status: Task Completed!");
startButton.setEnabled(true);
}
};
startButton.setEnabled(false);
worker.execute();
}
public void show() {
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MultithreadingExample example = new MultithreadingExample();
example.show();
});
}
}