Change JButton Color in a Thread

前端 未结 2 1879
深忆病人
深忆病人 2021-01-28 05:29

I am trying to make a game like simon: http://www.freegames.ws/games/kidsgames/simon/simon.htm#

I am making a smaller scale with only 2 buttons. I want the color to swit

相关标签:
2条回答
  • 2021-01-28 06:11

    A number of issues stand out (shazin has addressed one), the other that scares me is you are violating the single thread requirements of Swing. All changes to the UI must be made from within the context of the Event Dispatching Thread.

    Instead of using a Thread, you should be using a javax.swing.Timer. This will save you the need to have to resync your updates back to the EDT.

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class FlashyButtons {
    
        public static void main(String[] args) {
            new FlashyButtons();
        }
    
        public FlashyButtons() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private JButton btn1;
            private JButton btn2;
            private int count = 0;
    
            public TestPane() {
                setLayout(new GridBagLayout());
                btn1 = new FlashButton();
                btn2 = new FlashButton();
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                add(btn1, gbc);
                add(btn2, gbc);
    
                btn1.setBackground(Color.GREEN);
                btn2.setBackground(Color.BLUE);
    
                Timer timer = new Timer(500, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        count++;
                        if (count % 2 == 0) {
                            btn1.setBackground(Color.BLUE);
                            btn2.setBackground(Color.GREEN);
                        } else {
                            btn1.setBackground(Color.GREEN);
                            btn2.setBackground(Color.BLUE);
                        }
                    }
                });
                timer.start();
            }
    
        }
    
        public class FlashButton extends JButton {
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
        }
    
    }
    

    Take a look at Concurrency in Swing for more details

    0 讨论(0)
  • 2021-01-28 06:33
    if(switchColor = true){
        button1.setBackground(Color.blue);
        button2.setBackground(Color.green);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        refresh();
        switchColor = false;
    } else {
        button1.setBackground(Color.green);
        button2.setBackground(Color.blue);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        refresh();
    
        switchColor = true;
        }
    }
    

    In the above code change the following to

    if(switchColor = true){
    

    to

    if(switchColor == true){ 
    

    or just

    if(switchColor){
    

    And it is best to have your Runnable anonymous class inside

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
    
        }
    });
    

    than using a new Thread object to create and start the thread as it will be changing the Swing UI properties.

    0 讨论(0)
提交回复
热议问题