I am trying to get an image to display inside my JFrame and having no success. I have followed the Oracle tutorial exactly and I get a NullPointerException:
Exception in thread "main" java.lang.NullPointerException
at net.ultibyte.TheDo.CreateLoginScreen.DisplayImage(CreateLoginScreen.java:35)
at net.ultibyte.TheDo.CreateLoginScreen.main(CreateLoginScreen.java:41)
Below is my code.
public class CreateLoginScreen extends JFrame {
CreateLoginScreen() {
setTitle("TheDo");
setSize(1280, 720);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static Image loadImage() {
Image i = null;
try {
i = ImageIO.read(new File("src/resources/LoginScreen.png"));
} catch (IOException e) {
}
return i;
}
public static void DisplayImage(Image i) {
Graphics g = i.getGraphics();
g.drawImage(i, 0, 0, null);
}
public static void main(String[] args) {
CreateLoginScreen a = new CreateLoginScreen();
DisplayImage(loadImage());
}
}
And the image is named "LoginScreen.png", and is located in a package called "resources" which is in the src folder.
I have no idea what's wrong and would very much appreciate any help :).
Update: Corrected file path, pointed out by peeskillet. This fixed the NullPointerException. Still won't display image though.
"located in a package called "resources" which is in the src folder."
You need to use this file path. "src/resources/LoginScreen.png"
Your IDE will first look in the main project folder. since src is direct child of the project root, you need to add that to the path
EDIT
"The window loads up but no image is displayed. Any idea on this? "
Yes, you need to override a paint method in order to draw the image on to the component. I wouldn't use JFrame though. I would use a JPanel and override the paintComponent method.
Try this out
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
class JPanelTemplate extends JPanel {
private static final int SCREEN_WIDTH = 400;
BufferedImage img;
public JPanelTemplate() {
try {
img = ImageIO.read(new File("src/resources/LoginScreen.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(SCREEN_WIDTH, SCREEN_WIDTH);
}
private static void createAndShowGui() {
JFrame frame = new JFrame();
frame.add(new JPanelTemplate());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Related
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUITest {
private JPasswordField passwordBox;
private JButton enterButton = new JButton ("Enter");
private JLabel textBox = new JLabel("Enter Password Here:");;
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
public void GUITest() {
PanelSetup();
FrameSetup();
}
public void PanelSetup(){
panel.setBorder(BorderFactory.createEmptyBorder(150, 150, 250, 250));
panel.setLayout(new GridLayout(0,1));
}
public void FrameSetup(){
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setTitle("GUI TEST");
frame.pack();
frame.setVisible (true);
}
public static void main (String[] args) {
new GUI();
}
}
Unfortunately, the problem is creating the new GUI and I cannot run the code to see if the rest of it works and/or adding more stuff to it. If you can help that would be much appreciated
Change "new GUI();" to "new GUITest();" as you are creating a new instance of the current class.
public static void main (String[] args) {
new GUI();
}
to
public static void main (String[] args) {
new GUITest();
}
Also, remove the void tag from your constructor as it turns it into a method.
public void GUITest() {
PanelSetup();
FrameSetup();
}
to
public GUITest() {
PanelSetup();
FrameSetup();
}
It seems like you're new to java, welcome! I'd take a look at w3schools excellent java docs if you want to get better at syntax. w3schools java
For a few days I have been trying to create a JPanel, that comes flying in from the side. I found the Universal Tween Engine and also saw a few demos but for some reason I was never able to make it work in my own code. For the sake of simplicity let's just attempt to move a JPanel (containing an image in a JLabel) from (0,0) to (600,0) on a JFrame. This is what I've got so far and the closest I have ever gotten to actually moving things with this framework, all it does it make the JPanel jump to its destination within the first tick or so. It is supposed to be so simple but I must be missing something...
SlideTest.java - Creating the UI, initializing the Thread + Tween
public class SlideTest {
TweeningPane p;
public TweenManager tweenManager;
public static void main(String[] args) {
new SlideTest();
}
public SlideTest() {
try {
setupGUI();
} catch (IOException e) {
e.printStackTrace();
}
tweenManager = new TweenManager();
AnimationThread aniThread = new AnimationThread();
aniThread.setManager(tweenManager);
aniThread.start();
Tween.to(p, 1, 10.0f).target(600).ease(Quad.OUT).start(tweenManager);
}
public void setupGUI() throws IOException {
JFrame f = new JFrame();
f.setSize(800, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p = new TweeningPane();
JLabel l = new JLabel(new ImageIcon("E:/Pictures/Stream/aK6IX4V.png"));
f.setLayout(null);
p.add(l);
p.setBounds(0, 0, 300, 300);
f.add(p);
f.setVisible(true);
}
}
AnimationThread.java - The Thread, that is supposed to keep my TweenManager updated as much/often as possible
public class AnimationThread extends Thread {
TweenManager tm;
public void setManager(TweenManager tweenmanager) {
this.tm = tweenmanager;
}
public void run() {
while (true) {
//System.out.println("MyThread running");
tm.update(MAX_PRIORITY);
try {
sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
TweeningPane.java - My Object(JPanel), I want to move across the JPanel
public class TweeningPane extends JPanel implements TweenAccessor<JPanel> {
private static final long serialVersionUID = 1L;
#Override
public int getValues(JPanel arg0, int arg1, float[] arg2) {
return (int) arg0.getBounds().getX();
}
#Override
public void setValues(JPanel arg0, int arg1, float[] arg2) {
arg0.setBounds((int) arg2[0], 0, 300, 300);
}
}
I have finally figured it out. I was simply using the framework in a wrong way as I expected. I'm not sure whether all these steps were needed but this is what I went through in order to make it work: (for future reference)
I had to register my accessor to the engine:
Tween.registerAccessor(TweeningPane.class, new TweeningPane());
And the thread itself now looks like this; I had to give the manager's update method the elapsed time as a parameter.
public void run() {
long ms1 = System.currentTimeMillis();
while (true) {
//System.out.println("MyThread running");
tm.update((System.currentTimeMillis() - ms1) / 1000f);
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Please be patient with me.. I'm very new to Java.
I have two separate JFrames and the first loads the background I want but when I dispose the first JFrame and load the second one it loads with the background from the first.
j1.java
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
public class j1 extends JFrame implements KeyListener {
public bg1 img;
public bg2 img2;
public j1() {
lvl1();
}
private JFrame lvl1() {
this.img=new bg1();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
setTitle("lvl1");
setResizable(false);
setSize(600, 600);
setMinimumSize(new Dimension(600, 600));
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add(img);
pack();
setVisible(true);
return(this);
}
private JFrame lvl2() {
this.img2=new bg2();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
setTitle("lvl2");
setResizable(false);
setSize(600, 600);
setMinimumSize(new Dimension(600, 600));
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add(img2);
pack();
setVisible(true);
return(this);
}
public void keyPressed(KeyEvent e) { }
public void keyReleased(KeyEvent e) {
if(e.getKeyCode()== KeyEvent.VK_RIGHT) {
lvl1().dispose();
lvl2();
}
}
public void keyTyped(KeyEvent e) { }
public static void main(String[] args) {
new j1();
}
}
bg1.java
import java.awt.Graphics;
import javax.swing.JComponent;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
public class bg1 extends JComponent {
public BufferedImage person;
public BufferedImage background;
public bg1() {
loadImages2();
}
public void loadImages2() {
try {
String personn = "Images/person.gif";
person = ImageIO.read(new File(personn));
String backgroundd = "Images/background2.jpg";
background = ImageIO.read(new File(backgroundd));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background, 0, 0, this);
g.drawImage(person, 100, 100, this);
}
public static void main(String[] args) {
new bg1();
}
}
bg2.java is very similar to bg1.java but it has different names for the images and voids.
So you kind of have a series of problems.
First, this is one of the dangers of re-using a frame this way, basically, you never actually remove bg1 from the frame, you just keep adding new instances of the bg2. This means that bg1 is still visible and valid on the frame...
Second, you're calling lvl1() AGAIN before you call lvl2, which is making a new instance of bg1 and adding that to the window and then disposing of it (which does NOT dispose of the components) and then you add a new instance of lvl2 to the frame and the whole thing is just one big mess.
Instead, you should simply be using a CardLayout which will allow you to switch between the individual views more elegantly. See How to Use CardLayout for moer details.
You should also have a look at How to Use Key Bindings instead of using KeyListener
As general rule of thumb, you should avoid overriding JFrame, this has a nasty habit of just confusing the whole thing. Simple create a new instance of a JFrame when you need it and add you components directly to it. Before anyone takes that the wrong way, you'll also want to have a look at The Use of Multiple JFrames, Good/Bad Practice?
I am having trouble simply importing an image using this code. Where should the Image be stored? I thought it had to be in a folder within the source folder and in this case called ImageIcon but I am not sure... thanks to anybody who helps!
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
class Surface extends JPanel {
private Image mshi;
public Surface() {
loadImage();
setSurfaceSize();
}
private void loadImage() {
mshi = new ImageIcon("mushrooms.jpg").getImage();
}
private void setSurfaceSize() {
Dimension d = new Dimension();
d.width = mshi.getWidth(null);
d.height = mshi.getHeight(null);
setPreferredSize(d);
}
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(mshi, 1, 1, null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
public class DisplayImage extends JFrame {
public DisplayImage() {
initUI();
}
private void initUI() {
setTitle("Mushrooms");
add(new Surface());
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
DisplayImage ex = new DisplayImage();
ex.setVisible(true);
}
});
}
}
Do you try to put the image in the same directory as your class file Surface ?
Ok, sorry i had not seen the class DisplayImage.
The best way i think to do it, create a separate class file for Surface.
Write in Surface class file, a constructor with parameter. The parameter will be the image path. It will be simple for you to change the image if you want after.
Something like this :
public class Surface extends JPanel {
private Image mshi;
public Surface(String imagePath) {
mshi = new ImageIcon(imagePath).getImage();
setSurfaceSize();
}
private void setSurfaceSize() {
Dimension d = new Dimension();
d.width = mshi.getWidth(null);
d.height = mshi.getHeight(null);
setPreferredSize(d);
}
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(mshi, 1, 1, null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
You don't need to write the method loadImage(), it will be probably used in your class because it is private and it just do one simple thing.
Concerning the structure of your project directory make something like this
Project directory\src
Project directory\src\Surface.class
Project directory\src\DisplayImage.class
Project directory\images
Project directory\images\mushrooms.jpg
Ps : Sorry for my english, it still under construction.
I have designed a component for J2Me, and here is the paint method:
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
class Component {
...
public void paint(Graphics g) {
if (background != null)
g.drawImage(image, bounds.getLocation().x, bounds.getLocation().y, 0);
}
...
}
I want to paint this component on a J2Se application, I tried to paint the component onto a J2Me Image and extracted the int[] into an InputStream, and create a new image on the J2Se platform, with this object:
public class ComponentStreamer {
private Component component;
private Image j2Me_Image;
public void setComponent(Component component) {
this.component = component;
}
public InputStream getInputStream() throws IOException {
if(component==null)
return null;
//THIS LINE THROWS THE EXCEPTION
j2Me_Image=Image.createImage(component.getSize().width, component.getSize().height);
component.paint(j2Me_Image.getGraphics());
return getImageInputStream(j2Me_Image);
}
}
I've tried the Object, but the commented line throws an exception:
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: javax.microedition.lcdui.ImmutableImage.decodeImage([BII)V
at javax.microedition.lcdui.ImmutableImage.decodeImage(Native Method)
at javax.microedition.lcdui.ImmutableImage.getImageFromStream(Image.java:999)
at javax.microedition.lcdui.ImmutableImage.<init>(Image.java:955)
at javax.microedition.lcdui.Image.createImage(Image.java:554)
How can over come this error?
Thanks,
Adam.
Well,
That was a very long process of diving into the sources of the J2Me MIDP and CLDC, and the use of a package called Microemulator, here is some code to get anyone else started:
this starts an emulator, which then enables some of the J2Me features.
private void setUpEmulator() {
try {
// overrideJ2MeImagePackageLock();
Headless app = new Headless();
DeviceEntry defaultDevice = new DeviceEntry("Default device", null, DeviceImpl.DEFAULT_LOCATION, true, false);
Field field = app.getClass().getDeclaredField("emulator");
field.setAccessible(true);
Common emulator = (Common) field.get(app);
emulator.initParams(new ArrayList<String>(), defaultDevice, J2SEDevice.class);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Un-handled Exception");
}
}
Next we have few other nice objects to work with:
public class J2MeImageLayer extends ScalableLayer {
private static final long serialVersionUID = -4606125807092612043L;
public J2MeImageLayer() {
componentViewer.super();
}
#Override
public void repaint() {
J2SEMutableImage mutableImage = new J2SEMutableImage(page.getSize().width, page.getSize().height);
page.paint(mutableImage.getGraphics());
Graphics g = getImage().getGraphics();
g.drawImage(mutableImage.getImage(), 0, 0, DCP_Simulator.this);
}
public void addComponent(Component component) {
page.add(component);
}
public void setComponent(final Component component) {
page.removeAllElements();
final Container componentParent;
if ((componentParent = component.getParent()) != null)
component.setRemovedAction(new interfaces.Action() {
#Override
public void action() {
componentParent.add(component);
}
});
page.add(component);
}
}
and this is the highlight on how to do that.
Adam.