Problema com Threads (SIMPLES) - Desespero..não funciona!

21 respostas
iwallas

olá pessoal!

Eu estou tentando fazer um slideshow com imagens contidas em uma pasta, mas está dando problema..quando inicio o método, trava toda a aplicação! só pelo taskmanager para fechar=/. Alguém pode me ajudar?

package lib;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import java.io.File;

public class SlideShow {
    private JLabel lblImg;
    
    public SlideShow(JLabel img) {
        this.lblImg = img;
    }
    
    public void play(){
        String dir = "C:\app\dist\imgs\";
        File diretorio = new File(dir);
        File imgs[] = diretorio.listFiles();
        
        Thread t = new Thread();
        t.start();
        
        int i = 0;
        double tempo = 0;

        while (true){

            try{
                t.sleep(3500);
                tempo += 3500;

                if(i>imgs.length-1){
                    i = 0;
                }

                this.lblImg.setIcon(new ImageIcon(dir+imgs[i].getName()));
                i++;

                if(tempo >15000)
                    return;
            }catch(Exception e) {}
       }
    }
}

Estou chamando assim dentro de um form com um jlabel:

SlideShow slide = new SlideShow(this.lblImgs);
slide.play();

21 Respostas

Luiz-SP

Mas meu, vc já sabe a solução, usa thread, qual a sua dúvida em relação as threads?

iwallas

eu nunca usei threads, dai pesquiseiaqui como fazia… e tentei implementar desse jeito, mas trava a aplicação toda! gostaria de saber pq trava =/

Guilherme_Gomes

Tira esse

Thread t = new Thread();
t.start();

do seu código e substitua

t.sleep(3500);

por

Thread.sleep(3500);

E veja o que acontece!

iwallas

no começo tinha feito isso! Mas não funciona. Só funciona se executar essaclasse sozinha, neste caso eu estou criando um objeto e executando a partir de um JFrame, trava tudo…

Guilherme_Gomes

Dentro do seu catch, manda imprimir a exception e fala pra gente qual é!

iwallas
while (true){

            try{
                Thread.sleep(3500);
                tempo += 3500;

                if(i>imgs.length-1){
                    i = 0;
                }

                this.lblImg.setIcon(new ImageIcon(dir+imgs[i].getName()));
                i++;

                if(tempo >15000)
                    return;
            }catch(Exception e) {
                System.out.println(e.getMessage());
            }
       }

Chamando o método (dentro de um actionPerformed de um botão de um JFrame):

try{
                    slide.play();
                }catch(Exception x){
                    System.out.println(x.getMessage());
                    x.printStackTrace();
                }

Saída(Após fechar via taskmanager):

init:
deps-jar:
compile-single:
run-single:
null
null
null
null
Java Result: 1
EXECUTADO COM SUCESSO (tempo total: 43 segundos)

Detalhe: Quando clico no botão ele permanece"clicado"… =/

Guilherme_Gomes

Entendi o que você está fazendo.

Eu não sou bom desenvolvedor de aplicações Desktop, mas pelo que estou vendo do seu projeto tem uma coisa que não está legal!

O botão fica clicado acho que é por que você chama o SlideShow e espera ele retornar, mas ele demora, o que gera o problema.

Tente fazer o botão iniciar uma thread e essa thread é o SlideShow, ou faça o SlideShow iniciar em outra janela (um novo JFrame) e nesse novo JFrame você faz o slide show. Assim a primeira janela pode ficar livre quanto a execução desse slides…

iwallas

puts… eh q esses slides tem que estarna mesma janela =/

ViniGodoy

O trecho de código que vai ser disparado para outra thread tem que estar dentro de um Runnable.
Esse Runnable é então passado para classe Thread, para só então vc dar o start.

Tente assim:

package lib;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import java.io.File;

public class SlideShow {
    private JLabel lblImg;

    public SlideShow(JLabel img) {
        this.lblImg = img;
    }

    public void play() {
        Thread t = new Thread(new SlideRun());
        t.start();
    }

    private class SlideRun implements Runnable {
        public void run() {
            String dir = "C:\app\dist\imgs\";
            File diretorio = new File(dir);
            File imgs[] = diretorio.listFiles();
            int i = 0;
            double tempo = 0;
            try {
            while (true) {
                    Thread.sleep(3500);
                    tempo += 3500;

                    if (i > imgs.length - 1) {
                        i = 0;
                    }

                    SlideShow.this.lblImg.setIcon(new ImageIcon(dir
                            + imgs[i].getName()));
                    i++;

                    if (tempo > 15000)
                        return;
                }
            }
            catch (InterruptedException e) {}
        }
    }
}
iwallas

vlew cara… mas nao funcionou mesmo assim, veja:

Exception in thread Thread-2 java.lang.NullPointerException

at lib.SlideShow$SlideRun.run(SlideShow.java:30)

at java.lang.Thread.run(Thread.java:619)
iwallas

need help =(

Marcio_Biza

Fala!

Agora o porblema foi outro. Me parece que o lblImg nã foi inicializado e se encontra nulo, então o lblImg.setIcon() joga um NullPointerException. Pelo menos é mais facil o problema ser aí.

Quanto a execução de tarefas swing em background, recomendo utilizar o SwingWorker. Dá uma olhada em http://java.sun.com/docs/books/tutorial/uiswing/concurrency/worker.html

[]'s

iwallas

poxa cara vlew… mas fiquei até triste… nada q tem lá eu consegui usar…tudo da erro…po sem esperanças…

iwallas

o jlabel está instanciado, mas como mostrei ali, eu passo ele como referencia para o construtor da classe slideshow, agora… será q eu nao posso mais acessar esse jlabel de dentro desta classe?

iwallas

Aaaaah!!! deixei um SYSTEM>OUT e ele imprimi o nome das imagens!!! a execução está OK, o problema agora é acessar o JLabel!!

Tow matutando aqui…ajuda será bem vinda rs

Marcio_Biza

Pode sim… continua dando o NullPointer?

iwallas

sim! continua! E PIOR, não consigo acessar nada! Tentei colocar ela como innerclass, mesmo assim não rola… tentei imprimir só o length do array de imgs…e nao rolou, segue:

public class Teste extends JFrame{

//codigos...declarações...

public void metodo(){
    Teste.SlideShow slide = new Teste().new SlideShow();
    slide.play();
}

class SlideShow {

        public void play() {
            Thread t = new Thread(new SlideRun());
            t.start();
        }

        class SlideRun implements Runnable {
            public void run() {
                
                int i = 0;
                double tempo = 0;
                try {
                    while (true) {
                        Thread.sleep(3500);
                        System.out.println(imgs.length);
                    }
                }catch (InterruptedException e) {}
            }
        }
    }
}

E continua com a mesma exception!

iwallas

Falta só isso… acessar o componente para trocar as imgs! mew…qdo isso funcionar vou deixar um tutorialzinho pra galera! certeza!!!

Marcio_Biza

Pera pera pera…
algo muito estranho!

Tem como colocar o codigo mais completo nao? Da criacao do SlideShow e a chamada… e coloca a exception tb!
[]'s

iwallas
public class caixa extends javax.swing.JFrame{

    Sessao sessao;
    Vendas venda;
    public File diretorio;
    public File imgs[];
    
    public File[] getImgs(){
        return this.imgs;
    }
    
    /** Creates new form caixa */
    public caixa() {
        initComponents();
      
        diretorio = new File("C:\evasVendas\dist\imgs\");
        imgs = diretorio.listFiles();
    }
    
    public void setKeys(){
                
        //Animar
        Action alF12 = new AbstractAction() {
          public void actionPerformed(ActionEvent actionEvent) {
                animar();
          }
        };
        
       
        JPanel content = (JPanel) this.getContentPane();
        KeyStroke f12 = KeyStroke.getKeyStroke("F12");

        InputMap inputMap = content.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

        inputMap.put(f12, "F12");
        content.getActionMap().put("F12", alF12);

    }

    public void animar(){
        caixa.SlideShow slide = new caixa().new SlideShow();
        slide.play();
    }

    class SlideShow {

        public void play() {
            Thread t = new Thread(new SlideRun());
            t.start();
        }

        class SlideRun implements Runnable {
            public void run() {
                
                int i = 0;
                double tempo = 0;
                try {
                    while (true) {
                        Thread.sleep(3500);
                        System.out.println(imgs.length);
                    }
                }catch (InterruptedException e) {}
            }
        }
    }
}

O código eh mto grande… mas em resumo é isso ae!

init:

deps-jar:

compile:

run:

Exception in thread Thread-2 java.lang.NullPointerException

at evasvendas.caixa$SlideShow$SlideRun.run(caixa.java:887)

at java.lang.Thread.run(Thread.java:619)

EXECUTADO COM SUCESSO (tempo total: 14 segundos)

LINHA 887: System.out.println(imgs.length);

iwallas

se eu colocar a declaração do array de imgs dentro da classe SlideRun e imprimir com getName() ele imprime o caminho de todas imagens da pasta… então eu acho que funcionando está, mas nao consigo acessar o array ou qualquer elemento que seja fora dessa classe =/

Criado 16 de novembro de 2007
Ultima resposta 17 de nov. de 2007
Respostas 21
Participantes 5