tags:

views:

956

answers:

1

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.

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). Anything we open that extends Dialog works fine though.

I tried overriding the paint() method and drawing the background color there. 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. 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.

Is there a way to set the background color for a Frame that works in 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...).

A: 

I found a workaround. I created a wrapper class for Frame that creates a child Panel and places all its contents in that panel. 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.

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);
  }
}
Herms
Since this seems to work and no one else suggested anything I guess I'll mark this as the answer
Herms