# Image in jar einbauen



## wyldstyle (10. Apr 2010)

Hallo, ich hätte eine (wahrscheinlich recht simple) Frage:

Angenommen ich hätte folgende Struktur:

/bin
klassendateien
/bin/images
bilddateien

jetzt erzeuge ich aus meinem projekt eine ausführbare jardatei, diese funktioniert aber nicht korrekt denn das bild wird nicht gefunden, beim testen in eclipse funktioniert alles reibungslos.

Ich habe die Grafik folgenderweise eingebunden:

```
java.net.URL imageURL = GUI.class.getResource("images/background.png");
		ImageIcon icon = new ImageIcon(imageURL);
```

Kann mir jemand sagen wie ich das Unterverzeichnis mit einbinde in die jardatei, oder geht das auf dem obigen wege so nicht!?


zweite Frage:

Nehmen wir an ich habe ein Frame größe 800x600(standartmäßig beim start) und ein hintergrundbild(auf dem frame) mit 1920x1200
fall1:
starte ich jetzt das programm wird nur ein ausschnitt der grafik angezeigt bis das fenster eben 1920x1200 ist.
fall2:
ich starte das programm in 800x600 und habe eine grafik 800x600 auf dem frame -> maximiere ich jetzt das fenster, skaliert die grafik halt nicht mit.

Wie bekomme ich die grafik dazu mit der fensetrgröße zu skalieren? brauche ich für jede auflösung n eigenes bild oder vektorgrafiken!?


----------



## XHelp (11. Apr 2010)

Vllt klappt ja

```
GUI.class.getClassLoader().getResource("bin/images/background.png")
```

Zu der 2. Frage: wie machst du denn das Bild auf dein Frame?


----------



## wyldstyle (11. Apr 2010)

funktioniert leider so nicht!

2tens: Ich hatte die Grafik auf ein Jlabel gepackt, da ich nicht wusste wie ich das anders machen soll. am liebsten (logisch betrachtet) wäres es mir wenn ichd as ding direkt auf den ganzen frame klatschen könnte aber bisher sind alle Versuche fehlgeschlagen!


----------



## XHelp (11. Apr 2010)

Hm. Ich habe gerade meinen Vorschlag ausprobiert (package bin und bin.image) und das klappt, auch in einer jar.

Du kannst ja von einem JPanel ableiten und paintComponent überschreiben. Da malst du das Bild, und zwar skaliert auf die Panelgröße. Wenn sich nun deine Framegröße ändert, dann ändert sich auch die Panelgröße und paintComponent wird aufgerufen. Dann malst du quasi immer automatisch ein skaliertes Bild.


----------



## wyldstyle (11. Apr 2010)

Hallo nochmal XHelp, ich denke das stellt mich vor ein kleines Problem - ich erbe schon von JFrame und kann doch nur von einer Klasse direkt erben (kein Interface)?

Ich poste einfach mal meine Guicode rein, vielleicht ist da ja irgend ein Logikfehler drin:


```
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class GUI extends JFrame implements ActionListener, WindowListener {
	
	private String name = "";
	private short playercount = 0;
	private long money = 0;
	private long smallblind = 0;
	private long bigblind = 0;
	
	
	GUI(String name,short playercount, long money, long smallblind, long bigblind){
		
		this.name = name;
		this.playercount = playercount;
		this.money = money;
		this.smallblind = smallblind;
		this.bigblind = bigblind;
		java.net.URL imageURL = GUI.class.getResource("images/background.png");
		ImageIcon icon = new ImageIcon(imageURL);
		icon.setImage(icon.getImage().getScaledInstance(1980,1200, Image.SCALE_FAST));
		
		setTitle("Texas Code'em");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setResizable(true);
		
		getContentPane().setBackground(Color.green);
		JLabel test = new JLabel(icon);
		getContentPane().add(test);
		
		
		
		
		
	}  
	 

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosed(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosing(WindowEvent arg0) {
		System.exit(0);
		
		
	}

	@Override
	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowOpened(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

}
```


----------



## XHelp (11. Apr 2010)

Dass du nur von einer Klasse ableiten kannst, hast du recht. Aber du kannst ja auch 2 Klassen erstellen:

```
private class BGPanel extends JPanel {
		private Image image;

		public BGPanel(Image image) {
			super();
			this.image = image;
		}

		@Override
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
		}

	}
```

anstatt jetzt JLabel auf Frame zu packen, machst du:

```
BGPanel test = new BGPanel((new ImageIcon(MainFrame.class.getClassLoader().getResource("bin/images/chuck.png")).getImage()));
getContentPane().add(test);
```

Alle anderen Componenten fügst du dem BGPanel hinzu.


----------



## Ein Keks (11. Apr 2010)

kleine neben-info:
Bei 
	
	
	
	





```
class.getRessource(...)
```
 ist der Pfad relativ zur Klasse, bei 
	
	
	
	





```
class.getClassLoader().getRessource()
```
 hingegen der absolute Pfad in der Jar (also wenn die datei im package data liegt und Blubb.gif heißt: "data/blubb.gif")  bzw. vom Classpath aus


----------



## wyldstyle (11. Apr 2010)

Oh Klasse, das funktioniert genauso wie ich das wollte - zumindest in eclipse.

Beim exportieren hab ich immernoch den Fehler, dass die Quelldatei vom Bild nicht erkannt wird. ich hab die grafik aus scpass in jedes verzeichnis des projektes kopiert...aber finden tut er immernoch nix! woran könnte das noch liegen?


----------



## XHelp (11. Apr 2010)

Guck mal in die jar rein, ist da auch das Bild definitiv drin?


----------



## wyldstyle (11. Apr 2010)

ok da liegt das problem, kein bild drin - aber wieso exportiert eclipse das nicht mit!?


----------



## XHelp (11. Apr 2010)

Gegenfrage: wie exportierst du denn?
File > Export > Runnable JAR File > (richtige Konfiguration) + extrackt libraries?

Weiß es leider nicht von Eclipse, aber Hudson ingoriert z.B. Resourcen in normales Packages.


----------



## wyldstyle (12. Apr 2010)

Ja eigentlich genauso:

File > Export > Runnable JAR  File > "Extract required libraries into generated jar" > Finish

hab alle optionen da ausprobiert - aber das image wird nie eingebunden. hab das jetzt manuell eingefügt - das dürfte auf lange sicht aber keine option sein. Zumindest weiss ich jetzt wo das Problem liegt, danke vielmals für deine aufopfernde Hilfe!


----------



## Amios (17. Jan 2011)

Ich habe das selbe Problem, finde jedoch keine Lösung.

Ich habe mir ein Jarfile angelegt. Doch wenn ich dieses ausführe, findet er die benötigtene Bilder nicht.
Ich habe das File untersucht und die Bilder sind in diesem vorhanden.

Die Verzeichnisstruktur sieht wie folgt aus


```
- src
- Guis
| - playerGui
   | - PlayerGui.java
| + LoginGui
- Images
| - icon.gif
```

mein Code zum laden des icons, sieht wie folgt aus:

```
guiframe = new JFrame("IViRnN: ServerBrowser");
guiframe.setIconImage(new ImageIcon("./Images/icon.gif").getImage());
```

dies Funktioniert auch unter Eclipse.
Wenn ich das Project jedoch als Jar-file exportiere findet er den Pfad zum Image nicht mehr.
Ich habe nun schon diverse Mechanismen versucht.
Selbst

```
PlayerGui.class.getResource("./Images/icon.gif");
```
liefert "null" zurück.
wie kann ich das bild sowohl im Jar als auch im offenen Projekt laden?

bzw. gibt es eine Möglichkeit mir anzeigen zu lassen, in welchem Pfad gerade gesucht wird?


----------



## L-ectron-X (17. Jan 2011)

ClientGui taucht in deinem Dateibaum nicht auf, so kann man dir kaum helfen...


----------



## Amios (17. Jan 2011)

stimmt, habe mich vertippert. Nun ist es behoben.


----------



## L-ectron-X (17. Jan 2011)

Versuch mal

```
PlayerGui.class.getResource("../Images/icon.gif");
```


----------



## Amios (17. Jan 2011)

Er findet leider das Bild nicht. Ich vermute mal, dass das Image im JAR-file nicht den selben Pfad hat, wie im eclipse.


----------



## Grey_M (17. Jan 2011)

Also ich benutze in meinem Programm folgenden Pfad.

```
ImageIO.read(MonitoringFrame.class.getResourceAsStream("/images/icon.gif"))
```
Wenn ich die Jar Datei öffne, dann ist der Ordner images direkt zu sehen, also in der obersten Ebene


----------



## Amios (18. Jan 2011)

Grey_M hat gesagt.:


> Also ich benutze in meinem Programm folgenden Pfad.
> 
> ```
> ImageIO.read(MonitoringFrame.class.getResourceAsStream("/images/icon.gif"))
> ...



Funktioniert das bei dir sowohl in der Entwicklungsumgebung als auch in der Jar?


----------



## Grey_M (18. Jan 2011)

> Funktioniert das bei dir sowohl in der Entwicklungsumgebung als auch in der Jar?



Ja. Kannst dir ja mal hier im Forum unter Codeschnippsel den AnalyseSleeper anschauen. Da habe ich das verwendet.

das einzige was mir mal aufgefallen ist, die Methode von der aus 
	
	
	
	





```
MonitoringFrame.class.getResourceAsStream...
```
 aufgerufen wird darf nicht statisch sein. Ich musste bei mir von der Klasse ein Objekt erzeugen und darüber dann die Methode aufrufen.


----------



## Amios (21. Jan 2011)

erstmal Danke Grey_M für deine Hilfe.
Ich habe inzwischen das Problem gefunden und behoben.
Der Grund, warum die Bilder entweder nur in der Jar, oder nur in der Entwicklungsumgebung gefunden wurde war: Nicht alle Quellen lagen im src-folder von Eclipse. Ich vermute mal, da das Projekt ziemlich groß ist, dass es zur Übersichtlichkeit dienen soll. Da aus dem src beim kompilieren die kompilierten Files ins bin geschrieben werden, wird beim ausführen auch diese Ordnerstruktur gewählt. D.H. die Bilder müssen dann auch relativ zum class-file liegen. Bei der Jar verhällt es sich jedoch anders, da dort eine Andere Ordnerstruktur generiert wird. Um eine identische Ordnerstruktur zu bewerkstelligen, müssen die Quellordner, die nicht im src liegen mit in den Buildpath aufgenommen werden. Dann klappt es auch mit der Jar.

Danke nochmals, dass du mich auf die Ordnerstruktur aufmerksam gemacht hast


----------

