所以我从数据库加载一些数据并使用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,其引用应该更新...
问题出在哪里,为什么参考文献根本没有更新?
答案 0 :(得分:0)
Java引用按值传递,因此当您执行ucty = get()
时,swingworker中的引用会更改,但是不会更新naciatneUcty的引用。在运行swingworker之前,最好先实例化naciatneUcty,让doInBackground()返回void,废弃utcy2,然后在done()方法中使用utcy。