如何从Java Swing中的派生类更改JButton的背景颜色 [英] How to change Background color of a JButton from a derived class in Java Swing

查看:102
本文介绍了如何从Java Swing中的派生类更改JButton的背景颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基类的大型机,我将JButton保持为最终静态状态,它的BGcolor将由大型机的扩展类即数据帧更改.最初,我需要将JButton的BGColor设置为红色.然后,我需要将其从数据框中更改为其他颜色.我可以从大型机设置BGColor,但不能从数据框(扩展类)设置BGColor.我用过mainframe.Button_name.setBackground(color.yellow);但仍然没有改变

I have a base class mainframe and i have keeping the JButton as final static Which its BGcolor going to be changed by a extended class of mainframe namely dataframe. Initially i need to set the BGColor of the JButton to red. Then I need to change it to some other colors from the dataframe. I can able to set the BGColor from the mainframe but not from the dataframe(extended class). I've used mainframe.Button_name.setBackground(color.yellow); but still its not changing

`enter code here`

 public class mainframe {

 final static JButton Button_name = new JButton("Hi");

 public static void main(String[] args)
 {
 public void run()
  {
         Button_name.setBackground(color.Red);        //This is working  
  }
 }
}

 class dataframe extends mainframe implements Runnable
{
public void run()
{
   //doing other things
  while(some condition)
  {

     if (another_condition)
     {
        //from here i need to change that Buttons color
       // i've tried this
       mainframe.Button_name.setBackground(color.yellow);  //Not working
     }

    } 
  }
}

在此问题上任何人都可以帮助

Kindly anyone help with this issue

推荐答案

因此,您想从其他类中的其他线程更改UI组件的状态.您可能有多种方法可以执行此操作,但是首先,我将首先定义这些类,使其仅能够影响您希望它们进行的更改.

So you want to change the state of a UI component from a different thread in a different class. There are multiple ways you might be able to do this, but first, I would start by defining away for those classes to be able to only effect the change you want them to.

暴露整个框架,组件甚至按钮不是一个好主意,人们习惯于更改您不希望他们做的事情,因此,我们定义了一个简单的合同,阐明允许他们做的事情,例如...

Exposing the entire frame, component or even button is not a good idea, people have a habit of changing things you don't want them to, so instead, we define a simple contract which states what they are allowed to do, for example...

public interface Colorable {

    public void setColor(Color color);

}

这立即使您的代码脱钩,这意味着任何想要更改UI状态(或更改其他颜色)的代码都可以这样做,而无需依赖物理实现.

This immediately decouples your code, meaning that any code that wants to change the state of your UI (or change the color of something else) can do so, without relying on the physical implementation.

首先,我们将使用Thread来更改UI ...

First, we're going to have a look at using a Thread to change the UI...

public class ColorChanger {

    private Colorable colorable;

    public ColorChanger(Colorable colorable) {
        this.colorable = colorable;
    }

    public void start() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int index = 0; index < 1000; index++) {
                    if (index % 100 == 0) {
                        if ((index / 100) % 2 == 0) {
                            colorable.setColor(Color.GREEN);
                        } else {
                            colorable.setColor(Color.RED);
                        }
                    }
                    try {
                        // This is so you can see the colors changing
                        Thread.sleep(5);
                    } catch (InterruptedException ex) {
                    }
                }
                System.out.println("Done");
            }
        });
        t.start();
    }

}

这是一个非常基本的类,它需要一个Colorable实例,并将根据它是偶数还是奇数百次来更改每个100计数的颜色状态

This is a pretty basic class, it requires an instance of Colorable and will change the state of the color for every 100 counts, based on if it's an even or odd hundred

我们使用一个简单的JPanel作为我们的基础测试类,当您单击按钮时,会创建并启动ColorChanger.

We use a simple JPanel as our base test class, when you click the button, the ColorChanger is created and started.

public class TestPane extends JPanel implements Colorable {

    private JButton btn;
    private ColorChanger changer;

    public TestPane() {
        setLayout(new GridBagLayout());
        setBorder(new EmptyBorder(20, 20, 20, 20));
        btn = new JButton("I am your button");
        add(btn);
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (changer == null) {
                    changer = new ColorChanger(TestPane.this);
                    changer.start();
                }
            }
        });
    }

    @Override
    public void setColor(Color color) {
        if (EventQueue.isDispatchThread()) {
            btn.setBackground(color);
        } else {
            System.out.println("Not in the EDT");
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    setColor(color);
                }
            });
        }
    }

}

您会注意到,setColor方法中包含大量代码,这是为了确保对UI的更新仅在事件调度线程的上下文内执行.

You will note that the setColor method has a bunch of code in it, this is to ensure that the updates to the UI are executed only from within the context of the Event Dispatching Thread.

另一种选择是使用SwingWorker,它的功能与Thread非常相似,希望它具有将publish内容传送到EDT的功能

An alternative is to use a SwingWorker, which operates very similarly to a Thread, expect it has the ability to publish content to the EDT

public class ColorChangerWorker extends SwingWorker<Void, Color> {

    private Colorable colorable;

    public ColorChangerWorker(Colorable colorable) {
        this.colorable = colorable;
    }

    @Override
    protected void process(List<Color> chunks) {
        colorable.setColor(chunks.get(chunks.size() - 1));
    }

    @Override
    protected Void doInBackground() throws Exception {
        for (int index = 0; index < 1000; index++) {
            if (index % 100 == 0) {
                if ((index / 100) % 2 == 0) {
                    publish(Color.GREEN);
                } else {
                    publish(Color.RED);
                }
            }
            try {
                // This is so you can see the colors changing
                Thread.sleep(5);
            } catch (InterruptedException ex) {
            }
        }
        System.out.println("Done");
        return null;
    }

}

您将在此处注意到,当我们想要更改颜色时,我们将其称为publish.调用process方法是为了让我们知道还有更多数据要处理,但是在这里,我们只对最后的更改感兴趣.

You will note here, that when we want to change the color we call publish. The process method is called to let us know that there is more data to be processed, but here, we're only interested in the last change.

然后TestPane ...

public class TestPane extends JPanel implements Colorable {

    private JButton btn;
    private ColorChangerWorker changer;

    public TestPane() {
        setLayout(new GridBagLayout());
        setBorder(new EmptyBorder(20, 20, 20, 20));
        btn = new JButton("I am your button");
        add(btn);
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (changer == null) {
                    changer = new ColorChangerWorker(TestPane.this);
                    changer.execute();
                }
            }
        });
    }

    @Override
    public void setColor(Color color) {
        if (EventQueue.isDispatchThread()) {
            btn.setBackground(color);
        } else {
            System.out.println("Not in the EDT");
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    setColor(color);
                }
            });
        }
    }

}

您会注意到setColor方法保持不变,这是有意的,当您测试此类时,您会注意到"Not in the EDT"从未打印过,基本上意味着我们可以删除所有代码,而只需调用btn.setBackground(color);,但我希望您能看到其中的区别.

You will note that the setColor method remains unchanged, this is deliberate, when you test this class, you will note that "Not in the EDT" is never printed, basically meaning we could do away with all that code and just call btn.setBackground(color);, but I want you to see the difference.

现在,当我运行此代码时,我得到以下输出...

Now, when I run this code, I get the following output...

请稍等,按钮背景已填满?!实际上是这样,但是许多按钮实现具有辅助的内容区域".填充

Wait a minute, that buttons background is filled?! Actually it is, but many button implementations have a secondary "content area" filling

您可以使用类似...的功能将其关闭.

You can turn this off using something like...

btn.setContentAreaFilled(false);
btn.setOpaque(true);

这将导致类似...

这篇关于如何从Java Swing中的派生类更改JButton的背景颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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