views:

319

answers:

3

How do I set a background image to a JTextPane - some sort of a watermark.

I tried this option - creating a child class of JTextPane and use the paint method to draw the image. But then the text is displayed "below" the image than above.

Is there any "standard" or "well known" way to do this?

(BTW, I tried (something silly?) making the content type "text/html", and setting the image as the background image of a <div> but it did not help.)

+1  A: 

Try changing the paint code to this.

  public void paint(Graphics g)
  {
        g.setXORMode(Color.white);
        g.drawImage(image,0, 0, this);
        super.paint(g);
  }

This would make your image to be painted before the text is rendered by the actual component's paint method.

Chandru
Overriding paint() is generally not recommended in Swing, according to "Filthy Rich Clients". In Swing, overriding paintComponent is usually what you want.
Steve McLeod
Agreed. I just used the code from the EE URL posted by Nivas.
Chandru
+1  A: 

Hmm., put a background image to the JFrame/JPanel containg the JTextPane,.. and keep the JTextPane transparent to some level.

echo
A good idea, but i have other components on the same panel. Yes I can add a new panel *just* for this text pane, but somehow i dont want to add more components...
Nivas
+2  A: 

Here's a working example:

import javax.swing.*;
import java.awt.*;

public class ScratchSpace {

    public static void main(String[] args) {
        JFrame frame = new JFrame("");
        final MyTextPane textPane = new MyTextPane();
        frame.add(textPane);

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static class MyTextPane extends JTextPane {
        public MyTextPane() {
            super();
            setText("Hello World");
            setOpaque(false);

            // this is needed if using Nimbus L&F - see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6687960
            setBackground(new Color(0,0,0,0));
        }

        @Override
        protected void paintComponent(Graphics g) {
            // set background green - but can draw image here too
            g.setColor(Color.GREEN);
            g.fillRect(0, 0, getWidth(), getHeight());

            // uncomment the following to draw an image
            // Image img = ...;
            // g.drawImage(img, 0, 0, this);


            super.paintComponent(g);
        }
    }
}

The important things to note:

  1. your component must not be opaque... so setOpaque(false);

  2. override paintComponent(Graphics g), not paint.

  3. paint your background, with an image or drawing BEFORE calling super.paintComponent(g);

If you want to master this stuff, I recommend reading "Filthy Rich Clients", a book all about how to bend Swing to your will.

Steve McLeod
Nivas
@Nivas,I've added a work-around to the Nimbus problem: setBackground(new Color(0,0,0,0));
Steve McLeod
Thanks! I was about to comment "This is related to http://stackoverflow.com/questions/613603/java-nimbus-laf-with-transparent-text-fields :-)
Nivas
I found that the image was getting "stronger" everytime the TextPane got focus... thought that this was because the repaint method was painting the image again and again. To solve this, I added g.clearRect(0, 0, getWidth(), getHeight()); as the first line to paintComponent... and it worked!
Nivas