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 :!: )