JDK-4297006 : Difficult to use translucent background colors with JPanel
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1999-12-06
  • Updated: 2000-03-17
  • Resolved: 2000-03-17
Description

Name: mc57594			Date: 12/05/99


java version "1.3beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3beta-O)
Java(TM) HotSpot Client VM (build 1.3beta-O, mixed mode)


/* Separately, opaque and Color.alpha work ok.
 * But a transparent (setOpaque(false)) component cannot be
 * placed on a panel with a background whose color's alpha!=255
 * If you do it, one of the following 2 problems appear
 * a) in this example,
 *  caret is not properly repainted when you move it
 * In the example I even place a second white opaque panel behind
 * the yellow panel
 * b) in other cases,
 *  the color of the panel is not showed
 */
public class SwingApp extends JFrame{
  public SwingApp(String name){
    super(name);
    ///A white opaque background
    JPanel bottomPane = new JPanel();
    bottomPane.setBackground(Color.white);
    bottomPane.setOpaque(true);
    getContentPane().add(bottomPane);

    JPanel pane = new JPanel();
    bottomPane.add(pane);
    
    JTextPane t=new JTextPane();
    t.setOpaque(false);
    //t.setBackground(Color.white);
    pane.setBackground(new Color(255,255,0,128));
    pane.setOpaque(true);
    pane.add(t);
    
    
    
    pack();
    setVisible(true);
  }

  
  public static void main(String args[]) {
    SwingApp t= new SwingApp("hola");
  }
}
(Review ID: 98178) 
======================================================================

Comments
WORK AROUND import java.awt.*; import javax.swing.*; /* * An application that places a panel with a translucent yellow * background on top of a frame with a cyclic gradient fill * pattern. */ public class SwingApp extends JPanel{ boolean fancybg; public SwingApp(boolean bg){ fancybg = bg; setOpaque(false); } public void paintComponent(Graphics g) { super.paintComponent(g); if (fancybg) { Color c1 = new Color(128, 128, 255); Color c2 = new Color(128, 255, 128); ((Graphics2D)g).setPaint(new GradientPaint(0, 0, c1, 10, 0, c2, true)); } else { g.setColor(new Color(255,255,0,128)); } Rectangle r = g.getClipBounds(); g.fillRect(r.x, r.y, r.width, r.height); } public static void main(String args[]) { JFrame f = new JFrame("hola"); ///A white opaque background JPanel bottomPane = new SwingApp(true); f.getContentPane().add(bottomPane); SwingApp sa = new SwingApp(false); bottomPane.add(sa); JTextPane t=new JTextPane(); t.setText("Opaque text on Translucent background"); t.setOpaque(false); //t.setBackground(Color.white); sa.add(t); f.pack(); f.setVisible(true); } }
11-06-2004

EVALUATION This is really a Swing issue. It is not clear that they have a way of expressing a translucent background. In particular, it appears that the setOpaque() method has two consequences which do not interact well here: Setting it false causes Swing to not fill the component with its background color when painting it. Setting it true causes Swing to assume that filling the component with its background color will completely occlude and replace the previous contents of the pixels in the bounds of the component. In the case of trying to have a translucent component, you would not want to use false since that would not fill the background of the component and you would not want to use true since that would cause them to have you render your translucent colors on top of old, possibly stale pixel data. The latter problem is why the caret in this example is not erased (it is drawn over with a non-opaque color which does not completely erase it). Changing this example to use setOpaque(false) leaves the background of the text object unfilled. I believe that one possible answer is that you might be able to set the opaque flag to false so that Swing does not make bad assumptions about the backdrop of your component, but then to fill your own background in your paint routine since they will obviously not do it for you. I've attached an example of this in the workaround field, though I may not have implemented it correctly. Since this is a Swing issue, not a 2D issue, I am reassigning this to Swing for further consideration and comments on my workaround. jim.graham@Eng 2000-01-10 As Jim states above, the right thing to do is to set the opaque property to false, and do the painting yourself. Why? A component that paints itself with a translucent color is not opaque, and setting opaque to false means JComponent will not do the painting for you. scott.violet@eng 2000-03-17
17-03-2000