如何重绘Java Swing应用程序的所有可见组件?

时间:2013-07-31 19:50:19

标签: java swing user-interface

我有一个允许用户调整颜色的JFrame。使用反射将此颜色设置为类Colors的静态字段。这是Colors类:

public class Colors {

    public static Color TextBackground = Color.black;
    public static Color TextForeground = Color.white;
}

还有许多其他组件,位于多个JFrame中,它们都使用Colors类的字段。当我手动使它们重新绘制时(例如通过调整大小),它们都会正确重新绘制。

但是如何让所有其他组件自动重新绘制?

我尝试了一些看起来很脏的东西,改变了LookAndFeel,但它不起作用:

 UIManager.setLookAndFeel(UIManager.getLookAndFeel());

更新:我需要重新显示当前可见的所有其他 JFrame中的组件。

5 个答案:

答案 0 :(得分:2)

您需要在JFrame上调用一个方法,让它知道在更改颜色时需要重新绘制其内容。我认为正确的方法是revalidate(),但repaint()也可以。有关在Swing中绘画的更多信息,请尝试查看:

http://www.oracle.com/technetwork/java/painting-140037.html

答案 1 :(得分:2)

听起来您无法很好地处理使用Colors课程的组件。在这种情况下,我会Colors支持PropertyChangeListener s。

class Colors {

  private static Colors instance = new Colors();

  public static Colors getInstance() {
    return instance;
  }

  private Color textBackground = Color.black;

  private PropertyChangeSupport backgroundProp = new PropertyChangeSupport(textBackground);

  public void setBackgroundColor(Color color) {
    this.textBackground = color;
  }

  public void addBackgroundListener(PropertyChangeListener listener) {
    backgroundProp.addPropertyChangeListener(listener);
  }
}

然后,只要某个组件使用Colors,就将其定义为PropertyChangeListener并让Colors了解它。

class MyTextField extends JTextField implements PropertyChangeListener {

  public MyTextField() {
    super();
    Colors.getInstance().addBackgroundListener(this);
  }

  public void propertyChange(PropertyChangeEvent evt) {
    Color background = (Color)evt.getNewValue();
    setBackground(background);
    repaint();
  }
}

答案 2 :(得分:1)

让一个类扩展JPanel并覆盖它 public void paintComponent函数。

当你调用frame.repaint()时,它将引用paintComponent中的代码。

答案 3 :(得分:1)

这将重新绘制所有无主窗口

Window[] windows = Frame.getOwnerlessWindows();
for (int i = 0; i < windows.length; i++) {
    windows[i].repaint();
}

答案 4 :(得分:1)

  

使用反射将此颜色设置为类颜色的静态字段。

这是你的问题。而不是a)将颜色存储在静态变量中,b)使用反射来更新这些值,或者c)循环遍历无主窗口的数组,使用Swing设计。这是一个更多的代码,但它会更干净,更有效地做你想要的。

  1. 不要使用反射。为用户创建一个实际界面,在实例中而不是静态更新颜色值,并将其与用户将使用的框架绑定,以指定他们想要的颜色。

  2. 在ColorManager对象上放置接受ChangeListener个对象的方法。至少,只需创建addChangeListener()方法,但也可以通过定义多个方法addBackgroundListener()addForegroundListener()等来添加更精细的控件。这些方法应该存储已注册的侦听器列表当相关动作(用户更新颜色)被执行时将被通知。

  3. 让您的Windows实现ChangeListener接口,并使用ColorManager对象注册它们。调用stateChanged()方法时,您的窗口可以处理它,更新颜色并在同一位置调用repaint()

  4. 这里的关键优势是现在每个类都正在完成它应该做的事情,并且对其他类没有意外的副作用。 ColorManager直接(而不是通过反射)由用户更新,它准确地通知明确要求通知的对象(如果这是你想要的那些,它仍然可以是所有窗口),那些对象可以用它做信息他们需要什么,无论是重画还是做一些更复杂的事情。