Swing Image zur Laufzeit verändern

lala84

Mitglied
Hallo,

ich sitze jetzt Stunden vor einem vermeintlich kleinen Problem :/

Ich habe folgende Ausgangssituation:
Ein Programm mit mehrere Buttons und Textfeldern und ein Bild.
Dieses Bild soll am Anfang normal initialisiert werden, und abhängig von der Nutzereingabe soll das Bild sich entsprechend ändern. Ich habe dieses Problem leider nicht auf Anhieb lösen können ( unter c++ gab es hierfür repaint Methoden).
Ich hab mal ein lauffähige GUI angehängt, und ich hoffe mal, dass ihr mir damit weiterhelfen könnt.

Wichtig ist mir auch die Tatsache, dass man BufferedImage verwendet, da das Bild unter Umständen auch verändert werden soll.

Java:
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

public class Gui extends JFrame implements ActionListener {
	private static final long serialVersionUID = 1L;
	JLabel label;
	BufferedImage bufferedimage;
	JButton button;
	String url;

	public Gui() {
		GridBagLayout layout = new GridBagLayout();
		this.setLayout(layout);
		int x, y, breite, hoehe;
		breite = 1000;
		hoehe = 500;
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		x = (screen.width - getPreferredSize().width - breite) / 2;
		y = (screen.height - getPreferredSize().height - hoehe) / 2;
		this.setBounds(x, y, breite, hoehe);
		this.initWindow();
		setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	protected void initWindow() {
		button = new JButton("Do it");
		button.setBounds(300, 0, 30, 30);
		button.addActionListener(this);
		this.getContentPane().add(button);
		this.bild();
		this.pack();
	}

	public void bild() {
		try {
			url = "http://www.java-forum.org/images/misc/java_forum_org.gif";
			bufferedimage = ImageIO.read(new URL(url));
		} catch (IOException e) {
			e.printStackTrace();
		}
		label = new JLabel(new ImageIcon(bufferedimage));
		label.setBounds(0, 0, 256, 256);
		this.getContentPane().add(label);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == button) {
			try {
				url="http://www.java-forum.org/images/buttons/unmarked.gif";
				bufferedimage = ImageIO.read(new URL(url)); //sollte eingentlich nicht nütig sein wenn ich url verändere?!
			} catch (MalformedURLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			System.out.println("Button gedrückt");
			System.out.println("Aktuelle Url ist: " + url);
		}
	}
}

Und hier die Main
Java:
public class main {

	public static void main(String[] args) {
		Gui gui;
		gui = new Gui();
	}
}

Also wie gesagt, das Problem ist das Ändern des Bildes wenn das Programm schon läuft.
Ich würd mich wirklich sehr über Hilfe oder Ratschläge freuen.

Danke im Voraus.
mfg
 
Ja, nicht ganz. Wenn man die URL ändert, bekommt das bufferedImage davon nichts mit, und wenn man das BufferedImage ändert, bekommt das ImageIcon davon nichts mit. Entweder das ImageIcon entfernen und ein neues (mit den neuen BufferedImage) hinzufügen, oder das neue BufferedImage laden und in das alte reinmalen (dann passt sich aber die Größe nicht an).
 
Am einfachsten wäre wohl, nach der
Code:
 bufferedimage = ImageIO.read(new URL(url)); //sollte eingentlich nicht nütig sein wenn ich url verändere?!
sowas zu machen wie
Code:
label.setIcon(new ImageIcon(bufferedImage));
 
Danke euch beiden für die schnellen Antworten.
So wie es Marco13 beschrieben hat, funktioniert es auch.

Nochmal zum Verständnis: Lege ich dadurch ein neues Objekt im Speicher an ohne das alte zu löschen?
 
Ja, ich hätte auch editieren können 😳

Durch
bufferedimage = ImageIO.read(new URL(url))
wird ein neues BufferedImage erstellt. Das alte schnappt sich früher oder später der Garbage Collector. Was meinst du genau?
 
Ja, ich hätte auch editieren können 😳

Durch
bufferedimage = ImageIO.read(new URL(url))
wird ein neues BufferedImage erstellt. Das alte schnappt sich früher oder später der Garbage Collector. Was meinst du genau?

So hatte ich es mir auch gedacht, jedoch wird das alte BufferedImage anscheinend nicht gelöscht.
Bei größeren/mehreren zu ladenden Bildern dauert es 10-15sek alle Bilder zu laden. Wurden diese aber schon einmal vorher geladen, geht die Prozedur ohne/mit minimaler Wartezeit (getestet mit 100+ url und entsprechend so vielen Bufferedimages)

Und danke nochmal für die Hilfe
 

Zurück
Oben