我正在尝试创建一个包含大量JPanel和文本部分的JFrame,所有这些都有默认颜色(面板的背景为白色,文本为黑色)。我想允许用户在运行时动态更改这些,所以我实现了一个JColorChooser对话框,我可以在其中单击按钮,显示对话框,然后我可以保存颜色。
我的默认颜色是在实例变量中设置的,如下所示:
private Color panelColor;
private Color textColor;
要设置我的面板的背景颜色,我使用:
JPanel samplePanel = new JPanel();
samplePanel.setBackground(panelColor); //panelColor has already been instantiated
这很好用,使面板变白。但是,当我尝试使用JColorChooser加载新颜色以供使用时,面板不会更改。我选择Color之后使用的代码是:
if(newColor != null)
{
panelColor = newColor;
myFrame.repaint();
}
我的所有组件都在一个JFrame中,我认为在JFrame上调用repaint()会调用paintChildren()并一直向下级联到最低级别。
我认为我的问题在于我对如何在Java中处理对象的理解。我知道对象是通过引用传递的,但我也假设当我设置组件的背景颜色时,这是通过引用传递方案实现的,我开始怀疑。当我调用setBackground()时,我传入的Color参数是否通过pass-by-value作为副本结束?
如果我的预感是正确的,这是否意味着我应该编写一个方法,其中包含需要更改背景的所有组件,并调用每个组件的setBackground(),并使用新值传入Color变量?
干杯
答案 0 :(得分:1)
由于Color对象在使用setBackground()时按值传递给Component,正如markspace建议的那样,每个Component都会调用其各自的方法。
在此主题中使用Dan O提供的修改版代码:Iterate through all objects in Jframe, 我已经提出了一个解决方案,允许修改JFrame(或任何容器)中的每个JPanel。它是一个递归解决方案,因此任何嵌套的Container实例也将遍历其子代。
public void setPanelColor(Container parent)
{
for(Component c : parent.getComponents())
{
if(c instanceof Container)
{
if(c instanceof JPanel)
{
c.setBackground(panelColor);
}
setPanelColor((Container)c);
}
}
}
由于我使用实例变量(panelColor)来保存Color,我可以在方法中引用它,但您可以轻松地将其作为参数传递,并将panelColor替换为传入的Color变量的名称。