Ajuda com multi thread

20 respostas
nakrak

eu tenho duas classes Pane e Mov
a classe Mov implements Runnable e é chamada pela classe Pane
a classe Mov deve retornar dois valores para um metodo da classe Pane e é ai que estou tendo o problema e nao to sabendo como resolver

seguem as classes Mov e Pane

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package celulas;


import javax.swing.ImageIcon;
import javax.swing.JLabel;

/**
 *
 * @author billy
 */
public class Pane extends JLabel{


    //metodo que recebe valores da classe Mov
    static void setl(int x, int y) {
        setLocation(x,y);
    }
    
    public Pane(){
         ImageIcon icon = new ImageIcon("C:/Users/billy/Documents/NetBeansProjects/celulas/src/celulas/y.gif");
         setVisible(true);
         setBounds(0, 0, 31, 25);
         setIcon(icon);
         Runnable rMov = (Runnable) new Mov();
         Thread tMov = new Thread(rMov);
         tMov.start();

    }
}
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package celulas;

import java.awt.EventQueue;

/**
 *
 * @author billy
 */
public class Mov implements Runnable {
    
    int y;
    int x;

    public void run() {

         EventQueue.invokeLater(new Runnable() {
                         public void run() {

            x=10;
            y=10;
            for(;;){
            int i = 1+(int)(Math.random() * 8);

            System.out.println(""+i+"");

            if(i==1){
                if(y<=0){
                    y=y+100;
                }
                y--;
            }else if(i==2){
                if(y<=0){
                    y=y+100;
                }
                if(x>=769){
                    x=x-100;
                }
                x++;
                y--;
            }else if(i==3){
                if(x>=769){
                    x=x-100;
                }
                x++;
            }else if(i==4){
                if(y>=575){
                    y=y-100;
                }
                if(x>=769){
                    x=x-100;
                }
                x++;
                y++;
            }else if(i==5){
                if(y>=575){
                    y=y-100;
                }
                y++;
            }else if(i==6){
                if(y>=575){
                    y=y-100;
                }
                if(x<=0){
                    x=x+100;
                }
                x--;
                y++;
            }else if(i==7){
                if(x<=0){
                    x=x+100;
                }
                x--;

            }else if(i==8){
                if(y<=0){
                    y=y+100;
                }
                if(x<=0){
                    x=x+100;
                }
                 try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
            }
                x--;
                y--;
            }


            //envia dois numeros pra classe Pane
            Pane.setl(x, y);

        }
                             
                         }

                     });

    }

}

20 Respostas

mario.fts

cara, num consegui entender o que o código faz ainda, mas vai uma sugestão, troque esse monte de ifs por switch. melhor e muito a legibilidade do seu código.

int month = 8; switch (month) { case 1: System.out.println("January"); break; case 2: System.out.println("February"); break; case 3: System.out.println("March"); break; case 4: System.out.println("April"); break; case 5: System.out.println("May"); break; case 6: System.out.println("June"); break; case 7: System.out.println("July"); break; case 8: System.out.println("August"); break; case 9: System.out.println("September"); break; case 10: System.out.println("October"); break; case 11: System.out.println("November"); break; case 12: System.out.println("December"); break; default: System.out.println("Invalid month.");break; } }

O que vc quer fazer exatamente? qual o comportamentop q vc estava esperando? o que tem a ver com static?

nakrak

linha 96 da classe Mov deve enviar os valores para a linha 20 da classe Pane mas aparece o erro

“C:\Users\billy\Documents\NetBeansProjects\celulas\src\celulas\Pane.java:20: non-static method setLocation(int,int) cannot be referenced from a static context”
e eu nao sei como resolver

PS valeu pela dica com os ifs

M

Porquê o setl é estático?

Não parece lógico, e é isso que tá gerando o problema. Tente remover o modificaor static e veja se funciona.

nakrak

a classe Mov aparentemente so envia pra metodo static :?: :?: :?: :?: :?: :?: :?: :?:

aparece o mesmo erro so que na classe Mov

M

Vc precisa passar a referência para o objeto do tipo Pane que você está querendo alterar, e não o nome da classe.

Pane painel = new Pane();

...

painel.setl(x, y);
mario.fts

ta, faz assim:

no construtor da Mov, vc recebe o pane

Runnable rMov = (Runnable) new Mov(pane);
public class Mov implements Runnable {

	int y;
	int x;
	Pane pane;
	
	public Mov(Pane pane){
		this.pane = pane;
	}
...continua aqui

ai, no seu método lá embaixo, vc chama o set pro pane q vc recebeu no construtor:

// envia dois numeros pra classe Pane
					pane.setl(x, y);
e o método da classe pane, vc tira o static
//metodo que recebe valores da classe Mov  
     public void setl(int x, int y) {  
         setLocation(x,y);  
     }

acho que isso resolve. testa ae.

A

O seu problema está na hora de chamar o método setLocation(x,y)

ou o método setLocation deve ser static ou criar uma instancia de Pane antes de chamar o setLocation

Pane obj = new Pane();
obj.setLocation(x,y);

Um método static nunca chama um método não-static sem a criação do objeto antes.

Agora um método não-static pode chamar um método static sem problema nenhum.

nakrak

valew Marcos
so que Pane é um objeto que cria a thread (mov) que deve enviar x e y que seriam a posicao de uma figura na tela entendeu?

entao eu fiz Mov extender de Pane e utilizei setl(x, y); entao acontece o seguinte erro
“Exception in thread “main” java.lang.StackOverflowError”

nao sei se alguem entendeu o que quero com esse codigo mas é simples
a classe Pane é um objeto JLabel que se utiliza da classe Mov para gerar suas coordenadas x e y na tela

Tudo o que eu preciso é que o objeto Pane receba setLocation(x, y);

M

Mov estender Pane não é uma boa coisa… Tente aplicar o famoso teste… Mov “é um” Pane? Não, né…

O mario.fts explicou exatamente tudo o que você tem que fazer. :slight_smile:

mario.fts

tipo, vc ta criando um label que fica mudando de lugar na tela, é isso?

nakrak

Exato mario

To testando o que vc disse antes

nakrak

fiz o que o Mario.fts disse e recebi o seguinte erro

Pane pane;
Runnable rMov = (Runnable) new Mov(pane);

erro:
“Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException”

tentei assim tambem

Runnable rMov = (Runnable) new Mov(this);

erro:
tela congelada

Eu estou utilizando thread pra fazer a mudanca de local em vez de um loop normal é que eu quero criar varios objetos JLabel que ficam andando na tela

ViniGodoy

Não quero parecer rude, mas quer uma dica?

Antes de entrar em assuntos avançados como multi-threading, procure aprender bem o Java básico.
Não entender como static e não static funcionam é beeeem trivial. Fora que o seu código está bem desorganizado, a começar por esses ifs gigantescos e essas contas místicas.

Outra coisa, se você está numa aplicação multi-threaded, usar static é pedir para ter problemas.

mario.fts

pq ao invés de fazer todo esse malabarismo, vc num usa um timer?

tem um exemplo aqui, q o vini postou hoje mesmo em outro lugar, ele usava pra exibir a hora em uma janela, e atualizava o valor a cada segundo. vc pode usar o mesmo principio, mas alterando a pocição do label:

http://www.guj.com.br/posts/list/52964.java#279083

tem mais alguns exemplos nos posts mais pra frente. da uma estudada nisso, é melhor que ficar trabalhando com threads diretamente

[]'s

nakrak

tenho ciencia do que vcs dizem e ja tinha dado uma olhada no post da hora

vcs nao teriam um exemplo de uma thread multipla atualizando algum objeto?

Por favor? :oops: kkkk

Mas falando sobre o post do viny essa parte

// Iniciamos a thread do relógio. Tornei uma deamon thread para que seja
        // automaticamente finalizada caso a aplicação feche.
        Thread clockThread = new Thread(new ClockRunnable(), "Clock thread");
        clockThread.setDaemon(true);
        clockThread.start();

essa thread daemon pode ser criada varias vezes?

nakrak

esse post do viny http://www.guj.com.br/posts/list/52964.java#279083 funcionou e entendi como ele funciona mas eu preciso de mais de uma thread funcionando em paralelo

Alguem me ajuda?

ViniGodoy

A thread daemon pode ser criada várias vezes. Entretanto, você deve sincronizar o acesso ao objeto.

nakrak

Legal :smiley: :smiley: :smiley:
Mas como eu posso " sincronizar o acesso ao objeto"?
Pode me dar um exemplo utilizando o seu codigo?

mario.fts

da uma lida ai
http://www.guj.com.br/article.show.logic?id=43

nakrak

seguinte…

Finalmente consegui fazer da forma que eu queria

Agradeço a todos pela paciencia
Vlew mesmo Mario.fts Marcos Lima alexfmjr e o ViniGodoy

segue o fonte fungando

package celulas;

public class Main {

    public static void main(String[] args) {
        Tela tela=new Tela();
    }

}
package celulas;

import javax.swing.JFrame;
import javax.swing.JLabel;


public class Tela {
    JLabel label;

        public Tela(){
            JFrame frame=new JFrame();
            frame.setVisible(true);
            frame.setLayout(null);
            frame.setSize(900, 700);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            System.out.println("00000000000000000000000000");


            for(;;){
                Pane pane= new Pane();
            Thread th=new Thread();
            th.start();



            frame.add(new Pane());

            System.out.println("wwwwwwwwwwwwwwwwww");
             try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }
            }
            
            
        }
}
package celulas;


import java.awt.EventQueue;
import javax.swing.ImageIcon;
import javax.swing.JLabel;


public class Pane extends JLabel{
    int x=10;
    int y=10;
    public Pane(){
         ImageIcon icon = new ImageIcon("C:/Users/billy/Documents/NetBeansProjects/celulas/src/celulas/y.gif");
         setVisible(true);

         x = 1+(int)(Math.random() * 769);
         y = 1+(int)(Math.random() * 575);
         setBounds(x, y, 31, 25);
         setIcon(icon);

         Thread labelThread = new Thread(new LabelRunnable(), "cel thread");
         labelThread.setDaemon(true);
         labelThread.start();
    }

        private class LabelRunnable implements Runnable {
        public void run() {
            
                for(;;) {
                    EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        System.out.println("sdfsdfsdf");
                        int i = 1+(int)(Math.random() * 8);
                        System.out.println(""+i+"");
                        switch (i) {
                            case 1:  if(y<=0){
                                y=y+100;
                            }
                            y--;
                            break;
                            case 2:  if(y<=0){
                                y=y+100;
                            }
                            if(x>=769){
                                x=x-100;
                            }
                            x++;
                            y--;
                            break;
                            case 3:  if(x>=769){
                                x=x-100;
                                }
                            x++;
                            break;
                            case 4:  if(y>=575){
                                y=y-100;
                                }
                            if(x>=769){
                                x=x-100;
                            }
                            x++;
                            y++;
                            break;
                            case 5:  if(y>=575){
                                y=y-100;
                            }
                            y++;
                            break;
                            case 6:  if(y>=575){
                                y=y-100;
                            }
                            if(x<=0){
                                x=x+100;
                            }
                            x--;
                            y++;
                            break;
                            case 7:  if(x<=0){
                                x=x+100;
                            }
                            x--;
                            break;
                            case 8:  if(y<=0){
                                y=y+100;
                            }
                            if(x<=0){
                                x=x+100;
                            }
                            x--;
                            y--;
                            break;
                        }
                        setBounds(x, y, 31, 25);
           
                        }
                    });
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                    }
                }
            
            
        }
    }
}

:lol:

Criado 11 de fevereiro de 2010
Ultima resposta 11 de fev. de 2010
Respostas 20
Participantes 5