在线程中更改JButton颜色 [英] Change JButton Color in a Thread

查看:52
本文介绍了在线程中更改JButton颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作类似simon的游戏: http://www .freegames.ws/games/kidsgames/simon/simon.htm#

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

我只用2个按钮即可缩小规模.我希望颜色在2个按钮(button1和button2)之间切换.这是在线程中,因为在发生这种情况时我需要单击按钮.当我打开程序时,按钮颜色保持原样.

I am making a smaller scale with only 2 buttons. I want the color to switch between 2 buttons, button1 and button2. This is in a thread because I need buttons to be clicked while this is happening. When I open the program the button color stays as-is.

谢谢您的帮助!

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;

import javax.swing.*;

public class TestFrame extends JFrame{

    public JButton button1; 
    public JButton button2;

    boolean isTrue = true;
    boolean switchColor = true;

    TestFrame(){
        super("Simon");
        initialize();

        this.setSize(200, 400);
        this.setVisible(true);
    }

    private void initialize() {
         this.setLayout(new BorderLayout()); 

        button1 = new JButton();
        button1.setBackground(Color.green);
        button1.setSize(200,200);

        button2 = new JButton();
        button2.setSize(200, 200);
        button2.setBackground(Color.blue);

        this.add(button1, BorderLayout.NORTH);
        this.add(button2, BorderLayout.SOUTH);
        Thread t = new Thread(r1);
        t.start();

    }
    Runnable r1 = new Runnable() {
        public void run() {
            while(isTrue){
            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;
                }
            }

        }
    };

    public void refresh(){
        this.invalidate();
        this.validate();
        this.repaint();
    }

}

推荐答案

许多问题很突出(shazin解决了一个问题),另一个使我感到恐惧的问题是您违反了Swing的单线程要求.用户界面的所有更改都必须在事件调度线程的上下文内进行.

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.

您应该使用javax.swing.Timer,而不是使用Thread.这将使您不必将更新重新同步到EDT.

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);
        }

    }

}

有关更多详细信息,请参见 Swing中的并发

Take a look at Concurrency in Swing for more details

这篇关于在线程中更改JButton颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆