Eu nunca vi um exemplo de SwingWorker que eu conseguisse entender.
Tenho 3 sistemas grandes em Swing e o carregamento de grandes quantidades de dados ainda está sendo feito do tipo old fashion, gostaria de uma pequena luz de quem conhece bem esse SwingWorker porque tenho certeza que isso vai otimizar muito meu carregamento de dados (algumas vezes lista com 10 mil conhecimentos de transportes, ou 40 mil Orçamentos - bd Firebird).
Exemplo:
Quero carregar todos os clientes (beans) em uma lista (JComboBox), tenho um método no meu DAO que retorna um ArrayList, gostaria de fazer isso em background com SwingWorker.
Cheguei até aqui, e nada mais:
publicclassLoadClientesextendsSwingWorker<List<ClienteFormBean>,Void>{Connectionconn=Conexao.getConexaoSis();@OverrideprotectedList<ClienteFormBean>doInBackground(){ArrayList<ClienteFormBean>lista=newClienteDAO(conn).list(false);returnlista;//return domainManager.findAll();}@Overridepublicvoiddone(){// O que vai aqui?}}
Bem, não conheço o swingworker, mas acredito que usando threads você consegue chegar neste efeito desejado.
Neste micro não tem como fazer nenhum teste pra te servir de exemplo, então vai ter de dar uma procurada, mas a idéia é você criar a thread, fazer a consulta e colocar ou atualizar alguma lista, e sinalizar de volta pro programa que a consulta acabou, para a janela ser desenhada.
Flw
F
fabiofalci
Eu tenho um exemplinho simples e antigo, vc deve estar usando um swingWorker mais novo.
Mas nele tu pode executar um processo de três maneiras.
Usando swingWorker, usando uma thread e nao usando nada. Talvez tu vendo em execução
tu perceba a diferença! É meio grandinho o código pois inclui o swingWorker junto!
publicclassSwingThreadextendsJPanel{privateJButtonthreadButton;privateJButtonnonThreadbutton;privateJButtonswingWorkerButton;privateJProgressBarprogressBar;publicSwingThread(){this.add(this.getProgressBar());this.add(this.getSwingWorkerButton());this.add(this.getThreadButton());this.add(this.getNonThreadbutton());}publicJButtongetThreadButton(){if(this.threadButton==null){this.threadButton=newJButton("Thread Process");this.threadButton.setPreferredSize(newDimension(200,22));this.threadButton.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){executeThread();}});}returnthis.threadButton;}publicJButtongetNonThreadbutton(){if(this.nonThreadbutton==null){this.nonThreadbutton=newJButton("Process");this.nonThreadbutton.setPreferredSize(newDimension(200,22));this.nonThreadbutton.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){execute();}});}returnthis.nonThreadbutton;}publicJButtongetSwingWorkerButton(){if(this.swingWorkerButton==null){this.swingWorkerButton=newJButton("SwingWorker Process");this.swingWorkerButton.setPreferredSize(newDimension(200,22));this.swingWorkerButton.addActionListener(newActionListener(){publicvoidactionPerformed(ActionEvente){executeSwingWorker();}});}returnthis.swingWorkerButton;}publicJProgressBargetProgressBar(){if(this.progressBar==null){this.progressBar=newJProgressBar();this.progressBar.setPreferredSize(newDimension(300,22));}returnthis.progressBar;}publicvoidexecute(){newMyProcess().execute(this.progressBar);}publicvoidexecuteSwingWorker(){finalSwingWorkers=newSwingWorker(){publicObjectconstruct(){execute();returnnull;}};s.start();}publicvoidexecuteThread(){Runnabler=newRunnable(){publicvoidrun(){execute();}};newThread(r).start();}publicstaticvoidcreateAndShowGUI(){JFrameframe=newJFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setContentPane(newSwingThread());frame.pack();frame.setVisible(true);}publicstaticvoidmain(String[]args){SwingUtilities.invokeLater(newRunnable(){publicvoidrun(){createAndShowGUI();}});}}classMyProcess{publicvoidexecute(JProgressBarprogressBar){System.out.println("Process...");intvalue=0;while(value<=100){try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}progressBar.setValue(++value);System.out.print(".");if(value==20||value==50||value==80){JOptionPane.showMessageDialog(progressBar,"Valor está em "+value);}}System.out.println("\n...end");JOptionPane.showMessageDialog(progressBar,"Processo Finalizado...");}}abstractclassSwingWorker{privateObjectvalue;// see getValue(), setValue()privatestaticclassThreadVar{privateThreadthread;ThreadVar(Threadt){thread=t;}synchronizedThreadget(){returnthread;}synchronizedvoidclear(){thread=null;}}privateThreadVarthreadVar;protectedsynchronizedObjectgetValue(){returnvalue;}privatesynchronizedvoidsetValue(Objectx){value=x;}publicabstractObjectconstruct();publicvoidfinished(){}publicvoidinterrupt(){Threadt=threadVar.get();if(t!=null){t.interrupt();}threadVar.clear();}publicObjectget(){while(true){Threadt=threadVar.get();if(t==null){returngetValue();}try{t.join();}catch(InterruptedExceptione){Thread.currentThread().interrupt();// propagatereturnnull;}}}publicSwingWorker(){finalRunnabledoFinished=newRunnable(){publicvoidrun(){finished();}};RunnabledoConstruct=newRunnable(){publicvoidrun(){try{setValue(construct());}finally{threadVar.clear();}SwingUtilities.invokeLater(doFinished);}};Threadt=newThread(doConstruct);threadVar=newThreadVar(t);}publicvoidstart(){Threadt=threadVar.get();if(t!=null){t.start();}}}
J
javer
Muito obrigado amigo.
Pergunta: por que deve ter essa classe SwingWorker? No java 6 ja tem essa classe, certo?
J
javer
Agora eu consegui obter um resultado usando o SwingWorker do java 6, porém eu gostaria que a minha barra de progresso indicasse o andamento em percentual, mas não sei como fazer para isso acontecer, por enquanto estou mostrando a barra intermitente.
Essa consulta retorna uma lista com 220 mil itens.
SwingWorker<ArrayList<Orcamento>,Void>worker=newSwingWorker<ArrayList<Orcamento>,Void>(){@OverridepublicArrayList<Orcamento>doInBackground(){progressBar.setString("Carregando...");progressBar.setIndeterminate(true);ArrayList<Orcamento>lista=newcom.sikgraf.dao.OrcamentoDAO(c).lista();returnlista;}@Overridepublicvoiddone(){ArrayList<Orcamento>lista=null;try{lista=get();ArrayListComboBoxModelmodelOrcamentos=newArrayListComboBoxModel(lista);modelOrcamentos.insertElementAt("-- Relação de Orçamentos --",0);cbOrcamentos.setModel(modelOrcamentos);cbOrcamentos.repaint();cbOrcamentos.getModel().setSelectedItem(cbOrcamentos.getModel().getElementAt(0));}catch(InterruptedExceptionex){Logger.getLogger(OrcamentoUI.class.getName()).log(Level.SEVERE,null,ex);}catch(ExecutionExceptionex){Logger.getLogger(OrcamentoUI.class.getName()).log(Level.SEVERE,null,ex);}progressBar.setIndeterminate(false);progressBar.setString("Carregado(s) "+(lista==null?"0":lista.size())+" Orçamentos");}};worker.execute();
D
davidbuzatto
javer:
Muito obrigado amigo.
Pergunta: por que deve ter essa classe SwingWorker? No java 6 ja tem essa classe, certo?
Porque os componentes swing não são thread safe. Vc precisa delegar a atualização deles a outra thread caso o processo que for ser executado for muito demorado. Dê uma olhada na documentação, lá fala em várias partes que os componentes não são thread safe.
Quanto a sua dúvida do progresso, vc precisaria saber qual o tamanho final da sua consulta e saber qual o registro atual, aí é só vc usar regra de três para calcular o progresso atual.
J
javer
Porque quando eu tento executar 2 threads como a que mandei anteriormente eu recebo uma Exception como segue?
java.util.concurrent.ExecutionException: java.lang.NullPointerException
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
at java.util.concurrent.FutureTask.get(FutureTask.java:83)
at javax.swing.SwingWorker.get(SwingWorker.java:583)
at br.com.kooky.sikget.ui.ConhecimentoUI$16.done(ConhecimentoUI.java:1538)
D
davidbuzatto
Olha a excessão: java.util.concurrent.ExecutionException: java.lang.NullPointerException
Vc está tentando acessar algum membro não estático de uma referência nula.
Olha onde o erro está sendo gerado (linha 1538 da sua classe): at br.com.kooky.sikget.ui.ConhecimentoUI$16.done(ConhecimentoUI.java:1538)