move jlabel object with thread

0

I have this code, the idea is that through the Runnable interface, a thread is created that calls a "move" method, the method moves a JLabel object. The program compiles everything but does not move the JLabel object. I have tried to make the JLabel object static, the method, to make them public, but nothing. Could you help me:)

Thread Class

 package pruebasgraficas;

 import static java.lang.Thread.sleep;


 public class Hilo implements Runnable
 {


         @Override
     public void run()
     {
                 do
         {
             try
             {
                 sleep (1000);
             }catch (InterruptedException e) 
                 {
                     ;
                 }
             PruebasGraficas pu = new PruebasGraficas();
             pu.mover();


         }while(true);
     }
 }

TestingGraphic class

 package pruebasgraficas;


 import java.awt.Color;
 import javax.swing.*;


 public class PruebasGraficas extends JFrame{

 private JLabel et1;

 private static Hilo h1;

     public PruebasGraficas()
     {
         super("mover");
         setLayout(null);

         et1 = new JLabel( );
         et1.setSize(30,30);
         et1.setLocation(10,10);
         et1.setOpaque(true);
         et1.setBackground(Color.BLACK);
         add(et1);

         h1 = new Hilo();

     }

     public static void main(String[] args) 
     {
         PruebasGraficas o = new PruebasGraficas();
         o.setSize(500,500);
         o.setVisible(true);

         h1.run();

     }

     public void mover()
     {
         et1.setLocation( et1.getX() + 5, et1.getY() );
     }

 }
    
asked by Abner 06.04.2017 в 22:59
source

2 answers

2

Most swing components are not thread-safe. You can only act on them in the Event Dispatch Thread to take effect. Consequently, if you use another thread and modify the graphic component, it will not do anything in that thread.

Another problem you have is that you are creating a new JFrame every 1 second.

I have modified your example to make it work, however I recommend you use a layout that is not null.

The Thread class

static class Hilo implements Runnable {
    final PruebasGraficas pu;


    public Hilo(PruebasGraficas pu) {
        this.pu = pu;
    }


    @Override
    public void run() {
        do {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //con esto te aseguras que se ejecute en el EDT
            SwingUtilities.invokeLater(() -> {
                this.pu.mover();
            });

        } while (true);
    }

}

And then your JFrame

class PruebasGraficas extends JFrame {

        private JLabel et1;

        private static Hilo h1;

        public PruebasGraficas() {
            super("mover");
            this.setLayout(null);

            this.et1 = new JLabel();
            this.et1.setSize(30, 30);
            this.et1.setLocation(10, 10);
            this.et1.setOpaque(true);
            this.et1.setBackground(Color.BLACK);
            this.add(this.et1);


        }



        public void mover() {
            this.et1.setLocation(this.et1.getX() + 5, this.et1.getY());
        }

    }

The main

 public static void main(String[] args) {
        PruebasGraficas o = new PruebasGraficas();
        o.setSize(500, 500);
        o.setVisible(true);
        // como mencionó luigi
        new Thread(new Hilo(o)).run();

    }

And then running,

However, the best way to do this is to use a SwingTimer which is specifically for these tasks, every time you execute an instruction in the EDT

    
answered by 07.04.2017 в 05:11
1

The problem is that you are not using threads in your code. What you use is a direct implementation of Runnable , therefore the code is executed sequentially. A thread is handled by the class Thread and its execution starts when calling the start method.

Your code should look like this:

public static void main(String[] args) {
    PruebasGraficas o = new PruebasGraficas();
    o.setSize(500,500);
    o.setVisible(true);
    //aquí se dispara el hilo
    new Thread(h1).start();
}

It should be noted that the thread code has a new instance of PruebasGraficas , which may not be the best way to solve the problem you are raising. Also, if you are going to use Swing for the graphical environment of your application, it would be better to start the threads using SwingWorker (which uses instances of Thread behind the scenes).

    
answered by 06.04.2017 в 23:41