[Resolvido] ProgressBar enquanto atualiza BD

Pessoal,
Estou com o seguinte problema:
Tenho uma tela, no estilo splash, que gostaria que aparecesse para o usuário toda vez que alguma ação demorada executar, como por exemplo, uma consulta no banco (considere um banco na web, acessado pela maquina do cliente que possui link de 1 MB - isso chega a levar de 2 a 7 segundos pra completar cada ação- :frowning: )
A splashScreen funciona perfeitamente sozinha, porém quando chamo ela dentro de outro frame, a tela aparece, junto com a label que criei, mas a barra não, e quando a execução da minha operação no banco termina é que a barra aparece e começa e se mover (estou usando setIndeterminate(true))

Tentei de outras formas também, como criar uma progressBar diretamente no meu form, mas ocorre o mesmo, ela só inicia a execução depois que a consulta no banco já terminou, o que não adianta muito, rs.

Abaixo o código da splash screen, lembrando que ela funciona perfeitamente se for chamada sozinha:



public class waitScreen extends JWindow {


    public waitScreen() {
        JPanel content = (JPanel) getContentPane();
        content.setBackground(Color.white);

        final JProgressBar barra = new JProgressBar();
        int width = 350;
        int height = 150;
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (screen.width - width) / 2;
        int y = (screen.height - height) / 2;
        setBounds(x, y, width, height);


        Label label = new Label("Aguarde!!");
        content.add(label, BorderLayout.SOUTH);
        content.add(barra, BorderLayout.CENTER);
        Color verm = new Color(156, 20, 20, 255);
        content.setBorder(BorderFactory.createLineBorder(verm, 1));
        setVisible(true);
        
        SwingUtilities.invokeLater(new Runnable(){
   
            public void run() {

                barra.setIndeterminate(true);

            }
        });
        


    }


    public static void main(String[] args) {
        new waitScreen();
    }
}

A chamada da minha tela estou realizando antes de chamar o método que conecta no banco, como no exemplo abaixo:

new waitScreen();
meuMetodoDemorado();

Note que ainda não estou preocupado com o fechamento da tela, apenas quero fazer ela aparecer na tela enquanto meu método executa.

Como comentei, tentei criar a progressBar diretamente no meu form, e criei uma Thread para dispertá-la, mas ocorre o mesmo, ela só inicia quando a execução do meu método termina.

Tentei criando actionListener, Thread (propriamente dita) e invokeLater mas nada mudou.

Se alguém tiver alguma luz, ou souber de alguma forma mais fácil de deixar essa barrinha visível enquanto algo executa eu ficarei grato.

Abraços

Recentemente precisei gerar uma barra de progresso para a geração de alguns arquivos de exportação.
Esta barra está no meu painel mesmo, só que ao disparar a ação de exportação é realizada uma busca no bd e esta busca lança um “painel sobreposto” onde o usuário fica impossibilitado de realizar qualquer ação.

Para atualizar esta progress bar também penei e só consegui usando uma thread dentro da outra.
Por motivos empresariais, não posso postar o código, mas é mais ou menos assim:

[code]
void acaoGerar(parametros){

    jpbarArquivos.setValue(0);
    
    for (int barra = 0; barra < dias; barra++) {
        // dispara a thred da busca
        // no retorno, chama o metodo retornoGerar();
    }

}

void retornoGerar(parametros){

    new Thread(new Runnable() {

        @Override
        public void run() {
            geraArquivoFisico(parametros);
        }
    }).start();

}

void geraArquivoFisico(parametros) {
// instrucoes para gerar o arquivo
// gera o arquivo, bla bla bla

    EventQueue.invokeLater(new Runnable() {
        
        @Override
        public void run() {
            // calcula o pct
            jpbarArquivos.setValue((int) perc);
            
        }
    });

}[/code]

Espero que isso te ajude de alguma forma.

Outra forma que você pode tentar, obviamente adaptando a sua estrutura de código.

public class TestePBar extends JFrame{

	private JButton btnNewButton;
	private JProgressBar progressBar;
	
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				try {
					TestePBar frame = new TestePBar();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	
	public TestePBar() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		btnNewButton = new JButton("Executar");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				new Tarefa().execute();
			}
		});
		getContentPane().setLayout(new GridLayout(0, 1, 0, 0));
		getContentPane().add(btnNewButton);
		
		JScrollPane scrollPane = new JScrollPane();
		getContentPane().add(scrollPane);
		
		progressBar = new JProgressBar(0);
		progressBar.setStringPainted(true);
		scrollPane.setViewportView(progressBar);
	}


	
	
	class Tarefa extends SwingWorker<String, Integer>{

		public Tarefa() {
			btnNewButton.setEnabled(false);
		}
		
		@Override
		protected String doInBackground() throws Exception {
			
			for (int i = 0; i < 100; i++) {
				Thread.sleep(300);
				publish(i);
			}
			return "Processado.";
		}
		
		@Override
		protected void process(List<Integer> chunks) {
			progressBar.setValue((int) chunks.get(0).intValue());
		}
		
		@Override
		protected void done() {
			
			btnNewButton.setEnabled(true);
		}
		
	}
}

Caro jhaga,
Somente o fato de você ter dito que criou uma Thread dentro de outra Thread já me deu a luz que precisava :slight_smile:
Pra revolver meu problema foi relativamente simples, eu modifiquei meu método do banco para Thread, conforme abaixo:


    public void deletaItemPedido(final int item, int seq){
    final String query = "DELETE from PedidoItens WHERE codPed = " + item + " AND seqItem = " + seq;
    final BD  conn = new BD();
    new Thread(){   
    @Override
    public void run(){
    try {
    Statement stm = conn.criaConexao().createStatement();
    stm.execute(query);
    updateTable(item);
    }
    catch(SQLException ex){
    JOptionPane.showMessageDialog(null, "Erro ao remover!!");
    }
    }}.start();
    }

Agora tanto a telinha com a barra quanto a barra no meu form funcionaram exatamente do jeito que estavam, a única mudança mesmo foi colocar minha operação de banco como Thread, espero que isso não me gere nenhum outro problema, mas de qualquer forma a princípio funcionou :).

Abaixo a chamada da telinha no meu botão (Remover)

    private void jButtonRemoverItemActionPerformed(java.awt.event.ActionEvent evt) {                                                   

        if (jTableVenda.getSelectedRowCount()==0){
            JOptionPane.showMessageDialog(this, "Selecione uma linha para deletar!!");
        
        }
        
        if(jTableVenda.getSelectedRowCount()>0){
        int opt = JOptionPane.showConfirmDialog(this, "Deseja realmente deletar este item?", "Atenção!!!",JOptionPane.YES_NO_OPTION);
        
        if (opt == JOptionPane.YES_OPTION){   
        String seqValor = (String)jTableVenda.getValueAt(jTableVenda.getSelectedRow(),0);
        int seq = Integer.valueOf(seqValor);
        wait.setVisible(true);
        deletaItemPedido(Integer.valueOf(jTextFieldPed.getText()), seq);
       
        }
        
        if (opt==JOptionPane.NO_OPTION){}
        
        
        }

Da forma acima está chamando a telinha normalmente.

Muito obrigado pela ajuda, grande abraço!