# JButton - Icon(.png) aus resources laden



## Hering (15. Sep 2012)

Moin,
ich hab mal wieder ne Frage:
Und zwar habe ich momentan mehrere JButtons, denen ich gerne ein Icon zuweisen würde.
Diese Icons liegen allerdings in einem anderen Ordner als das package mit meiner Klasse.

```
Klassenpfad: src\main\java\xxx\xxx\xxx\xxx\xxx\xxx\GUI\MainWindow.java
Iconpfad: src\main\resources\xxx\btnBlubb.png
```

Hier ein Beispiel wie ich momentan versuche zu laden:

```
JButton btnBlubb = new JButton("Blubb");
btnBlubb.setBounds(5, 423, 31, 32);
btnBlubb.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("btnBlubb.png"))));
contentPane.add(btnBlubb); //content pane des JFrames
```

Allerdings erhalte ich immer folgenden Error beim Laden:

```
Uncaught error fetching image:
java.lang.NullPointerException
	at sun.awt.image.URLImageSource.getConnection(Unknown Source)
	at sun.awt.image.URLImageSource.getDecoder(Unknown Source)
	at sun.awt.image.InputStreamImageSource.doFetch(Unknown Source)
	at sun.awt.image.ImageFetcher.fetchloop(Unknown Source)
	at sun.awt.image.ImageFetcher.run(Unknown Source)
```

Woran liegt das und wie kann ich das Icon richtig laden?

mfg
Hering


----------



## Kevin94 (15. Sep 2012)

Der Pfad ist falsch. Ist ja auch irgendwie logisch, dass er eine Datei die in einem vollkommen anderen Ordner liegt, als die Klasse, nicht finden kann. Richtig müsste imho folgende Pfadangabe sein:


```
/main/resources/xxx/btnBlubb.png
```


----------



## Fab1 (15. Sep 2012)

Hallo,

schau mal hier: Grafikdateien laden und anzeigen ? Byte-Welt Wiki

du kannst einfach den absoluten Pfad übergeben. Am besten einfach aus dem Explorer kopieren und anschließend Backslash mit Slash ersetzen. Dann sollte es eigentlich gehen. Wenn du eine .jar erzeugst, werden die Bilder auch geladen, wenn du folgende Methode anwendest.


```
ImageIcon icon = new ImageIcon(getClass().getResource("demo.jpg"));
JButton button = new JButton("Demo", icon);
```

Edit: 

Du könntest auch mithilfe von den Pfad raus bekommen in dem der Computer sucht. Anschließend kannst du das dann ändern. 
	
	
	
	





```
public void test() {

		File f = new File("deinPfad");
		
		System.out.println(f.getAbsolutePath());
	}
```


----------



## Hering (15. Sep 2012)

Moin, danke für die schnelen Antworten 

Mein Problem besteht leider weiterhin mit genau der gleichen Exception die geworfen wird.
Hier zur Verdeutlichung der Verzeichnisstruktur nochmal ein Bild: (Sorry für die "Zensur", aber die Namen sind nicht öffentlich)






Fixe Pfade gehen leider nicht, da das ganze ein Maven&Git Projekt ist, und auf verschiedenen Rechnern unter verschiedenen Ordnern laufen soll.

Hoffe es kann mir jemand helfen

mfg
Hering


----------



## Hering (15. Sep 2012)

So sieht das ganze in eclipse aus:


Spoiler: Hier mal ein Bild vom Pfadaufbau











mfg
Hering


----------



## ...ButAlive (15. Sep 2012)

So solltest du z.B. das btnExit.png laden können:

```
Icon icon = new ImageIcon(getClass().getResource("GUIElements/btnExit.png");
```


----------



## Hering (15. Sep 2012)

Nö, funktioniert immer noch nicht 

Mein Code momentan:

```
private void initButtons() {
		//Buttons
		JButton btnOptions = new JButton("Options");
		****
	    //Setting the size of the buttons
		btnOptions.setBounds(5, 423, 31, 32);
		****
		//Setting icons
		try {
			//Normal Icon
			loadIcon(btnOptions, "GUIElements/btnOptions.png", "Normal");
			****	
			//RollOver Icon
			loadIcon(btnOptions, "GUIElements/btnOptions_RollOver.png", "RollOver");
			****
			//Pressed Icon
			loadIcon(btnOptions, "GUIElements/btnOptions_Pressed.png", "Pressed");
			****
		} catch (Exception e) {e.printStackTrace();}
		
		//Adding buttons to contentPane
		contentPane.add(btnOptions);
        ****
	}

	private void loadIcon(JButton button, String path, String mode) {
		Icon icon = new ImageIcon(getClass().getResource(path));
		switch (mode) {
			case ("Normal"): {button.setIcon(icon);}
			case ("RollOver"): {button.setRolloverIcon(icon);}
			case ("Pressed"): {button.setPressedIcon(icon);}
		}
	}
```


----------



## Kevin94 (15. Sep 2012)

Drei Sachen:
1. Werden die Bilder überhaupt in das bin Verzeichnis kopiert? Unwahrscheinlich das nicht, aber man muss ja aller Fehlerquellen ausschliesen.
2. Aus den Class#getResource hier zu lesenden Gründen, kann es nicht gehen, da immer noch in einem Unterordner von GUI gesucht wird.
3. Hast du meinen Vorschlag schon probiert? (
	
	
	
	





```
/main/resources/GUIElements/btnXXX.png
```
)


----------



## Hering (15. Sep 2012)

Moin,

Ja die Bilder sind ins richtige Verzeichnis kopiert worden von eclipse "target/classes/GUIElements/..".
Auch den Vorschlag mit "/main/resources/GUIElements/btnXXX.png" hab ich probiert, allerdings funktioniert es dann immer noch nicht, in der Zeile "Icon icon = new ImageIcon(getClass().getResource(path));" der Methode loadIcon() tritt weiterhin eine NullPointerException auf.

mfg
Hering


----------



## Kevin94 (16. Sep 2012)

Unter falschen Annahmen können auch keine richtigen Ergebnisse entstehen. Meine Pfad ist unter folgenden Annahmen entstanden:

src/ ist der Root-Odernder des Projekts und somit die unter Ordner auch im Root eines Builds
Die Ordner /main/java und /main/resources/ sind "Packages", das sind aber die tatsächlichen Roots
Nachedem sich das als falsch herrausgestelt hat, was bei genauem hinschauen mir auch auffallen hätte können (facepalm), ist mein korigierter Tipp: 
	
	
	
	





```
/GUIElements/btnXXX.png
```


----------



## Hering (16. Sep 2012)

Moin,

OMG manchmal sieht man den Wald vor lauter Bäumen nicht...
Daran lag es wirklich! Allerdings hat sich jetzt ein weiteres Problem ergeben, und zwar wird das Bild versetzt gezeichnet. Wenn ich mit folgender Methode lade:

```
private void loadIcon(JButton button, String path, String mode) {
		Icon icon = new ImageIcon(getClass().getResource(path));		
		switch (mode) {
			case ("Normal"): {button.setIcon(icon);}
			case ("RollOver"): {button.setRolloverIcon(icon);}
			case ("Pressed"): {button.setPressedIcon(icon);}
		}
	}
```
Wird das Bild nach links versetzt gezeichnet (siehe Bild):





Auch wenn ich folgenden Code verwende um den Rand zu entfernen etc funktioniert es nicht:

```
//Method 1	
        Dimension d = new Dimension(icon.getIconWidth(), icon.getIconHeight());
		button.setPreferredSize(d);

		button.setBackground(null); 
		button.setBorder(null); 
		button.setBorderPainted(false);

        //Method 2
		button.setMargin(new Insets(0,0,0,0));
```

Was übersehe ich da?

mfg
Hering


----------



## Fab1 (16. Sep 2012)

Versuch mal 
	
	
	
	





```
deinButton.setContentAreaFilled(false);
```

Ich denke mal es liegt an deinem Icon. In welchem Format ist es?


----------



## Hering (16. Sep 2012)

Moin,
dein Vorschlag führt zwar dazu, dass kein Rahmen mehr gezeichnet wird, allerdings ist rechts von dem Button dann ein schwarzer Punkt und das Icon ist immer noch links abgeschnitten.




Die Icons liegen im 16Bit/RGB-PNG Format vor. Und sie sind in genau der gleichen Größe wie die Buttons selbst.

mfg
Hering

P.s.: Hier ist mal ein Test-Button zum runterladen: File-Upload.net - btnExit.png


----------



## Hering (16. Sep 2012)

... Moin
ich bin echt doof...
Es lag daran, dass noch Text auf dem Button stand, wenn ich den lösche klappts ohne Probleme.
Jetzt muss ich's nur noch hinkriegen, dass mein ImagePanel(erbt von JPanel) in der Lage ist sein Bild anzuzeigen ohne, dass ich erst minimieren/maximieren oder verschieben muss.
Ein einfaches repaint() scheint nicht zu funzen.
Wenn da jemnd grad ne Idee hat wäre ich wirklich dankbar, auch wenns nicht wirklich in diesen Thread gehört.

mfg
Hering


----------



## L-ectron-X (16. Sep 2012)

Beispiel:
Grafikdateien laden und anzeigen ? Byte-Welt Wiki


----------



## noobee (25. Jan 2013)

ich hab das problem, dass meine icons nicht angezeigt werden aufm button. ich habe sie über IMPORT von eclipse importieren lassen. diese sind im ordner workspace/meineprog/bin gelandet, also da wo auch die von eclipse erzeugten klassen liegen. ein einbinden  in den button über


```
meinBtn.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("test.png")))); // oder
meinBtn.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("bin/test.png")))); // oder
meinBtn.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/bin/test.png"))));
```
geht nicht. ich bekomme keinen fehler bei zeile 1, nur fehlt eben bei jedem button das bild.
bei den anderen zwei zeilen gibts ne NPE.
wo liegt da der fehler ?


----------



## L-ectron-X (25. Jan 2013)

```
meinBtn.setIcon(new ImageIcon(getClass().getResource("bin/test.png")));
```
So in der Richtung sollte gehen.
Ansonsten schau dir den Link an.


----------



## noobee (25. Jan 2013)

geht leider nicht  immer nullpointerexception
nützt auch nix, mal den komplette pfad anzugeben, auch da NPE


----------



## L-ectron-X (26. Jan 2013)

Der Pfad war auch nur als Beispiel gedacht. Du bekommst die NPE, weil das Bild nicht am angegebenen Ort liegt.
Wo liegt dein Bild und wo die Klasse, in der du diesen Code schreibst? Schreibe mal die Pfade auf, oder mach mal ein Bild von den Pfaden, wie das Hering oben gemacht hat.


----------



## Dekker (26. Jan 2013)

Drauf achten das keine Leerzeichen im Pfad sind. Java mag das nicht.


----------



## noobee (26. Jan 2013)

es waren die leerzeichen -.- hab die ordner umbenannt und es so gemacht:


```
ImageIcon icon = new ImageIcon("xxx/xxx/bin/test.png");
JButton btnNewButton = new JButton("TestButton", icon);
```

jetzt gehts wunderbar  DANKÖÖÖ


----------



## L-ectron-X (26. Jan 2013)

Nun müssen die Bilder aber auf jedem Rechner, der dein Programm ausführt an den angegebenen Verzeichnissen liegen.
Normalerweise legt man die Bilder mit in der Jar-Datei ab und referenziert sie, wie ich das oben gezeigt habe.


----------



## noobee (26. Jan 2013)

jupp, das ist der fall  liegen auf jedem rechner im gleichen verzeichnis. das machts für mich einfacher


----------



## L-ectron-X (26. Jan 2013)

...ist aber schlechter zu warten, ist unflexibel und unprofessionell.


----------

