JADE, Swing e os problemas MultiThread

E ae pessoal!

Faz tempo que eu nao recorro a vcs! Nao porque eu tenha melhorado meu Javanês, mas eu nao programo nada ha meses! huehueahueahuea

Seguinte, tô fazendo uma sistema multi-agente com o JADE, e a principio, ele funciona bem.

Para quem nao conhece, JADE eh uma plataforma que, resumindo, gerencia cada agente numa thread separada e cuida das mensagens e tudo mais.

O problema eh que eu tenho que mostrar algo na tela para ver o que os agentes tao fazendo, entao, tenho que criar um jpanel com os bonequinhos andando pra la e pra ca.

Eu nao me lembro muito bem mas tive problemas similares com repaint() na mesma thread do swing, mas nao achei a soluçao que me ajudou da outra vez.

Bem, sem mais balela, la vai:

Eu tenho um agente ambiente que depois de se registrar (nas paginas amarelas do jade), ou seja, se tornar disponivel pros outros, ele cria o jpanel com os bufferedimages dentro.

Quando um agente se move, depois de responder “Ok, vc se moveu” pra ele, o ambiente pinta a antiga casa com empty.jpg e a nova com hunter.jpg.

MAAAAAAAS, as vezes, ficam imagens de ‘hunter.jpg’ perdidas no tabuleiro.

Eu SEI que é porque eu faço um IF na hora de pintar de empty.jpg, entao a thread do ambiente pode dar vez à thread do hunter antes que eu consiga terminar o IF. Mas ai fica aquela imagem sobrando no tabuleiro.

A minha pergunta eh:

Numa aplicaçao multi thread (mais de 1 thread), eu devo criar OUTRA para os graficos (swing) neh? E devo chamar o repaint() em alguma das outras threads criadas, nao na do Swing, neh?

Bem… Admitindo que eu tenho sérios problemas em OO, como diabos eu crio e acesso uma thread diferente para poder dar o repaint() corretamente?

La vao alguns codigos:
Atual método de delete e repaint():

} else {
					// OK: move accepted
					my_environement.mygrid[current_location.x][current_location.y].chasseur_AID = null;
					my_environement.mygrid[wished_location.x][wished_location.y].chasseur_AID = hunter_name;
					RichLocation newlocation =  my_environement.get_richlocation_from_position(wished_location.x,wished_location.y);
					my_environement.HunterMap.put(hunter_name, newlocation);
					// Inform the hunter agent
					ACLMessage reply = msg.createReply();
					reply.setPerformative( ACLMessage.REQUEST );
					ADMessages replyadmessage = new  ADMessages();
					replyadmessage.performatif = ACLMessage.CONFIRM;
					replyadmessage.comment = "Moving is OK";
					replyadmessage.richlocation= newlocation;
					if (newlocation.treasure) {
						//Cool, the treasure was found!
						replyadmessage.reward = 10000.;
					} else {
						replyadmessage.reward = -1.; // Try to get the agent to find the shortest path.
					}
					try {
						reply.setContentObject(replyadmessage);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

					
					//TODO: with the immortal mode, the ADPanel erase every single cell when the hunter
					//steps on it and DOESN'T DIE!
					//This needs a solution:
					
					//deletes the Hunter's image from current_location
					if (my_environement.mygrid[current_location.x][current_location.y].cell_code==AGWumpusEnvironnement.REGULAR_CELL){
						my_environement.cave_panel.add_empty_cell(current_location.x, current_location.y);
					}else if (my_environement.mygrid[current_location.x][current_location.y].cell_code==AGWumpusEnvironnement.HOLE_CELL){
						my_environement.cave_panel.add_hole(current_location.x, current_location.y);
					}else if (my_environement.mygrid[current_location.x][current_location.y].cell_code==AGWumpusEnvironnement.WUMPUS_CELL){
						my_environement.cave_panel.add_wumpus(current_location.x, current_location.y);
					}else if (my_environement.mygrid[current_location.x][current_location.y].cell_code==AGWumpusEnvironnement.TREASURE_CELL){
						my_environement.cave_panel.add_treasure(current_location.x, current_location.y);
					}
					//Draws the agent moving (next position)
					my_environement.cave_panel.add_hunter(wished_location.x, wished_location.y);


					myAgent.send(reply);
					if (my_environement.DEBUG_LEVEL > 3)  System.out.println( "== Environment: I told the agent that he could move to  (" +String.valueOf(wished_location.x)+","+String.valueOf(wished_location.y)+")");
				}
				break;
				// All other cases:
			default:
				//todo
				System.out.println( "== Environment: Did not handle message  "  +  msg.getContent() );
				break;
			}	[/code]

O Add_Empty_Cell e o ADPanel
[code]
		private JFrame frame;
		private Cell[][] cell;

		public ADPanel() {
			cell = new Cell[GRIDSIZE][GRIDSIZE];
			frame = new JFrame();
			frame.setSize(FRAMESIZE+8,FRAMESIZE+20);
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setContentPane(this);
			setLayout(new GridLayout(GRIDSIZE, GRIDSIZE));

			//initiates the grid with empty cells (constructor overrided)
			for (int i = 0; i < GRIDSIZE; i++) {
				for (int j = 0; j < GRIDSIZE; j++) {
					Cell c = new Cell();
					cell[i][j] = c;
					add(c);
				}
			}

			frame.setVisible(true); //pop out the grid!

		}

		public void add_empty_cell(int x, int y) {
			cell[x][y].cell_Empty();
			repaint();
		}

		public void add_hunter(int x, int y) {
			cell[x][y].draw_hunter();
			repaint();
		}
[/code]

E o draw_hunter e add_empty
[code]class Cell extends JComponent {

@Override
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			g.drawImage(_image, 0, 0, getWidth(), getHeight(), null);
		}

		public void cell_Empty() {
			try {
				_image = ImageIO.read(new File("Images/empty.jpg"));
			} catch (IOException e) {
			}
		}

		public void draw_hunter() {
			try {
				_image = ImageIO.read(new File("Images/hunter.jpg"));
			} catch (IOException e) {
			}
		}

Pra quem conhece JADE, o método Setup() parte os parametros dos agentes e no fim a gente da o Behaviour dele (no meu caso, CyclicBehaviour = thread com loop):

[code]protected void setup() {
if (DEBUG_LEVEL > 1) System.out.println("Environnement: Starting ");

	/** Let's do our own things here **/

	//Check if it's video_mode, and create the window
	if (VIDEO_GRID) {
		cave_panel = new ADPanel(); 
		//We need to create: the initial grid and positions (check if they are good!);
		initializeGrid(cave_panel);
	}else {
		//No video mode!
		initializeGrid_without_video(); 
	}

addBehaviour(new receivingEnvironmentBehaviour(this));
[/code]

E ae, apesar do post extenso, consegui me fazer entender?

(Espero pelo menos ter explicado o Jade direito :!: )

olha eu estou investigando um pouquinho do jade, e queria aproveitar a ocasião para te fazer uma pergunta

no jade da para fazer o programa se comportar de forma inteligente como se fosse inteligencia artificial???

Rapaz…

Primeira coisa, fazer o programa se comportar como “inteligência artificial” é meio complicado, porque acho que nao existe um comportamento chamado inteligência artificial.

Agora, se vc quis dizer “fazer o programa se comportar de maneira inteligente”, ai da sim! :wink:

Esse meu programa do Wumpus por exemplo, tem um caçador que roda umas 1000x no tabuleiro, decora as melhores açoes de cada casa e quando parte o jogo na moral, sempre faz o melhor caminho entre a casa de entrada (aleatoria) e o tesouro, desviando dos buracos e monstros.

Eu implementei o algoritmo chamad de Q-Learning, ou seja, tornei o meu agente caçador capaz de aprender.

Soh depende de vc e das suas escolhas de algoritmos.

O jade eh soh uma plataforma pra acessar seus agentes de forma segura, sem bugs (sem muitos bugs…)

EDIT:

Eu resolvi meu problema, melhorei o codigo pra nao repintar tudao toda hora e coloquei os repaints no lugar certo.
Agora ele roda lisinho