为了账号安全,请及时绑定邮箱和手机立即绑定

如何使我的SwingWorker示例正常工作?

/ 猿问

如何使我的SwingWorker示例正常工作?

UYOU 2019-11-19 15:18:48

我制作了自己的SwingWorker示例,以熟悉其工作原理。


我要执行的操作如下:单击按钮时,我希望进度条出现直到任务完成,我只想删除进度条并向对话框添加字符串。


单击该按钮时,进度条会出现,但永远不会消失。(千万不要在10秒后删除进度条,也不要将标签放在上方)


这是一个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;

    }



查看完整描述

3 回答

?
翻翻过去那场雪

这是您的代码的更新版本,可以使用


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

  }


}

关键是设置模型对话框可见块,直到对话框被处理为止。因此,validate在切换组件时,使其成为非模式固定+ 内容窗格上的调用。我还调整了您的主要方法以在EDT上运行,并添加了一些System.out调用。如果删除setModal( false )呼叫,您将看到在关闭对话框之前不会打印这些语句


查看完整回答
反对 回复 2019-11-19
?
幕布斯6054654

无需使对话框成为非模态对话框。启动SwingWorker之后,只需显示对话框即可。这可以通过调用类(执行SwingWorker的类)来完成,方法是先调用execute,然后显示对话框,也可以从SwingWorker完成,但是如果要从后者中进行,则必须自己制作调用super的execute的伪执行方法,然后显示对话框。请注意,您不能覆盖execute()本身,因为它是最终的。


例如...


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;

   }


}


查看完整回答
反对 回复 2019-11-19
?
一只萌萌小番薯

无需使对话框成为非模态对话框。启动SwingWorker之后,只需显示对话框即可。这可以通过调用类(执行SwingWorker的类)来完成,方法是先调用execute,然后显示对话框,也可以从SwingWorker完成,但是如果要从后者中进行,则必须自己制作调用super的execute的伪执行方法,然后显示对话框。请注意,execute()由于它是最终的,因此您无法覆盖自身。

查看完整回答
反对 回复 2019-11-19

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信