How can I make several threads draw several JLabel?

0

My teacher let me do a program where the user is asked for an entry data and according to that data generate "N" agents (threads) and that each agent appears randomly in a window. After they appear, the agents must move randomly either up, down, left or right. My problem is that at the time of calling the function mover only 1 agent (thread) is the one that moves; the other agents remain static. My agents are printing them in JLabel. Here is the code to see if anyone can help me solve that problem.

import java.util.Random;

import javax.swing.*;
public class Ventana extends JFrame implements Runnable{

   JLabel label1;


   public Ventana() {

      int cantidad=Integer.parseInt(JOptionPane.showInputDialog("Numero de agentes?: "));
      Thread hilo[]= new Thread[cantidad];
       for(int i=0;i<cantidad;i++) {
          hilo= new Thread(this);
          hilo.start();
       }
    }

   public void agregalabel(int x1,int y1) {

      setLayout(null);
        label1=new JLabel("(*)");
        label1.setBounds(x1,y1,x1,y1);
        add(label1);
   } 

   public void mover(int x1,int y1) {
      int dec;
      while(true) {
      dec = (int)(Math.random()*3)+1;

      switch(dec) {
      case 1:
          System.out.println(dec);
         while(x1<getWidth()-30){
         x1=x1+10;
         label1.setBounds(x1,y1,x1,y1);
           try {
              Thread.sleep(500);
           }catch(Exception e) {

           }
         }
              break;

      case 2:
         System.out.println(dec);
         while(x1>20){
            x1=x1-10;
            label1.setBounds(x1,y1,x1,y1);
            try {
                 Thread.sleep(500);
              }catch(Exception e) {

              }
            }
             break;
      case '3':
          System.out.println("3");
            while(y1<getHeight()-30){
            y1=y1+10;
            label1.setBounds(x1,y1,x1,y1);
              try {
                 Thread.sleep(500);
              }catch(Exception e) {

              }
            }
             break;
      case '4':
             break;

      }
      }
   }

    public static void main(String[] ar) {
        Ventana formulario1=new Ventana();
        formulario1.setBounds(0,0,1500,400);
       //formulario1.setExtendedState(JFrame.MAXIMIZED_BOTH);
       // formulario1.setSize(1300,600);
        formulario1.setResizable(true);
        formulario1.setVisible(true);
    }
    int x1,y1;
   @Override
   public void run() {

      try {
         x1= (int)(Math.random()*500)+300;
         y1= (int)(Math.random()*100)+301;

         agregalabel(x1,y1);
         mover(x1,y1);
         System.out.println("X: "+x1+"Y: "+y1);
         Thread.sleep(1000);
      }catch(Exception e) {

      }

      }
}
    
asked by Luis Daniel 28.03.2018 в 07:48
source

2 answers

1

The problem is that all the threads share the same object and, therefore, the same attribute JLabel label1; : All threads are moving the same JLabel , which is the last one added.

    
answered by 28.03.2018 в 10:15
1

As you say @ pablo-lozano, you are sharing the Label between threads. You also have some other fault:

  • Thread array : You are declaring an array of Thread but then you try to assign a thread without accessing the array index. This should not even compile you

    Thread hilo[] = new Thread[cantidad];
     for (int i = 0; i < cantidad; i++) {
      hilo = new Thread(this, "Hilo n: " + i);
      hilo.start();
      System.out.println(hilo[i].getName());
    }
    
  • Values x1, y1 : Like the JLabel you have declared them outside the run , so in the first thread no, but in the rest you will be assigned to all the same values (overlapping labels)

I'll give you a quick example of how you should do it (the JLabel is created in the run and passed as an argument to the methods that modify it)

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

import javax.swing.*;

/**
 *
 * @author fjlabiano
 */
public class Ventana extends JFrame implements Runnable {
public Ventana() {

    int cantidad = Integer.parseInt(JOptionPane.showInputDialog("Numero de agentes?: "));
    Thread hilo[] = new Thread[cantidad];
    for (int i = 0; i < cantidad; i++) {
        hilo[i] = new Thread(this, "Hilo n: " + i);
        hilo[i].start();
        System.out.println(hilo[i].getName());
    }
}

public void agregalabel(int x1, int y1, JLabel label1) {

    setLayout(null);
    label1.setBounds(x1, y1, x1, y1);
    add(label1);
}

public void mover(int x1, int y1, JLabel label1) {
    int dec;
    while (true) {
        dec = (int) (Math.random() * 3) + 1;
        System.out.println("X: " + x1 + "Y: " + y1);
        switch (dec) {
            case 1:
                while (x1 < getWidth() - 30) {
                    x1 = x1 + 100;
                    label1.setBounds(x1, y1, x1, y1);
                    try {
                        Thread.sleep(500);
                    } catch (Exception e) {
                    }
                }
                break;

            case 2:
                while (x1 > 20) {
                    x1 = x1 - 100;
                    label1.setBounds(x1, y1, x1, y1);
                    try {
                        Thread.sleep(500);
                    } catch (Exception e) {
                    }
                }
                break;
            case '3':
                while (y1 < getHeight() - 30) {
                    y1 = y1 + 100;
                    label1.setBounds(x1, y1, x1, y1);
                    try {
                        Thread.sleep(500);
                    } catch (Exception e) {
                    }
                }
                break;
            case '4':
                break;

        }
    }
}

public static void main(String[] ar) {
    Ventana formulario1 = new Ventana();
    formulario1.setBounds(0, 0, 1800, 800);
    //formulario1.setExtendedState(JFrame.MAXIMIZED_BOTH);
    // formulario1.setSize(1300,600);
    formulario1.setResizable(true);
    formulario1.setVisible(true);
}

@Override
public void run() {
    int x1, y1;
    try {
        x1 = (int) (Math.random() * 500) + 500;
        y1 = (int) (Math.random() * 100) + 301;
        JLabel label1 = new JLabel("(*)");
        agregalabel(x1, y1, label1);
        System.out.println("Label agregado");
        mover(x1, y1, label1);
        Thread.sleep(1000);
    } catch (Exception e) {
    }
}
}
    
answered by 28.03.2018 в 10:30