Java SwingWorker不从GUI更新对象的引用

时间:2014-04-20 02:41:05

标签: reference swingworker

所以我从数据库加载一些数据并使用SwingWorker。

public class LoadFromDatabase extends SwingWorker<ArrayList<Ucet>, GuiUpdate>{

    private ArrayList<Ucet> ucty;
    private JLabel lblStav;
    private File dbPath;
    private JProgressBar progress;
    private int pocetUctov;
    private JButton btnLoad;
    private JButton btnStart;

    public LoadFromDatabase(ArrayList<Ucet> ucty,JLabel lblStav,File dbpath,JProgressBar progress, JButton btnLoad,JButton btnStart){
        this.ucty=ucty;
        this.lblStav=lblStav;
        this.dbPath=dbpath;
        this.progress=progress;
        this.btnLoad=btnLoad;
        this.btnStart=btnStart;

    }

    @Override
    protected ArrayList<Ucet> doInBackground() throws Exception {
        String sqlLoadUcty="SELECT email,password FROM members";
        ArrayList<Ucet> ucty2=new ArrayList<>();
        try {
          Class.forName("org.sqlite.JDBC");
          Connection conn = DriverManager.getConnection("jdbc:sqlite:"+dbPath.getPath());
          Statement stmt = conn.createStatement();
          stmt.setQueryTimeout(30);
          ResultSet rs = stmt.executeQuery(sqlLoadUcty);
          GuiUpdate gd=new GuiUpdate(GuiUpdate.GuiType.setStartLoading);
          gd.setValue(0);
          publish(gd);
          pocetUctov=rs.getFetchSize();
          gd=new GuiUpdate(GuiUpdate.GuiType.setMaxValue); 
          gd.setValue(pocetUctov);
          publish(gd);
          int counter=0;
          while (rs.next()){
              Ucet uct=new Ucet(
                      rs.getString("email"),
                       rs.getString("password")
                      );
              gd=new GuiUpdate(GuiUpdate.GuiType.setValue);
              gd.setValue(counter);
              publish(gd);
              ucty2.add(uct);
          }

          rs.close();
          stmt.close();
          conn.close();

        } catch (ClassNotFoundException ex) {
            System.out.println("Problem= "+ex);

        } catch (SQLException ex) {
             System.out.println("Problem= "+ex);

        }


        return ucty2;
    }


    @Override
    public void process(List<GuiUpdate> update){
        for (GuiUpdate guiUpdate : update) {
            if (guiUpdate.getToDo()==GuiUpdate.GuiType.setStartLoading) {
                lblStav.setText("Loading ...");
                progress.setVisible(true);
            } else if (guiUpdate.getToDo()==GuiUpdate.GuiType.setMaxValue) {
                progress.setMaximum(guiUpdate.getValue());
                pocetUctov=guiUpdate.getValue();
                progress.setMinimum(0);
            } else if (guiUpdate.getToDo()==GuiUpdate.GuiType.setValue) {
                progress.setValue(guiUpdate.getValue());
            }
        }
    }

    @Override
    public void done(){
        progress.setVisible(false);

        btnLoad.setEnabled(true);
        try {
            ucty=get();
        } catch (InterruptedException ex) {
            System.out.println("Problem= "+ex);
        } catch (ExecutionException ex) {
           System.out.println("Problem= "+ex);
        }
        if (ucty!=null && ucty.size()>0) {
            btnStart.setEnabled(true);
            lblStav.setText("Loaded "+ucty.size()+" accounts.");
        }
    }


}

这是整个SwingWorker。我基本上从DB加载数据并更新进度条。 加载后,调用done()方法,其中doInbackground中创建的ArrayList的引用设置为arraylist,它来自mainGUI,允许和禁止某些按钮。

这就是我从Gui调用SwingWorker的方式:

private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        JFileChooser fileDb=new JFileChooser();
        int returnVal=fileDb.showOpenDialog(this);
        if (returnVal==JFileChooser.APPROVE_OPTION) {
            databasePath=fileDb.getSelectedFile();
            jButton4.setEnabled(false);
            execurtor.execute(new LoadFromDatabase(naciatneUcty, jLabel9, databasePath, jProgressBar1, jButton4,jButton1));
        }
    }   

这很好用,即使在SwingWorker中调试最后一行代码完成()我也可以清楚地看到ArrayList ucty从数据库中获取数据。

一旦回到主gui,ArrayList naciatneUcty仍为null。 但它不应该是因为我将它发送到SwingWorker,其引用应该更新...

问题出在哪里,为什么参考文献根本没有更新?

1 个答案:

答案 0 :(得分:0)

Java引用按值传递,因此当您执行ucty = get()时,swingworker中的引用会更改,但是不会更新naciatneUcty的引用。在运行swingworker之前,最好先实例化naciatneUcty,让doInBackground()返回void,废弃utcy2,然后在done()方法中使用utcy。