Stefano Maglione Stefano Maglione - 1 month ago 10
Java Question

Why does the background image only appear after the window is resized?

I'm creating a simple window with a background image by Swing java library.

The problem is :background image appear only when you resize window.

import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.MediaTracker;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.Toolkit;

public class StartWindow {

JFrame frame;
private JButton button;
private JButton button2;

public void CreateStartWindow() {
frame = Window.createwindow();
Container container = frame.getContentPane();
JpanelStart panel = new JpanelStart();
container.add(panel);
this.button = new JButton("Start");
this.button2 = new JButton("Classifica");
panel.add(button);
panel.add(button2);
}

public void addActionListener(ActionListener al) {
this.button.addActionListener(al);
this.button2.addActionListener(al);
}

public void chiudi() {
frame.dispose();
}
}

class JpanelStart extends JPanel {
private Image img;
private String path_img="img/sfondo.jpg";

public JpanelStart(){
img = Toolkit.getDefaultToolkit().createImage(path_img);
loadImage(img);
}

private void loadImage(Image img) {
try {
MediaTracker track = new MediaTracker(this);
track.addImage(img, 0);
track.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
protected void paintComponent(Graphics g){
setOpaque(false);
g.drawImage(img,0, 0, null);
super.paintComponent(g);
}
}


Window



public class Window extends JFrame {

public static JFrame createwindow() {//fare singleton

JFrame frame = new JFrame("Battaglia navale");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640, 640);
frame.setVisible(true);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

frame.setLocation(((int)dim.getWidth()-(int)frame.getWidth())/2,
((int)dim.getHeight()-(int)frame.getHeight())/2);
return frame;
}
;
}

Answer

If possible, call setVisible on the frame after you've added the components to it, otherwise you'll need to use revalidate and repaint.

Don't call super.paintComponent after you've painted something, as it's likely to clear Graphics context

Don't change the state of any component from with the paintComponent method, call setOpaque is bad from within the paint method is a bad idea, as the Graphics context has already being prepared assuming that the component was opaque

As has already being suggest, you should be passing this as the last parameter to drawImage, especially because of the way you load the image. Personally, I prefer to use ImageIO to load images, as it provides more details when the image fails to load....