example ejemplo edt java swing jdialog swingworker

java - edt - ¿Cómo hago para que mi ejemplo SwingWorker funcione correctamente?



java swingworker example (2)

Aquí una versión actualizada de su código que funciona

import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JProgressBar; import javax.swing.SwingWorker; public class SwingTesting { public static void main(String[] args) { EventQueue.invokeLater( new Runnable() { @Override public void run() { JFrame frame = new JFrame(); JButton button = new JButton(); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { new GuiWorker().execute(); } }); button.setText("Test Me"); frame.getContentPane().add(button); frame.pack(); frame.setVisible(true); } } ); } } class GuiWorker extends SwingWorker<Integer, Integer> { /* * This should just create a frame that will hold a progress bar until the * work is done. Once done, it should remove the progress bar from the dialog * and add a label saying the task complete. */ private JFrame frame = new JFrame(); private JDialog dialog = new JDialog(frame, "Swingworker test", true); private JProgressBar progressBar = new JProgressBar(); public GuiWorker() { progressBar.setString("Waiting on time"); progressBar.setStringPainted(true); progressBar.setIndeterminate(true); dialog.getContentPane().add(progressBar); dialog.pack(); dialog.setModal( false ); dialog.setVisible(true); } @Override protected Integer doInBackground() throws Exception { System.out.println( "GuiWorker.doInBackground" ); Thread.sleep(1000); return 0; } @Override protected void done() { System.out.println("done"); JLabel label = new JLabel("Task Complete"); dialog.getContentPane().remove(progressBar); dialog.getContentPane().add(label); dialog.getContentPane().validate(); } }

El punto clave es que al establecer un diálogo de modelo los bloques visibles hasta que el diálogo esté dispuesto. Por lo tanto, al hacer que sea no modal, se corrigió + la llamada de validate en el panel de contenido cuando cambia los componentes. También ajusté su método principal para ejecutarlo en el EDT, y agregué algunas llamadas de System.out. Si elimina la setModal( false ) , verá que esas declaraciones no se imprimen hasta que cierre el cuadro de diálogo.

He hecho mi propio ejemplo de SwingWorker para familiarizarme con cómo funciona.

Lo que quiero hacer es lo siguiente: cuando se hace clic en el botón, quiero que aparezca una barra de progreso hasta que se complete la tarea. Simplemente quiero eliminar la barra de progreso y agregar una cadena al cuadro de diálogo.

Cuando se hace clic en el botón, la barra de progreso aparece pero nunca desaparece. (Nunca quita la barra de progreso después de 10 segundos y nunca coloca la etiqueta arriba)

Aquí hay un SSCCE:

package swingtesting; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JProgressBar; import javax.swing.SwingWorker; public class SwingTesting { /** * Creates a frame that will hold a simple button to make use of SwingWorker */ public static void main(String[] args) { // TODO code application logic here JFrame frame = new JFrame(); JButton button = new JButton(); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new GuiWorker().execute(); } }); button.setText("Test Me"); frame.getContentPane().add(button); frame.pack(); frame.setVisible(true); } } class GuiWorker extends SwingWorker<Integer, Integer> { /* * This should just create a frame that will hold a progress bar until the * work is done. Once done, it should remove the progress bar from the dialog * and add a label saying the task complete. */ private JFrame frame = new JFrame(); private JDialog dialog = new JDialog(frame, "Swingworker test", true); private JProgressBar progressBar = new JProgressBar(); public GuiWorker() { progressBar.setString("Waiting on time"); progressBar.setStringPainted(true); progressBar.setIndeterminate(true); dialog.getContentPane().add(progressBar); dialog.pack(); dialog.setVisible(true); } @Override protected Integer doInBackground() throws Exception { Thread.sleep(10000); return 0; } @Override protected void done() { JLabel label = new JLabel("Task Complete"); dialog.getContentPane().remove(progressBar); dialog.getContentPane().add(label); } }


No hay necesidad de hacer el diálogo no modal. Simplemente muestra el cuadro de diálogo después de iniciar SwingWorker. Esto se puede hacer desde la clase que llama, la que ejecuta SwingWorker, primero ejecutando la ejecución y luego mostrando el cuadro de diálogo, o puede hacerlo desde el SwingWorker, pero si desde este último, tendrá que hacer su propia Método de pseudo ejecución que llama a super''s execute, y luego muestra el diálogo. Tenga en cuenta que no puede anular a execute () ya que es definitivo.

Por ejemplo...

import java.awt.CardLayout; import java.awt.Window; import java.awt.Dialog.ModalityType; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.concurrent.ExecutionException; import javax.swing.*; @SuppressWarnings("serial") public class SwingTesting2 { private static void createAndShowGui() { final JFrame frame = new JFrame("SwingTesting2"); final JDialog dialog = new JDialog(frame, "Dialog", ModalityType.APPLICATION_MODAL); final DialogPanel dialogPanel = new DialogPanel(); dialog.getContentPane().add(dialogPanel.getMainPanel()); dialog.pack(); dialog.setLocationRelativeTo(frame); JButton button = new JButton(new AbstractAction("Test Me") { @Override public void actionPerformed(ActionEvent actEvt) { final GuiWorker2 guiWorker = new GuiWorker2(); guiWorker.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent pcEvt) { if (pcEvt.getPropertyName().equals("state")) { if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) { try { dialogPanel.done(guiWorker.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } else if (pcEvt.getPropertyName().equals("progress")) { dialogPanel.setProgress((Integer)pcEvt.getNewValue()); } } }); guiWorker.execute(); dialogPanel.start(); dialog.setVisible(true); } }); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(button); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } class GuiWorker2 extends SwingWorker<Integer, Integer> { private static final int MAX_COUNT = 20; private static final long SLEEP_TIME = 100; private int count = 0; @Override protected Integer doInBackground() throws Exception { while (count < MAX_COUNT) { Thread.sleep(SLEEP_TIME); count++; setProgress((100 * count) / MAX_COUNT); } return count; } } @SuppressWarnings("serial") class DialogPanel { public static final String PROGRESS_BAR = "Progress Bar"; public static final String DONE = "Done"; private static final int TIMER_DELAY = 2000; private CardLayout cardLayout = new CardLayout(); private JPanel mainPanel = new JPanel(cardLayout); private JLabel doneLabel = new JLabel("Done", JLabel.CENTER); private JProgressBar progressBar = new JProgressBar(); public DialogPanel() { progressBar.setString("Waiting on time"); progressBar.setStringPainted(true); progressBar.setIndeterminate(false); mainPanel.add(progressBar, PROGRESS_BAR); mainPanel.add(doneLabel, DONE); } public void setProgress(Integer newValue) { progressBar.setValue(newValue); } public void start() { cardLayout.show(mainPanel, PROGRESS_BAR); progressBar.setValue(0); } public void done(int countValue) { doneLabel.setText(DONE + ". Count: " + countValue); cardLayout.show(mainPanel, DONE); new Timer(TIMER_DELAY, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Window win = SwingUtilities.getWindowAncestor(mainPanel); win.dispose(); } }){{setRepeats(false);}}.start(); } public JPanel getMainPanel() { return mainPanel; } }