Jcomponents Not Showing Up With Picture Background

Having images as background of JPanel

Why not make a single class that takes a Image??

public class ImagePane extends JPanel {

private Image image;

public ImagePane(Image image) {
this.image = image;
}

@Override
public Dimension getPreferredSize() {
return image == null ? new Dimension(0, 0) : new Dimension(image.getWidth(this), image.getHeight(this));
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(image, 0, 0, this);
g2d.dispose();
}
}

You would even provide hints about where it should be painted.

This way, you could simply create an instance when ever you needed it

Updated

The other question is, why?

You could just use a JLabel which will paint the icon for you without any additional work...

See How to use labels for more details...

This is actually a bad idea, as JLabel does NOT use it's child components when calculating it's preferred size, it only uses the size of the image and the text properties when determining it's preferred size, this can result in the component been sized incorrectly

Why is my image (and child components) not showing with ImageBackground on React Native?

Answered! The answer was to add flex: 1 to the parent view container - for those running into the same problem.

Background image not showing in Java Game

Let's start with...

backgroundImage = new BackgroundImage("/background.png");

Which becomes...

File image2 = new File(path);

or

File image2 = new File("/background.png");

so you can see it...can you see a problem with this? This is requesting a file which resides at the root location of the current drive...not really what I think you want...

The images are stored in a folder called "res" in the main project folder

Which would suggest you want to use...

backgroundImage = new BackgroundImage("res/background.png");

Assuming that the images are not embedded resources....

Next...

public BackgroundImage(String s) {
if (s == null) {
background = getImage(s);
}
}

So, you only ever want to try a load the image when it's reference is null???

Side notes...

frame.setSize(WIDTH * SCALE, HEIGHT * SCALE); is a bad idea, as frames have borders which occupy space within side the frame itself.

Better to override the getPreferredSize method of Canvas and provide a default size value you want to use and then call pack on the frame instead. This will calculate the size of the frame as the preferred size of it's content PLUS the frame border requirements...

You "game loop" is running wild...

while (running) {
delta += (now - lastTime) / ns;
lastTime = now;
if (delta >= 1) {
tick();
delta--;
}
render();
}

Basically, this will run as fast as it possibly can and will reduce the opportunity for other threads to run, eventually bringing your game (and probably your PC) to it's knees

This is "simple" concept of a run loop...

public void run() {
init();
final long amountOfTicks = 60;
long ns = Math.round(1_000_000_000 / (double)amountOfTicks);

int frames = 0;
long frameStart = System.currentTimeMillis();

while (running) {
long startedAt = System.nanoTime();
tick();
render();
long completedAt = System.nanoTime();
long duration = completedAt - startedAt;

long frameEnd = System.currentTimeMillis();
if (frameEnd - frameStart >= 1000) {
System.out.println(frames);
frames = 0;
frameStart = System.currentTimeMillis();
} else {
frames++;
}

long rest = ns - duration;
if (rest > 0) {
rest = TimeUnit.MILLISECONDS.convert(rest, TimeUnit.NANOSECONDS);
try {
Thread.sleep(rest);
} catch (InterruptedException ex) {
}
}
}
stop();
}

Basically, it tries to ensure that there is enough delay between each iteration in order to maintain the 60fps you are trying to target...without starving the system...

JFrame not showing a picture

There are so many things wrong with this I'm not sure where to start...

Let's start at the beginning...

Problem #1

You declare a instance field called steve in you WindowPractice class, this is fine, but in your main method, you declare ANOTHER variable called steve which you are using the reference to the loaded image...

public static void main(String[] args) {
new WindowPractice();
ImageIcon steve = new ImageIcon("C:/Users/shane/Dropbox/issue459.jpg");
JLabel imageLabel = new JLabel(steve);
}

This means that the class instance variable is never initialised and remains null.

Problem #2

While not directly related, you never call super.paint from your paint method. This is a BIG NO, NO. You are obligated to maintain the paint chain. The paint methods are complex and very, very important.

Problem #3

You should never override a top level container (such as JFrame) nor you should you override any of it's paint methods. There are lots of reasons for this, but among the top two are, most top level containers actually contain a number of components (JRootPane, which houses the glass pane, content pane, layer pane and menu bar) which can sit over your painting efforts and, generally, they're not double buffered, meaning you paint updates will flicker and look horrible ;)

You should also avoid using paint, instead, you should look towards using paintComponent where it's available.

Problem #4

ImageIcon is not you best choice for loading images. The main reason I don't use them is that you have no idea of when the image being loaded will actually become available (actually there are ways, but to be frank, ImageIO is just simpler). This was a great feature back in 1999 when dial-up speeds where around the 14.4k mark, but now days...

ImageIO supports a wider range of picture formats, supports reading and writing of images and guarantees that when the method returns (successfully), the image pixel data is available to your application.

Example

Here's a better (IMHO) approach...

Sample Image

public class BetterDrawing {

public static void main(String[] args) {
new BetterDrawing();
}

public BetterDrawing() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new PaintPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class PaintPane extends JPanel {

private BufferedImage background;

public PaintPane() {
try {
background = ImageIO.read(new File("/path/to/image"));
// Use this instead to load embedded resources instead
//background = ImageIO.read(getClass().getResource("/path/to/image"));
} catch (IOException ex) {
ex.printStackTrace();
}
}

@Override
public Dimension getPreferredSize() {
return background == null ? super.getPreferredSize() : new Dimension(background.getWidth(), background.getHeight());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

if (background != null) {

int x = (getWidth() - background.getWidth()) / 2;
int y = (getHeight() - background.getHeight()) / 2;

g.drawImage(background, x, y, this);

}

}
}
}

Have a read of

  • Performing custom painting
  • Working with Images

For some more information.



Related Topics



Leave a reply



Submit