United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4297006 Difficult to use translucent background colors with JPanel
JDK-4297006 : Difficult to use translucent background colors with JPanel

Details
Type:
Bug
Submit Date:
1999-12-06
Status:
Closed
Updated Date:
2000-03-17
Project Name:
JDK
Resolved Date:
2000-03-17
Component:
client-libs
OS:
windows_nt
Sub-Component:
javax.swing
CPU:
x86
Priority:
P4
Resolution:
Not an Issue
Affected Versions:
1.2.0
Fixed Versions:

Related Reports

Sub Tasks

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);
  }
}
                                     
2004-06-11
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
                                     
2000-03-17



Hardware and Software, Engineered to Work Together