This code is supposed to display a background image and the player. But it just comes up with a pink screen. I can't really figure out where the problem is coming from, here is my code.
package main;
import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class Images extends JFrame {
public static void main(String Args[]) {
DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN); // This is going to take 4 parameter, first 2 is x and y for resolotion. Bit depth, the number of bits in a cloour
// 16 is your bit depth. the last one is the monitor refresh, it means it will refres how much it wants
Images i = new Images(); // making an object for this class
i.run(dm); // making a run method and is taking the dm as a parameter, in this method we are putting stuff on the screen.
}
private Screen s; // Creating the Screen, from the Screen.java
private Image bg; // Background
private Image pic; // Face icon
private boolean loaded; // Making the loaded
//Run method
private void run(DisplayMode dm) { // this is where we do things for the screen
setBackground(Color.PINK); // Setting the Background
setForeground(Color.WHITE); // Setting the ForeGround
setFont(new Font("Arial", Font.PLAIN, 24)); // setting the font
s = new Screen(); // now we can call ALL methods from the Screen object
try {
s.setFullScreen(dm, this); // This is setting the full screen, it takes in 2 parameters, dm is the display mode, so its setting the display settings, the next part is the this, what is just s, the screen object.
loadpics(); // calling the loadpics method
try { // so if that try block works, then it will put it to sleep for 5 seconds
Thread.sleep(5000); // its doing this because, at the bottom (s.restorescreen) this makes it into a window again. so it needs to show it for 5 seconds.
} catch (Exception ex) {
}
} finally {
s.restoreScreen();
}
}
// Loads Pictures
private void loadpics() {
System.out.println("Loadpics == true");
bg = new ImageIcon("Users/georgebastow/Picture/background.jpg").getImage(); // Gets the background
pic = new ImageIcon("Users/georgebastow/Picture/Player.png").getImage(); // Gets the Player
System.out.println("Loaded == true in da future!");
loaded = true; // If the pics are loaded then...
}
public void paint(Graphics g) {
if (g instanceof Graphics2D) { // This has to happen, its saying if g is in the class Graphics2D, so if we have the latest version of java, then this will run
Graphics2D g2 = (Graphics2D) g; // Were making the Text smooth but we can only do it on a graphcis2D object.
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // we are making the text aniti alias and turning it on!(it means making the text smooths! :) )
}
if(loaded == true){
System.out.println("Loaded == true3");
g.drawImage(bg,0,0,null);
g.drawImage(pic, 170, 180, null);
System.out.println("Loaded == true4");
}
}
}
Many Thanks in Advance
When using images, you want to load them through URL with Class.getResource()
, which returns a URL. Passing a String the the ImageIcon
will cause the image to be looked up through the file system. Though this may work during development in your IDE, you'll come to find out it won't work at time of deployment. Better make the changes now. To use this method, you want do this
ImageIcon icon = new ImageIcon(Images.class.getResource("/Users/georgebastow/Picture/background.jpg"));
For this to work though, you file structure needs to look like this
ProjectRoot
src
Users
georgebastow
Picture
background.jpg
A more common approach is just to put the image a reousrces folder in the src
ProjectRoot
src
resources
background.jpg
And use this path
ImageIcon icon = new ImageIcon(Images.class.getResource("/resources/background.jpg"));
When you build, your IDE will transfer the images to the class path.
Side Note
JFrame
. Instead use JPanel
or JComponent
and override the paintComponent
method. if using JPanel
, you should also call super.paintComponent
in the paintComponent
method.Run you Swing Apps from the Event Dispatch Thread like this
public static void main(String[] args) {
SwingUtiliities.invokeLater(new Runnable(){
public void run() {
new Images();
}
});
}
See Initial Thread
Don't call Thread.sleep()
. When running from the EDT (like you should), you will block it. Instead use a java.swing.Timer
if it's animation you're looking for. Even if it's not animation, still use it! See this example for Timer
program.
UPDATE
Run this example. I also forgot to mention, when you paint on JPanel
you also want to override the getPreferredSize()
. This will give your panel a size.
src/resources/stackoverflow5.png
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestImage {
public TestImage() {
JFrame frame = new JFrame("Test Image");
frame.add(new NewImagePanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public class NewImagePanel extends JPanel {
private BufferedImage img;
public NewImagePanel() {
try {
img = ImageIO.read(TestImage.class.getResource("/resources/stackoverflow5.png"));
} catch (IOException ex) {
System.out.println("Could not load image");
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestImage();
}
});
}
}