1

我有一个允许用户调整颜色的 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 中重新绘制当前可见的组件。

4

5 回答 5

2

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

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

于 2013-07-31T20:03:40.043 回答
2

听起来您没有很好地处理使用您的Colors类可能存在哪些组件。在这种情况下,我将提供Colors支持PropertyChangeListeners 的能力。

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,将其定义为 aPropertyChangeListenerColors告知它。

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();
  }
}
于 2013-08-01T09:18:41.570 回答
1

让一个类扩展 JPanel 并覆盖公共 void paintComponent 函数。

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

于 2013-07-31T20:04:07.130 回答
1

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

Window[] windows = Frame.getOwnerlessWindows();
for (int i = 0; i < windows.length; i++) {
    windows[i].repaint();
}
于 2013-08-28T18:29:57.700 回答
1

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

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

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

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

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

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

于 2013-08-28T21:19:31.773 回答