Flashing buttons with Thread

4

I have a problem trying to make the buttons blink.

Using Thread.sleep() , when clicking the button, Thread.sleep() ignores what comes before it, executes sleep and executes only what comes next, in this case setBackground(Color.GRAY) . I've already looked for solutions here, and either did not understand what they meant or did not work. I also tried with the class Timer , but I could not.

package exstackoverflow;

import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;

public class ExStackOverflow extends JFrame{

    JButton b = new JButton();
    JButton b2 = new JButton();
    JButton b3 = new JButton();
    JButton b4 = new JButton();
    int numBotao=0;

    public ExStackOverflow(){

         Container c = getContentPane();
        c.setLayout(new GridLayout(2,2));

        b.setBackground(Color.GRAY);
        b2.setBackground(Color.GRAY);
        b3.setBackground(Color.GRAY);
        b4.setBackground(Color.GRAY);

        b.addActionListener(new botaoListener());
        b2.addActionListener(new botaoListener());
        b3.addActionListener(new botaoListener());
        b4.addActionListener(new botaoListener());

        c.add(b);
        c.add(b2);
        c.add(b3);
        c.add(b4);
        numBotao = new Random().nextInt(4);

        piscar();

        setSize(300,300);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    class botaoListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent ae) {
             if(ae.getSource().equals(b)){
                 numBotao=1;
                 piscar();

             }else if(ae.getSource().equals(b2)){
                 numBotao=2;
                 piscar();

             }else if(ae.getSource().equals(b3)){
                 numBotao=3;
                 piscar();

             }else if(ae.getSource().equals(b4)){
                 numBotao=4;
                 piscar();
             }
        }
    }

     public void piscar(){
        try{
            switch(numBotao){//switch baseado nos valores inseridos na lista Sequencia
                case 1:
                    b.setBackground(Color.BLUE);
                    Thread.sleep(1500);
                    b.setBackground(Color.GRAY);
                    break;

                case 2:
                    b2.setBackground(Color.RED);
                    Thread.sleep(1500);
                    b2.setBackground(Color.GRAY);
                    break;
                case 3:
                    b3.setBackground(Color.YELLOW);
                    Thread.sleep(1500);
                    b3.setBackground(Color.GRAY);
                    break;
                case 4:
                    b4.setBackground(Color.GREEN);
                    Thread.sleep(1500);
                    b4.setBackground(Color.GRAY);
                    break;
            }
        }catch(Exception e){

        }
    }

    public static void main(String[] args) {
        new ExStackOverflow().piscar();

    }

}
    
asked by anonymous 28.03.2017 / 20:31

1 answer

4
  

Note: The swing interface must always be executed within Event   Dispatch Thread (or EDT) , for this you should always start a   window in main , as follows:

public static void main(String[] args) {

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
           new ExStackOverflow().piscar();
        }
    });
}
     

Or using lambda, in Java 8:

public static void main(String[] args) {

    EventQueue.invokeLater(() -> {
        new ExStackOverflow().piscar();
    });
}

When you run an interface in

29.03.2017 / 01:22