Search code examples
javaswingjtextareaalpha-transparency

Java Swing: Ghost text showing up when updating text on a JTextArea with partially transparent background


So here's the deal:

I've got a JPanel and a JTextArea inside that one. The JPanel has a background color which has an alpha value of 200, ie. you can paritally see the background image through the JPanel. Ain't that called partial transparency? Anyway, then I've set the JTextArea non-opaque, so that I can fully see through that one:

JPanel p = new JPanel();
p.setBackground(new Color(237, 234, 215, 200);
JTextArea jta = new JTextArea("Blahblahblahblah");
jta.setOpaque(false);
p.add(jta);

Ok, so when I hit a button, the text will be changed like this:

jta.setText("new BlahBlah...");

Then it happens: the first text remains back there with a new partially transparent film on it. And the text I added, comes on top of course, but right there behind you can see the previous one. When I change the text some few times more, the ghost disappears.

The screenshot as a link.

Translation (the screenshot has 3 shots on a row):
Left one: "Question # 1 out of 8: (a political question)? (My comment: OK)"
Center: "Question # 2 out of 8: (another question, never mind)? (My comment: The ghost is there! [and the arrow pointing it out])"
Right-hand side: "Question # 8 out of 8: (another question)? (My comment: OK)"

If I reduce the amount of questions this program swaps, from 8 to 3, for example, the last one looks usually good, the ghost is gone. But sometimes it sticks on no matter what I do. Could it possibly have something to do with not enough memory (I hardly swallow that, though)?

So, please help me out, dudes! I've got the deadline in 48 hrs.

PS. In case you wonder, that language is Finnish. I'm working on a school project: It's gonna be a comparing machine that can have a variety of applications: For example, if you have a public election coming, the press/media may use this kind of machine on the web to get the candidate's opinions on whatever issues, and then voters may enter their opinions too, and the machine calculates which candidates match the voter's thoughts best. See my homepage, ie. the project blog (Finnish) for more screenshots in case you're interested.

an55i


Solution

  • p.setBackground(new Color(237, 234, 215, 200);
    

    Swing does not support transparent backgrounds.

    Swing expects a component to be either:

    1. opaque - which implies the component will repaint the entire background with an opaque color first before doing custom painting, or
    2. fully transparent - in which case Swing will first paint the background of the first opaque parent component before doing custom painting.

    The setOpaque(...) method is used to control the opaque property of a component.

    In either case this makes sure any painting artifacts are removed and custom painting can be done properly.

    If you want to use tranparency, then you need to do custom painting yourself to make sure the background is cleared.

    The custom painting for the panel would be:

    JPanel panel = new JPanel()
    {
        protected void paintComponent(Graphics g)
        {
            g.setColor( getBackground() );
            g.fillRect(0, 0, getWidth(), getHeight());
            super.paintComponent(g);
        }
    };
    panel.setOpaque(false); // background of parent will be painted first
    

    Similar code would be required for every component that uses transparency.

    Or, you can check out Background With Transparency for custom class that can be used on any component that will do the above work for you.