【问题标题】:Swingworkers can't get GUI variablesSwingworkers 无法获取 GUI 变量
【发布时间】:2014-02-15 17:49:26
【问题描述】:

我有名为 Worker 的 SwingWorker;

public class Worker extends SwingWorker<Void, Void> {

               private MainProgramWindow mpw;
               public Worker(MainProgramWindow mpw) {
               this.mpw = mpw;
               }

                public String getStartDate (){
                String inputStringDate = mpw.startDateBox.getText();
                SimpleDateFormat inputFormat = new SimpleDateFormat("dd.MM.yyyy");
                Date inputDate = null;
                try {
                    inputDate = inputFormat.parse(inputStringDate);
                } catch (ParseException ex) {
                    Logger.getLogger(MainProgramWindow.class.getName()).log(Level.SEVERE, null, ex);
                }

                SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00.000");
                String outputStringDate = outputFormat.format(inputDate);
                return outputStringDate;
              }



              public String getEndDate (){
                 String inputStringDate = mpw.endDateBox.getText();
                 SimpleDateFormat inputFormat = new SimpleDateFormat("dd.MM.yyyy");
                 Date inputDate = null;
                 try {
                     inputDate = inputFormat.parse(inputStringDate);
                 } catch (ParseException ex) {
                     Logger.getLogger(MainProgramWindow.class.getName()).log(Level.SEVERE, null,  ex);
                 }

                 SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd 23:59:59.999");
                 String outputStringDate = outputFormat.format(inputDate);
                 return outputStringDate;
              }




                @Override
       protected Void doInBackground() throws Exception {
         //here you make heavy task this is running in another thread not in EDT
          int i = 50;
          setProgress(i);
               //Rest of code.

            ResultSet rs1;
            Statement stmt;
            String query1 = "select date,id,dur from exampletable\n" +
            "where adetdate between '"+getStartDate()+"' and '"+getEndDate()+"'";

           rs1 = stmt.executeQuery(query1);

           //Rest of Code

           while(i <= 100){
           setProgress(i++);
           Thread.sleep(5); // random magic number
           }

        return null;
        }

     }

Worker 成功运行并在定义的位置创建 excel 文件。

我的问题是;当我启动带有 StartDate Chooser - EndDate Chooser - StartJob 按钮的程序 GUI 时。当 Button 单击某个调用的进度条时,进度条执行此 Worker,进度条开始监听。

但是 Worker 总是使用第一个 GUI 出现的 startdate 和 enddate 值。我在 Worker 中定义了两个方法来获取实际的 startdate 和 enddate 值并在 String query1 中使用它们。

为什么 query1 成功调用但无法识别方法 getStartDate() 和 getEndDate() 我不明白。有什么想法吗?

编辑: 我也有进度条的 PbarNEW 类;

package AgentStatGenerator;

    //Imports here    

    public class PbarNEW extends JPanel {

      JProgressBar pbar;

      public PbarNEW() {
        // initialize Progress Bar
        pbar = new JProgressBar();
        // add to JPanel
        add(pbar);

      SwingWorker myWorker = new Worker();
      myWorker.addPropertyChangeListener(new PropertyChangeListener() {
      @Override
        public void propertyChange(final PropertyChangeEvent event) {
        switch (event.getPropertyName()) {
        case "progress":
        pbar.setIndeterminate(false);
        pbar.setValue((Integer) event.getNewValue());
        break;
        }
     }
    });
       myWorker.execute(); 
  }

      public static void main(String args[]) {

        final PbarNEW it = new PbarNEW();

        JFrame frame = new JFrame("Progress Bar Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(it);
        frame.pack();
        frame.setVisible(true);


      }
    }

当我在出现的 MainProgramWindow(主 GUI)progresbar 中单击按钮并开始侦听 Worker。但是 SwingWorker myWorker = new Worker();在 Worker 中创建构造函数后不起作用。

private void createExcelButonActionPerformed(java.awt.event.ActionEvent evt) {                                                 
   // TODO add your handling code here:
      String[] arguments = new String[] {"123"};
      PbarNEW.main(arguments); 
} 

【问题讨论】:

    标签: java progress-bar swingworker


    【解决方案1】:

    请编辑您的拼写和语法问题。正如所写的那样,它很难阅读,因此更难理解您的问题。

    至于您的问题,您是在事件发生时创建 SwingWorker 吗?例如,当按下按钮时?如果是这样,您应该通过其构造函数将感兴趣的相关值传递给 SwingWorker。我看不到您的 SwingWorker 甚至没有构造函数。给它一个并允许传入适当的参数,这些参数将用于设置对象的字段。


    编辑关于您发布的代码的更改:

    public class Worker extends SwingWorker<Void, Void> {
    
                MainProgramWindow MPW = new MainProgramWindow();
    

    射击,您正在 SwingWorker 内部创建一个全新的 GUI 程序 -- 不要这样做!。您创建的这个对象与正在显示的对象完全不同。而是按照我的建议传入构造函数参数。呵呵,可以把当前的GUI对象作为构造函数参数传入,但是不要在SwingWorker中新建一个。

    例如,

    public class Worker extends SwingWorker<Void, Void> {
    
        private MainProgramWindow mpw;
    
        public Worker(MainProgramWindow mpw) {
          this.mpw = mpw;
        }
    

    编辑 2
    对于我的意思的一个简单的例子:

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.*;
    
    public class MyGui extends JPanel{
       private JTextField textField = new JTextField("Start", 10);
       private JButton button = new JButton("Press Me");
    
       public MyGui() {
          textField.setEditable(false);
          textField.setFocusable(false);
    
          button.addActionListener(new ActionListener() {
    
             @Override
             public void actionPerformed(ActionEvent arg0) {
                MySwingWorker mySwingWorker = new MySwingWorker(MyGui.this); // pass in the GUI
                mySwingWorker.execute();
             }
          });
    
          add(textField);
          add(button);
       }
    
       public void setTextFieldText(String text) {
          textField.setText(text);
       }
    
    
       private static void createAndShowGui() {
          JFrame frame = new JFrame("MyGui");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(new MyGui());
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    
    class MySwingWorker extends SwingWorker<Void, Void> {
       private static final long SLEEP_TIME = 2 * 1000;
       private MyGui myGui;
    
    
       public MySwingWorker(MyGui myGui) {
          this.myGui = myGui; // use the  gui to set a field
       }
    
    
       @Override
       protected Void doInBackground() throws Exception {
          Thread.sleep(SLEEP_TIME);
          return null;
       }
    
       @Override
       protected void done() {
          myGui.setTextFieldText("Done!"); // call field's method
       }
    
    }
    

    【讨论】:

    • 对不起我的英语。我语法不好。我在上面编辑我的代码。
    • @Lacrymae:见编辑回答。你是在用你的代码打自己的脚。
    • 感谢您的示例。我现在试试它们并更新你。
    • SwingWorker myWorker = new Worker();在我的进度条类中这次不工作。我需要它,因为我首先在我的 GUI 按钮 actionlistener 中启动了这个进度条。
    • @Lacrymae:你上面的评论不清楚。请为我们澄清一下,以便我们了解您当前的问题(如果有)。
    【解决方案2】:

    您的工作人员将使用实例创建时的开始日期和结束日期。这是因为您的查询是在对象实例化时作为成员变量创建的。

    将查询构造移动到 doInBackground 中,就可以了。

    【讨论】:

    • 感谢您的建议。我编辑我的代码。添加一些实例并将查询块移动到 doinbackround 内。但还是出现了同样的问题。我选择 02.12.2014 和 02.12.2014,但查询使用 02.12.2014 和 02.15.2014 执行(程序启动时加载这些值)
    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 2022-11-23
    相关资源
    最近更新 更多