Bild einfügen bei JAVA

Racerin

Grünschnabel
Hallo,

ich habe mir diverse Erklärungen durchgelesen, wie man ein Bild (JPEG) bei Java einfügt. Allerdings verstehe ich diese nicht richtig.

Man verwendet
g.drawImage
oder ist das falsch?
Dann weiß ich allerdings nicht, wie ich den Pfad angeben soll.
Es wäre echt total lieb, wenn mir jemand helfen könnte.

Liebe Grüße
 

Kai008

Erfahrenes Mitglied
Man könnte die Paint verwenden.
Die meisten fügen es aber einen Label o. ä. als Icon hinzu und plazieren das. Weiß aber nicht warum, Paint ist doch viel einfacher und imho auch übersichtlicher.

Bild musst du in Image-Variable laden.
Dazu verwendet man entweder ImageIO oder JFrame.getToolkit.getImage();
ImageIO hat ne Throw, aber für dem Toolkit braucht man halt immer einen Komponenten. Außerdem besteht ein Unterschied, wann genau die Bilder geladen werden. Ich denke bei ImageIO werden sie erst geladen wenn sie gebraucht werden, musst du aber nachlesen, bin mir nicht sicher. Ich verwende prinzipiell nur ImageIO.read(new File("Datei.jpg"));

Wenn das Bild z. B. "img\race.jpg" ist, schaut das ganze dann so aus:

Java:
BufferedImage image = null; //Deklariere ein Image (BufferedImage ist auch eins), lasse es aber auf NICHTS verweißen. NIEMALS in dem Zustand zugreifen.
try
{
	image = ImageIO.read(new File("img\\race.jpg")); //Schreibe in image das Bild. try ist nötig, da ImageIO eine Exception wirft. Von nun an ist image nicht mehr 'null' und es kann darauf zugegriffen werden. Backslash muss Espaped werden!
}
catch(Exception e)
{
	e.printStackTrace(); //Schlägt das laden fehl (z. B. Datei wurde nicht gefunden) gebe den StackTrace aus. Das ist eine Liste mit den vor geraumer Zeit aufgerufenen Methoden. Denke daran dass image noch immer 'null' ist.
}

Im Grunde sieht das dann in der Paint so aus:

Java:
public void paint(Graphics g)
{
	BufferStrategie bs = this.getBufferStrategie(); //Hohle die BufferStrategie
	if(bs == null) //Gibt es keine...
	{
		if(this.isVisible()) //...und ist das Frame, JFrame, Applet o.w.a.i sichtbar...
			this.createBufferStrategie(2); //...erstelle eine mit 2 Buffern...
		return;//...und brich ab
	}
	Graphics realG = bs.getDrawGraphics(); //Hohle die Graphics, die auch tatsächlich verwendet werden wird.

	BufferedImage image = null; //s. o., sollte wenn möglich nur einmal und schon garnicht in der eh schon zeitkritischen Paint passieren. ^^
	try
	{
		image = ImageIO.read(new File("img\\race.jpg"));
	}
	catch(Exception e)
	{
		return;
	}
	//Beginn of drawing
	realG.drawImage(image, 0, 0, this); //Zeichne das Bild im Buffer. Parm. 1 und 2 sind die x/y-Koordinaten, Parm 3 ist der ImageObserve, i. d. R. das Frame, JFrame, Applet o. w. a. i.
	//End of drawing
	realG.dispose(); //Gib alle Ressourcen wieder frei.
	bs.show(); //Zeige nun endlich den Inhalt des Buffers an.
}

Ich hoffe das war ein wenig verständlich. Viel Glück noch.
Ach ja, für Fehler wird keine Haftung übernommen, habe das schnell in der Textarea zusammengeschrieben.
 
Zuletzt bearbeitet:

Racerin

Grünschnabel
Vielen Dank für die schnell Antwort!
Leider sind einige Begriffe, wie try und catch völlig fremd, sodass ich das Programm leider nicht nachvollziehen kann.
Ich habe bis jetzt eigentlich nur von Java die objektorientierte Programmierung kennen gelernt.
Gibt es dennoch einfachere Möglichkeiten ein Bild einzufügen?

Liebe Grüße
 

Kai008

Erfahrenes Mitglied
Wie ich schon sagte:
this.getToolkit().getImage("link zum Bild");
Damit lädst du dann aber ein Image.
Try/Catch ist ganz einfach: Wird wärend des Aufrufes von try eine Exception geworfen, wird abgebrochen und in der jeweiligen catch() weitergemacht. Das danach gibt an, welche Exception behandelt wird, "Exception" selbst ist auch die Superklasse aller anderen Exc., deshalb werden alle behandelt.
 

zerix

Hausmeister
Moderator
@Kai008
Die meisten fügen es aber einen Label o. ä. als Icon hinzu und plazieren das. Weiß aber nicht warum, Paint ist doch viel einfacher und imho auch übersichtlicher.

Es kommt drauf an, wofür man das Bild braucht. Als Icon bei einer GUI-Komponente, die mit einem LayoutManager positioniert wird, wäre es wohl einfacher ein JLabel zu nehmen.

Meiner Meinung nach ist es nicht einfacher die Paint-Methode zu überschreiben, um eine Bild darzustellen. Warum es übersichtlicher sein soll, verstehe ich auch nicht ganz.


Code:
ImageIcon bild = new ImageIcon(/*Pfad zum Bild*/);
JLabel label = new JLabel(bild);

//Jetzt muss man nur noch das JLabel der Komponente hinzufügen, auf der man das Bild möchte.

Wie gesagt, ich weiß nicht, was an den zwei Zeilen nicht übersichtlich sein soll.


@Racerin
Ich würde dir Vorschlagen, dass du dich erstmal mit den Grundlagen von Java beschäftigst, bevor du dich darum kümmerst wie man ein Bild anzeigt.
Try/Catch gehören zu den grundlegendsten Sachen in Java wie Schleifen oder auch if/else. Sowas sollte man schon kennen.

MFG

Sascha
 

Kai008

Erfahrenes Mitglied
Ich meinte eh Programme die nur zeichnen. Wenn ich Component-Subklassen verwende nutze ich natürlich auch selbst JLabels.

Aber man muss ja erst Position setzen:
Java:
setBounds(x, y, breite, hoehe);
Bei Paint benötigt man keine Größenangaben.
Und dann halt noch add();
Also hat man im Endeffekt:

Java:
SomeObj sOj = this.getSomeObj();
JLabel label = new JLabel(sOj.getIcon());
label.setBounds(0, 0, 10, 10);
jframe.add(label);

Bei Paint:

Java:
SomeObj sOj = this.getSomeObj();
g.drawImage(sOj.getImage, sOb.getX(), sOb.getY(), this);

Zudem zeichnen die meisten User von JLabel's noch nicht direkt auf das JFrame sondern klatschen es vorher auf ein JPanel. Ich weiß nicht warum, ist wohl eine Art Doppelbuffer. Da afaik neue Swing-Komponenten unter dem Vorherigen dazugefügt werden, müssen nicht nur verkehrt damit gezeichnet werden (Background als letztes usw.), sondern das alte JPanel später noch entfernt werden. Finde ich viel komplizierter als einfach alles direkt auf was draufzuzeichnen.

Ich hoffe das ist jetzt alles soweit richtig, habs ein paar mal zum testen soeinen Zeichenvorgang gebastelt, fand aber wie gesagt alles viel zu kompliziert.

btw. Zwar braucht man natürlich schon die Grundlagen, aber ich denke dass es einfacher ist mit einem Projekt zu arbeiten, wenn man etwas sieht. Vor allem als Anfänger(in?). Aber ich habe als Anfänger immer alles gethrowt, bis ich mit Threads angefangen habe, danach alle Try/Catch einfach in andere Methoden ausgelagert.

Na ja, ist nur meine Meinung. Natürlich bin ich selbst bei weiten nicht so gut wie du, deshalb erwarte ich gespannt deine Antwort. :)
 

zerix

Hausmeister
Moderator
Man muss nur eine Größe setzen, wenn man keinen LayoutManager verwendet. Es sei denn man möchte eine andere Größe. Dann muss man sie aber in paint auch setzen.

Je nachdem welchen LayoutManager man verwendet, müssen auch keine Positionsangaben gemacht werden.

Ich sagte ja auch, dass es auf den Anwendungsfall ankommt. Es gibt Anwendungsfälle da überschreibt man besser die paint-Methode. Dann gibt es Anwendungsfälle da nimmt man besser ein ImageIcon und ein JLabel.

Ich bin der Meinung, dass es mit einem JLabel für einen Anfänger leichter zu verstehen ist, als das überschreiben der paint-Methode.


Zwar braucht man natürlich schon die Grundlagen, aber ich denke dass es einfacher ist mit einem Projekt zu arbeiten, wenn man etwas sieht.

Meiner Meinung nach sollte man die grundlegenden Elemente einer Programmiersprache kennen, bevor man mit einem Projekt beginnt.
Dinge wie if/else, Schleifen, try/catch usw sollten schon bekannt sein, bevor man mit einem Projekt beginnt.
Das wäre das gleiche, wenn man einen Brief auf dem PC schreiben möchte und nicht mal weiß, wie der PC eingeschaltet wird.

Wenn man sich beispielsweise in GUI-Programmierung einarbeiten möchte, dann kann man sich ein Projekt ausdenken.

MFG

Sascha