简体   繁体   English

java.awt.Frame.setBackground()在OS X中不起作用

[英]java.awt.Frame.setBackground() not working in OS X

I'm trying to iron out some UI rendering bugs in my java applet in OS X, and I've hit one that I can't figure out. 我试图消除OS X中Java小程序中的一些UI渲染错误,但遇到了一个我不知道的错误。

All the windows that we open that extend java.awt.Frame seem to ignore the setBackground() calls, and instead use the OS X default (brushed metal or gray gradient, depending on the OS version). 我们打开的所有扩展java.awt.Frame的窗口似乎都忽略了setBackground()调用,而是使用OS X的默认设置(金属拉丝或灰色渐变,具体取决于OS版本)。 Anything we open that extends Dialog works fine though. 我们打开扩展Dialog的所有内容都可以正常工作。

I tried overriding the paint() method and drawing the background color there. 我尝试覆盖paint()方法并在那里绘制背景色。 However, this only partially works. 但是,这仅部分起作用。 The background does end up as the correct color in some places, but all child components of the Frame still draw with the OS X background, not the one I set, and so now it looks even worse. 在某些地方,背景确实以正确的颜色显示,但是Frame的所有子组件仍然使用OS X背景绘制,而不是我设置的背景,因此现在看起来更糟了。 Those same component types (Panel, Checkbox, etc) are used in a couple Dialog-extending windows and they work fine there, so I'm guessing there has to be something with Frame that's messing things up. 这些相同的组件类型(Panel,Checkbox等)在几个Dialog扩展窗口中使用,并且在其中可以正常工作,因此我猜测Frame一定有东西在搞乱。

Is there a way to set the background color for a Frame that works in OS X? 有没有一种方法可以为OS X中可用的框架设置背景颜色? Has anyone else even seen this before? 有人看过吗?

Note that I'm stuck coding against the Java 1.1 spec, as I'm required to support the Microsoft JVM (don't get me started...). 请注意,由于我需要支持Microsoft JVM,所以我坚持按照Java 1.1规范进行编码(不要让我开始...)。

I found a workaround. 我找到了解决方法。 I created a wrapper class for Frame that creates a child Panel and places all its contents in that panel. 我为Frame创建了一个包装器类,该包装器类创建了一个子面板,并将其所有内容放置在该面板中。 The Panel has the background color set explicitly (instead of letting it inherit from its parent Frame). 面板具有明确设置的背景颜色(而不是让其从其父框架继承)。 I then changed the classes that extended Frame to extend my new FrameW wrapper class, and the problem went away. 然后,我更改了扩展Frame的类,以扩展新的FrameW包装器类,问题消失了。

My wrapper isn't really functionally complete, but it handles what I need it to handle for the usages I have. 我的包装器实际上并不是功能完整的,但是可以处理我需要的包装,以适应我的用法。 Here's the code I used, in case anyone else runs into this issue: 这是我使用的代码,以防其他任何人遇到此问题:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.LayoutManager;
import java.awt.Panel;

/**
 * Wrapper for java.awt.Frame that wraps the contents in a Panel.  This is done
 * because Frames in OS X appear to ignore the background color, but if the
 * contents are wrapped in a Panel and that Panel is given the background color
 * then it works fine.
 */
public class FrameW extends Frame {

  private Panel wrapper;

  /** Constructs the Frame wrapper */
  public FrameW() {
    super();
    init();
  }

  /**
   * Constructs the Frame wrapper.
   * @param title The title to give the frame.
   */
  public FrameW(String title) {
    super(title);
    init();
  }

  public Component add(Component comp) {
    return wrapper.add(comp);
  }

  public Component add(String name, Component comp) {
    return wrapper.add(name, comp);
  }

  public Component add(Component comp, int index) {
    return wrapper.add(comp, index);
  }

  public void add(Component comp, Object constraints) {
    wrapper.add(comp, constraints);
  }

  public void add(Component comp, Object constraints, int index) {
    wrapper.add(comp, constraints, index);
  }

  public LayoutManager getLayout() {
    return wrapper.getLayout();
  }

  public void setLayout(LayoutManager mgr) {
    /* setLayout is called by Frame's constructor before our init runs. */
    if(this.wrapper == null) { return; }
    wrapper.setLayout(mgr);
  }

  public void setBackground(Color c) {
    super.setBackground(c);
    wrapper.setBackground(c);
  }

  /**
   * Overriding the insets of the frame will cause the panel used for the
   * background color to not take up the entire frame's area.  Instead, override
   * FrameW.getContentInsets() for setting the insets of the content.
   * @return The frame's insets
   */
  public Insets getInsets() {
    return super.getInsets();
  }

  /**
   * Override this instead of getInsets() in order to set the insets of the
   * FrameW.
   * @return The insets for the content
   */
  public Insets getContentInsets() {
    return new Insets(0, 0, 0, 0);
  }

  private void init() {
    this.wrapper = new Panel() {
      public Insets getInsets() {
        return FrameW.this.getContentInsets();
      }
    };

    super.setLayout(new BorderLayout());
    super.add(this.wrapper, BorderLayout.CENTER);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM