Problem mit null pinterexception beim laden von Bildern

  • Themenstarter Themenstarter Maicus
  • Beginndatum Beginndatum
M

Maicus

Gast
Guten Mittag,
ich sitze jetzt schon ziemlich lange an einer Aufgabe, ich will eine art Vereinfachung des Grafikladevorgangs schreiben. Habe aber eine Klasse die sich nicht lädt usw. seht einfach selbst:
Das ist bisher der gesamt Code: (Es geht um die Klasse ImageContainer)
[Java]

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.border.TitledBorder;
import java.io.*;
import javax.imageio.*;
import java.net.*;


/*
* Marcus Janiks Engine zur einfach Erstellung von einfachen Grafischen Anwendung unter Bentzung von Swing
*/
public class Leinwand extends JFrame implements ActionListener
{
private JLabel imageLabel;
private JLabel textLabel;
private JLabel topLabel;
ImageContainer background[];
private JButton imageButton;
private int currentimage;
private ShowCanvas canvas;

public static void main() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Leinwand app = new Leinwand();
app.setVisible(true);
}
});
}

Leinwand()
{
BufferedImage help;

try {
URL url = new URL("images/sunw01.jpg");
help = ImageIO.read(url);
}
catch(MalformedURLException e)
{
}
catch (IOException e) {
System.out.println("What the Heck");
}
System.out.println("Probe");







setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("4Gewinnt");

background = new ImageContainer[5];

for (int i = 0; i < background.length; i++)
{
String path = "images/sunw0" + (i+1) + ".jpg";
int b = 1;
background.loadImage(path);
}

//Container container = getContentPane();
canvas = new ShowCanvas();

imageButton = new JButton(background[0].getImageIcon());
currentimage = 0;

imageButton.setActionCommand("Change");
//imageButton.setOpaque(false);
imageButton.setContentAreaFilled(false);
imageButton.setBorderPainted(false);

/*
imageLabel = new JLabel(background,JLabel.CENTER);
imageLabel.setHorizontalAlignment(JLabel.LEFT);
imageLabel.setVerticalAlignment(JLabel.BOTTOM);
imageLabel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
*/

textLabel = new JLabel("Some sort of text");
textLabel.setVerticalTextPosition(JLabel.CENTER);
textLabel.setHorizontalTextPosition(JLabel.RIGHT);
textLabel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));

topLabel = new JLabel("This the top area");
topLabel.setVerticalAlignment(JLabel.CENTER);
topLabel.setHorizontalAlignment(JLabel.CENTER);
topLabel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

imageButton.addActionListener(this);
imageButton.setToolTipText("Click this Button to change the picture");

setSize(400, 300);
setLocationRelativeTo(null);
//add(imageLabel, BorderLayout.CENTER);
add(imageButton, BorderLayout.WEST);
add(canvas, BorderLayout.CENTER);
add(textLabel, BorderLayout.EAST);
add(topLabel, BorderLayout.NORTH);

}

protected ImageIcon createImageIcon(String path,
String description) {
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}

public void actionPerformed(ActionEvent e)
{
if ("Change".equals(e.getActionCommand())&&currentimage<4)
{
currentimage++;
imageButton.setIcon(background[currentimage].getImageIcon());
}
else
{
currentimage = 0;
imageButton.setIcon(background[currentimage].getImageIcon());
}

}
}

class ImageContainer
{
String Description;
BufferedImage image, originalImage;
ImageIcon icon;
int width, height;
int type;

ImageContainer()
{
Description = "Standard";
image = null;
originalImage = null;
width = 0;
height = 0;
type = 0;
icon = null;
System.out.println("Hierher-1");
}

public void loadImage(String path)
{
System.out.println("Hierher0");
int i=0;
int b = 5;
int x = 3;
try
{
System.out.println("Hierher1");
URL url = new URL(path);
System.out.println("Hierher2");
this.image = ImageIO.read(url);
System.out.println("Hierher3");
}
catch(MalformedURLException e)
{
System.out.println("URLEXCEPTION!");
}
catch(IOException e)
{
System.out.println("Bild");
}
System.out.println("Hierher4");
width = image.getWidth();
height = image.getHeight();
type = image.getType();

originalImage = image;
}

public void resetImage()
{
image = originalImage;
}

public ImageIcon getImageIcon()
{
return icon;
}

public BufferedImage getBufferedImage()
{
return image;
}

public void rescaleImage(int w, int h)
{
BufferedImage resizedImage = new BufferedImage(w, h, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, w, h, null);
g.dispose();
g.setComposite(AlphaComposite.Src);

g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

image = resizedImage;
}
}

class ShowCanvas extends JPanel
{
int x, y;
BufferedImage image;

ShowCanvas() {
setBackground(Color.white);
setSize(450, 400);
addMouseMotionListener(new MouseMotionHandler());

Image img = getToolkit().getImage("images/node.png");

MediaTracker mt = new MediaTracker(this);
mt.addImage(img, 1);
try {
mt.waitForAll();
} catch (Exception e) {
System.out.println("Image not found.");
}
image = new BufferedImage(img.getWidth(this), img.getHeight(this),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
g2.drawImage(img, 0, 0, this);
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(image, x, y, this);
}

class MouseMotionHandler extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}

public void mouseMoved(MouseEvent e) {
}
}
}

class GameTimer
{

private final int NANOSECONDS = 1000000000;

private boolean timerStarted;
private long beginTime, time, timeDifference;

public GameTimer()
{
timerStarted = false;
beginTime = 0;
time = 0;
timeDifference = 0;

}

public void start()
{

timerStarted = true;
beginTime = System.nanoTime();

}

public void stop()
{
timerStarted = false;
beginTime = 0;

}

public int get()
{
time = System.nanoTime();
timeDifference = time - beginTime;
beginTime = time;

return (int)timeDifference;
}

}
[/code]

Das ist die Fehler Ausgabe im Terminal:
Code:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at Leinwand.<init>(Leinwand.java:64)
	at Leinwand$1.run(Leinwand.java:27)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:701)
	at java.awt.EventQueue.access$000(EventQueue.java:102)
	at java.awt.EventQueue$3.run(EventQueue.java:662)
	at java.awt.EventQueue$3.run(EventQueue.java:660)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:671)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
Und im Ausgabefenster kommt nur "Probe raus" nicht einmal das im Konstruktor aufgerufene "Hierher-1" wird angezeigt. Ich würd darauf schließen das es nicht lädt und somit die NullPointerException aufgerufen wird bin mir aber nicht sicher, und seh auch nicht was falsch ist.

Ich hoffe das ihr was findet und danke euch schonmal im Voraus
Marcus
 
Ärger macht:

Java:
URL url = new URL("images/sunw01.jpg");
help = ImageIO.read(url);

Hier wird das Bild nicht gefunden. help bleibt null.

Siehe Doku: ImageIO (Java 2 Platform SE 5.0)).

Returns:
a BufferedImage containing the decoded contents of the input, or null.
 
Find ich aber seltsam da er erst von er die loadImage Funktion von ImageContainer aufruft "abschmiert" das help irgendwie nicht geladen wird fand ich auch komisch aber es ist wenigstens nicht abgeschmiert. Naja und das man BufferedImage so lädt steht überall.
Ich weiß nicht genau wie man des sonst lädt. Einfacher könnte man es aufjedenfall mit ImageIcon machen aber da ich zwischendrin auch die Größe des Bildes ändern will, möchte ich eigentlich auch BufferedImage bleiben.
Und im Endeffekt bleibt die Frage wieso es abschmiert und wieso er null zurückliefert. Weil mit genau dieser URL habe ich auch ein imageicon kreieren können
 
Du hättest auch einfach mal gucken können, was in Zeile 64 in deiner Leinwand Klasse steht 😉
Code:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Leinwand.<init>(Leinwand.java:64)
 
Java:
  background = new ImageContainer[5];
Dabei sind alle Einträge null, aber du rufst dann direkt danach:
Java:
  background[i].loadImage(path);
auf.
Das wirft die NPE 🙂
Wie gesagt, Zeile 64.
 
Hab ich geschaut aber wie gesagt mit [Java]java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}[/code] kann er des laden
 
Aber wenn ich background = new Imagecontainer[5] aufrufe, dann werden doch auch die Konstruktoren von ImageContainer aufgerufen wie kann es dann null sein?
 
Du rufst da keinen Konstruktor von ImageContainer auf. Du sagst da nur, dass du ein Array erstellen möchtest, indem 5 Objekte des Types ImageContainer platz haben. Du allozierst da Speicher 😉

Du musst die noch mit ImageContainer Objekten füllen.
 
Aber wenn ich background = new Imagecontainer[5] aufrufe, dann werden doch auch die Konstruktoren von ImageContainer aufgerufen wie kann es dann null sein?

Dein Denkfehler ist das du glaubst durch "new" würden deine 5 Array-Elemente bereits initialisiert. Das ist aber falsch ! Das "new" bezieht sich hier lediglich auf das Array selbst. Deine 5 Elemente selbst sind aber immer noch NULL. Und da du dann in Zeile 64 versuchst NULL.loadImage(String) zu callen fliegt die NPE.

Du musst also deine Array noch richtig initialisieren.

Java:
for(int i=0; i<background.length; i++)
{
background[i]=new ImageContainer();
}
 
Das heißt ich muss noch eine for-schleife machen und für durchgehen und dann was aufrufen. Ich dachte immer das man mit dem Aufruf von new eben ein neues Objekt von der gewünschten Klasse erstellt. Was muss ich da machen ich steh vollkommen auf dem Schlauch.
 
"new" erzeugt auch ein neues Objekt, hier allerdings nur das Array, da Arrays in Java eher selbst wie Objekte sind als primitive zusammenhängende Speicher-Blöcke wie man es eigentlich denkt. Nur darum kannst du überhaupt "new" callen.
 
Immer dieses Antworten wenn grad eine Antwort kommt ^^. Danke jetzad kapier ich endlich wieso des nicht funktioniert weißt du zufällig in C genauso ist weil daran kann ich mich nicht erinnern. Ich komm nämlich von C und muss jetz für die Schule ein Projekt in Java machen mein Lehrer hat das Problem mit dem erstellen von Java auch schon gemacht.
Aber nochmals danke.
Muss ich jetzt davor auch das Array mit new erstellen?
 
Nun throwt er mir eine URL-Exception, Ich schließ jetzt daraus das die URL falsch oder nicht gefunden wird. Ist diese Relativ oder nicht. Also muss ich das komplette Verzeichnins angeben oder kann ich das mit "images/sunw01.jpg" erreichen. Der Ordner images befindet sich im Ordner des Verzeichnisses:
4Gewinnt/images/sunw01.jpg damit müsste es doch das image finden order nicht?
 
Wie das ganze in C abläuft weis ich nicht. Ich kenn zwar die Sprache an sich, hab mich aber nie mit befasst.
In Java läuft das ganze so ab :

Java:
Object[] objectArray=new Object[10];

Damit erstellst du ein neues Array vom Typ "Object" und der Größe "10". Allerdings NUR das Array. Das bedeutet das du nun zwar das Array mit der entsprechenden Größe hast, aber dieses an sich noch keinen Inhalt besitzt. Oder anders gesagt : jedes Elemtent hat den "Wert" NULL.
Also musst du nun erstmal das Array füllen :

Java:
for(int i=0; i<objectArray.length; i++)
{
objectArray[i]=new Object();
}

Im gegensatz zu C kann man den Zähler bei Java direkt im Loop-Header deklarieren (habe mal was gelesen das man in C das "int i=0;" vor den Loop schreiben muss weil sonst der Compiler nich klar kommt).
Mit diesem Loop befüllst du nun also das Array mit konkreten Objekten.

Es gibt allerdings eine kleine Ausnahme bei primitiven Datentypen. Das sind byte, short, char, int, float und double. Erstellst du ein Array vom Typ eines primitiven Datentypes , etwa :

Java:
int[] intArray=new int[10];

musst du dich um die Initialisierung nicht weiter kümmern da primitive Datentypen als default immer den Wert "0" haben. Das oben gesagt gilt nur bei nicht-primitiven Datentypen (also richtigen Objekten).

Hoffe das dir das eine kleine Hilfe ist.
 
Jetz versteh ichs gänzlich ;D. In C muss man es davor deklarieren in C++ kann man es genau wie in Java in die for Schleife was ich sinnvoll finde.
 
Was jetzt noch deine Exceptions angeht : man sollte IMMER in einem catch-Block [japi]Throwable#printStackTrace()[/japi] callen um die vollständige Exception zu erhalten. Einfach nur ein Syso "Fehler" ist ziemlich sinnfrei.

Es kann also sein das er entweder den Pfad nicht finden (zum Testen mal mit absolutem Pfad testen), das er Probleme hat das Package richtig zu erkennen oder das die Daten einfach in falschen Ordnern liegen. Ist alles schon mal passiert und passiert auch immer wieder. Da muss man jetzt halt ein bisschen debuggen. Am besten mal direkt vor dem Laden einfach mal die absolute URL ausgeben lassen. Dann sieht man meist schon obs stimmt oder nicht.
 
Sry war kurz weg. So mit absoulutem Pfad hab ich schon getestet und es hat nichts gebracht . Aber wo muss ich dieses printStackTrace hinschreiben damit das funktioniert oder wie funktioniert das. Was muss man dafür einbinden.
 
Hier ist die neue Ausgabe:


Code:
java.net.MalformedURLException: unknown protocol: f
	at java.net.URL.<init>(URL.java:590)
	at java.net.URL.<init>(URL.java:480)
	at java.net.URL.<init>(URL.java:429)
	at ImageContainer.loadImage(Leinwand.java:168)
	at Leinwand.<init>(Leinwand.java:68)
	at Leinwand$1.run(Leinwand.java:30)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:701)
	at java.awt.EventQueue.access$000(EventQueue.java:102)
	at java.awt.EventQueue$3.run(EventQueue.java:662)
	at java.awt.EventQueue$3.run(EventQueue.java:660)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:671)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at ImageContainer.loadImage(Leinwand.java:183)
	at Leinwand.<init>(Leinwand.java:68)
	at Leinwand$1.run(Leinwand.java:30)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:701)
	at java.awt.EventQueue.access$000(EventQueue.java:102)
	at java.awt.EventQueue$3.run(EventQueue.java:662)
	at java.awt.EventQueue$3.run(EventQueue.java:660)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:671)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
 
Java:
Image result = null;
try
			{
				result = ImageIO.read(ImageManager.class.getClassLoader().getResource("de/nj/njprogrammanager/images/" + name));
			}
			catch (IOException exception)
			{
				System.out.println(Cannot load image \"" + name + "\"");
				exception.printStackTrace();
			}

Das wäre mal ein Ausschnitt aus einem einfachen Programm. Das ganze ist in eine Methode eingebettet, damit man einfach nur den Namen der Datein angeben muss, um sie zu laden. "ImageManager" ist bei mir eine Klasse, da könntest du beispielsweise deine ImageLoader -Klasse verwenden. Anschließend musst du nur die Verzeichnishirachie anpassen, die bei mir eben "de/nj/njprogrammanager/images/" ist.
 

Neue Themen


Zurück
Oben