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);
}
}
|
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
|