0

I was trying to have a image background, so I created the following code in a JFrame:

@Override
public void paint(Graphics g) {
    super.paint(g);
    try {
        final Image image = ImageIO.read(getClass().getResource("/images/login/gentlenoise100.png"));
        int iw = 256;
        int ih = 256;
        for (int x = 0; x < getWidth(); x += iw) {
            for (int y = 0; y < getHeight(); y += ih) {
                g.drawImage(image, x, y, iw, ih, this);
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
    }
    for(Component componente:getComponents()){
        componente.repaint();
    }

}

I saw that the background color had some kind of preference and I decided so set it to invisible:

setBackground(new java.awt.Color(0,0,0,0));

It was working fine in Mac OS X (java 1.6), and I had to probe it in Windows and if I remove the setBackground call it doesn't show my background, if I keep the background color invisible it throws an exception and says the Frame is decorated!

I tried to use setUndecorate(true) but in macosx it looses the title bar (of course) and in Windows it gives me a transparent window.

How can I solve that?

  • 1
    [This](http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html) might help explain why you're aving issues with setBackground with an alpha value – MadProgrammer Oct 05 '12 at 11:31

2 Answers2

1

there are three ways, to use

  1. JComponent#setOpaque() in the case that you don't want to panting background

  2. How to Create Translucent and Shaped Windows on Win, OSX a few ***unix

  3. for Transparency have to change value of AlphaComposite


don't paint() whatever to JFrame, put there JPanel and override paintComponent()

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
1

If you can avoid it, don't override the paint methods of top level containers (like JFrame), they do to many important things.

In the case, you'd be better of using a JPanel and setting the frames content pane to it...

Something like...

public class BackgroundPane extends JPanel {

    private Image background;
    public BackgroundPane() {
        try {
            background = ImageIO.read(getClass().getResource("/images/login/gentlenoise100.png"));
        } catch (IOException ex) {
            Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        int iw = 256;
        int ih = 256;
        for (int x = 0; x < getWidth(); x += iw) {
            for (int y = 0; y < getHeight(); y += ih) {
                g.drawImage(background, x, y, iw, ih, this);
            }
        }
    }
}

//...

JFrame frame = new JFrame();
frame.setContentPane(new BackgroundPane());
//...

Don't do anything in your paint method's that are either time consuming or that may cause the repaint manager to schedule your component for repainting again

Things like...

final Image image = ImageIO.read(getClass().getResource("/images/login/gentlenoise100.png"));

and

for(Component componente:getComponents()){
    componente.repaint();
}

Inside you're paint method is an really bad idea.

The second one could cause the repaint manager to decide that the parent container (your frame) needs to repainted, over and over and over and over again...eventually consuming your CPU...

Beware, as of Java 7, calling setBackground with a color that that contains a alpha value of less then 255 on Window will cause the window to become transparent.

Window.setBackground(Color) Passing new Color(0,0,0,alpha) to this method, where alpha is less than 255, installs per-pixel translucency

This will also throw an exception if the window is decorated...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366