Ein Bild mit dynamischer Quelle neuzeichnen

Stuck1A

Mitglied
Hallo zusammen,

derzeit arbeite ich mich in Java ein. Ursprünglich komme ich aus der Ecke Pascal/Basic. Nach dem lernen der Syntax habe ich mich an erste Projekte gewagt. Aktuell scheitere ich jedoch kläglich an einem im Grunde ziemlich trivialen Problem (zumindest wäre das Vorhaben in Pascal mit wenigen Codezeilen gelöst).
Folgende Funktion möchte ich umsetzen:
In einer GUI-Anwendung liegt ein JPanel, auf welchem diverse Bilder aus einer jeweils eigenen Datei gezeichnet werden sollen. Das aktuell im JPanel anzuzeigende Bild soll (später) aus einer ComboBox ausgewählt werden können. Daher möchte ich eine Methode umsetzen, welche das ausgewählte Bild aus einem hinterlegten Pfad lädt und auf das JPanel zeichnet (also das alte Bild überzeichnet).

Nach einigen Fehlversuchen bin ich zu dem Schluss gekommen, das es scheinbar nicht ausreicht, beim Laden eines neuen Bildes dieses lediglich auf ein neues Graphics-Objekt zu zeichnen und dieses dann dem immer gleichen JPanel zum neu zeichnen zu übergeben. Zumindest ist es an der Einschränkung gescheitert, das der Zeichenvorgang während der Objekterzeugung via JPanel:paintComponent() stattfinden muss.
Also ist mein neuer Ansatz, jeweils ein neues JPanel zu erzeugen, über dem alten zu positionieren und das alte dem Garbage Collector zum Fraß vorzuwerfen.
Das kommt mir zwar relativ ineffezient vor, aber nun gut.

Hier mein aktueller Ansatz als Code:

Java:
package ZeichnungsTest;

import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;


public class ZeichnungsTest extends JFrame
  {
  public static ZeichnungsTest zeichnungsTest;
 
 
  public static void main(String[] args)
    {
    zeichnungsTest = new ZeichnungsTest("Zeichnung per Methode aktualisieren - Codesnippet");
    
    // Vorschaubild 1 erzeugen
    erzeugeNeuesVorschaubild("H:/playground/water01.bmp", 10, 10);
        
    // Vorschaubild 2 erzeugen
    erzeugeNeuesVorschaubild("H:/playground/water02.bmp", 10, 50);
    }
  
 
  public ZeichnungsTest(String title)
    {
    super(title);
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setSize(800, 600);
    setLocationRelativeTo(null);
    setVisible(true);
    }
 
 
  private static void erzeugeNeuesVorschaubild(String dateipfad, int x, int y)
    {
    // Neues Vorschaubild-Panel erzeugen
    Vorschaubild vorschaubild = new Vorschaubild(dateipfad);
    
    // Das Vorschaubild-Panel in das Formular-Objekt aufnehmen
    zeichnungsTest.add(vorschaubild);
    
    // Das Vorschaubild-Panel an die übergebene Position setzen
    vorschaubild.setPosition(x, y);
    
    // Die Größe des Vorschaubild-Panels auf die Größe der Bilddatei einpassen   
    vorschaubild.setPreferredSize(new Dimension(vorschaubild.bild.getHeight(), vorschaubild.bild.getWidth()));
    vorschaubild.setMinimumSize(new Dimension(vorschaubild.bild.getHeight(), vorschaubild.bild.getWidth()));
    vorschaubild.setMaximumSize(new Dimension(vorschaubild.bild.getHeight(), vorschaubild.bild.getWidth()));
    
    // Die Zeichnungsgrenzen des Vorschaubild-Panel auf die Größe der Bilddatei einpassen
    vorschaubild.setBounds(0, 0, vorschaubild.bild.getWidth(), vorschaubild.bild.getHeight());   
    
    // In Dauerschleife das neue Bild zeichnen (ohne Schleife würde es direkt überzeichnet werden)
    while (true)
      vorschaubild.zeichneBild();    // TODO In eigenen Thread verlegen, damit Interpreter weiterarbeiten kann   
    }

  }



class Vorschaubild extends JPanel
  {
  public BufferedImage bild;
  private int x;
  private int y;


  public Vorschaubild(String pfad)
    {
    try
      {
      bild = ImageIO.read(new FileInputStream(new File(pfad)));
      }
    
    catch (IOException e)
      {
      System.out.println("Datei konnte nicht geladen werden.");
      e.printStackTrace();
      }
    }


  public void setPosition(int x, int y)
    {
    this.x = x;
    this.y = y;
    }


  public void zeichneBild()
    {
    Graphics g = getGraphics();
    g.drawImage(bild, x, y, null);
    }
 
  }
Leider funktioniert das Ganze hinten und vorne noch nicht so, wie ich mir das vorstelle.
Es fängt schon damit an, das ich das Bild dauernd neuzeichnen muss, damit es zur Laufzeit nicht augenblicklich wieder verschwindet (überpainted vom Frame?). Daher auch die Dauerschleife. Durch die arbeitet die JVM natürlich nicht weiter, wodurch das zweite Bild logischerweise gar nie erscheint. Ein Thread würde das zwar lösen, aber es kann doch nicht richtig sein, das jedes Bild in Dauerschleife von der JVM neu gezeichnet werden muss, obwohl sich der zugrunde liegende Frame nicht ändert?!
Ferner funktioniert der obige Code derzeit nur, wenn ich das Bild relativ weit oben links zeichnen lasse (etwa x,y < 20 px) und skaliert sich etwas größer, sobald ich den JFrame mit der Maus größer oder kleiner ziehe. Hängt das womöglich mit den Bounds des JPanels zu tun?

Über jegliche Hilfe wäre ich sehr dankbar!

Beste Grüße,
Stuck1A
 

mihe7

Top Contributor
Hi,

der Code ist insgesamt stark verbesserungswürdig. Erstens: kein static abgesehen bei main(). Zweitens: Du brauchst JFrame nicht zu erweitern, denn am Verhalten von JFrame änderst Du nichts. Drittens: verwende um Gottes Willen einen LayoutManager, absolute Positionierung braucht man nur in ganz wenigen Ausnahmefällen. Viertens:

Zumindest ist es an der Einschränkung gescheitert, das der Zeichenvorgang während der Objekterzeugung via JPanel:paintComponent() stattfinden muss.
Warum machst Du es denn dann nicht dort?!? Die while-Schleife brauchst Du jedenfalls nicht.
 

Stuck1A

Mitglied
Danke für die Antworten

kein static abgesehen bei main()
verwende um Gottes Willen einen LayoutManager, absolute Positionierung braucht man nur in ganz wenigen Ausnahmefällen.
Du brauchst JFrame nicht zu erweitern, denn am Verhalten von JFrame änderst Du nichts
Die Klasse ist nur ein KSKB für die Fehlersuche. Der Einfachheit halber, habe ich statisch gearbeitet und keinen LayoutManager implementiert, um den Code möglichst kompakt und übersichtlich zu halten. Im ursprünglichen Projekt sieht das anderst aus. Das erweitern von JFrame ist noch ein Überbleibsel aus verschiedenen Versuchen.


Warum machst Du es denn dann nicht dort?!? Die while-Schleife brauchst Du jedenfalls nicht.
Weil ich es auf dem Weg leider nicht umgesetzt bekommen habe. Die ursprüngliche Idee war ja, das ich ein einziges JPanel-Objekt habe, das an fester Position auf dem Frame liegt und zu verschiedenen Zeitpunkten ein neues Bild aus einem neuen Quellpfad erhält.
 

Stuck1A

Mitglied
Die habe ich selbstverständlich schon durchwühlt. Das hat mich soweit gebracht, das der obere Code entstand (Davor habe ich mich noch in keinster Weiße mit GUI-Objekten unter Java beschäftigt). Ich denke jedoch, das hier ein grundsätzliches Verständnisproblem vorliegt bzw die komplette Herangehensweise unzweckmäßig ist. Deshalb hoffe ich jetzt auf menschliche statt lexikalische Hilfe.
 

Stuck1A

Mitglied
Willst du ein Panel über ein Panel legen, oder soll das neue Bild das Alte ersetzen?
Am liebsten wäre es mir, wenn das neue Bild einfach das alte ersetzt.
Mein Versuch dazu hatte jedoch nicht funktioniert. Da war mein Ansatz, ein neues Graphics-Objekt zu erzeugen, auf dem das neue Bild zu zeichnen und damit die paintComponent-Methode aufzurufen.

Deshalb hatte ich den neuen Ansatz, jedesmal wenn sich das Bild ändert, ein neues Panel zu verwenden. Das ist der Ansatz aus dem geposteten KSKB.


Beste Grüße,
Stuck1A
 

mihe7

Top Contributor
Weil ich es auf dem Weg leider nicht umgesetzt bekommen habe.
Ersetze mal:
Java:
public void zeichneBild() {
    Graphics g = getGraphics();
    g.drawImage(bild, x, y, null);
}
durch
Java:
@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(bild, x, y, null);
}
 

Stuck1A

Mitglied
Ersetze mal:
Java:
public void zeichneBild() {
    Graphics g = getGraphics();
    g.drawImage(bild, x, y, null);
}
durch
Java:
@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(bild, x, y, null);
}
Okay, damit konnte ich mich jetzt tatsächlich der Schleife entledigen, danke für die Hilfe.
Für den Aufruf bin ich dann auf die repaint() ausgewichen, da die kein Graphics-Objekt verlangt.
Wieso funktioniert das denn nun, ohne jemals ein Graphics-Objekt zu erzeugen?

Die Bilder werden jetzt allerdings erst angezeigt, wenn ich die Fenstergröße zur Laufzeit mit der Maus verändere. Liegt wohl am fehlenden LayoutManager, oder?
Werde jetzt mal testen das ganze im Projekt umzusetzen, da ist einer dabei.

Und ist es eigentlich sinnvoll für solche Aufgaben ein JPanel statt einem Canvas zu nehmen?
 

Stuck1A

Mitglied
Ich muss doch noch mal nachhacken: du willst eine Auswahlliste oder eine Combobox haben? Soll dann das gerade gewählte Bild, ganz gleich woher, im Fenster gezeichnet werden? Ist es richtig? Oder soll jeweils ein neues Fenster (FileChooser) benutzt werden?
Also, im ursprünglichen Projekt wird zunächst über einen FileChooser ein Verzeichnispfad ausgewählt. In einer ComboBox werden dann alle Bilder aus dem Verzeichnis aufgelistet und das erste Bild direkt in einem Vorschaubild angezeigt. Sobald der Nutzer in der ComboBox ein anderes Bild auswählt, soll das Vorschaubild entsprechend aktualisiert werden.
 

mihe7

Top Contributor
Für den Aufruf bin ich dann auf die repaint() ausgewichen, da die kein Graphics-Objekt verlangt.
Wieso funktioniert das denn nun, ohne jemals ein Graphics-Objekt zu erzeugen?
Das Graphics-Objekt wird schon erzeugt, nur nicht von Dir. Das erledigt das Framework für Dich, genauso wie den Aufruf von paint(), in dessen Folge dann auch paintComponent aufgerufen wird.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Athro-Hiro Weißes Bild in Java erstellen Java Basics - Anfänger-Themen 3
V Bild per Java Script austauschen Java Basics - Anfänger-Themen 7
I Bild richtig speichern / Hochkant im File Explorer, nach Upload vertikal Java Basics - Anfänger-Themen 9
B Bild per KeyListener drehen Java Basics - Anfänger-Themen 1
I Kamera anschließen / Bild machen / Live View / Externe Blitz Java Basics - Anfänger-Themen 19
I Innerhalb einem Bild ein Teil austauschen Java Basics - Anfänger-Themen 26
I Datei (Bild) Drucken und wie Druckeinstellung speichern? Java Basics - Anfänger-Themen 3
krgewb byte-Array, das ein Bild repräsentiert Java Basics - Anfänger-Themen 1
H Artefact mit Bild erzeugen Java Basics - Anfänger-Themen 11
R UML-Bild (Erkennung ob static o. nicht) Java Basics - Anfänger-Themen 18
J Bild auf Hintergrundbild zeichnen Java Basics - Anfänger-Themen 5
krgewb Bild itextpdf Java Basics - Anfänger-Themen 2
C Bild in executable JAR File mitgeben Java Basics - Anfänger-Themen 5
VPChief Bild in JEditorPane Java Basics - Anfänger-Themen 9
B Warum bekomme ich kein Bild. Java Basics - Anfänger-Themen 10
S Bild einfügen // NEU Java Basics - Anfänger-Themen 12
N Bild drehen Java Basics - Anfänger-Themen 3
N GLOOP Bild nicht ansichtbar Java Basics - Anfänger-Themen 5
M Bild in JFrame Java Basics - Anfänger-Themen 1
B Signatur erstellen - Bild ist nur weiß Java Basics - Anfänger-Themen 0
CptK Interface Bild rotieren Java Basics - Anfänger-Themen 17
CptK Interface Bild rotieren Java Basics - Anfänger-Themen 1
Anica Processing Animation Bild-Position ändern Java Basics - Anfänger-Themen 9
CptK Interface Bild über Methode ändern funktioniert nicht Java Basics - Anfänger-Themen 4
CptK Interface Curser durch Bild ersetzen & MouseListner Java Basics - Anfänger-Themen 2
M jTextPane Bild anzeigen Java Basics - Anfänger-Themen 6
CptK Bild beim betätigen eines JButtons Java Basics - Anfänger-Themen 6
S Bild über JButton legen Java Basics - Anfänger-Themen 3
B Bild mit Schrift befüllen / Anpassung bei Wortlänge Java Basics - Anfänger-Themen 2
D Google maps bild mit marker versehen Java Basics - Anfänger-Themen 12
D ImageView mit einfarbigem Bild fuellen Java Basics - Anfänger-Themen 3
it_is_all Bild-Pfad wird gefunden, nicht aber Textdatei-Pfad Java Basics - Anfänger-Themen 8
M Einzelne Pixel in einem Bild auslesen und bearbeiten Java Basics - Anfänger-Themen 1
M Bild wird von JFrame nicht geladen Java Basics - Anfänger-Themen 12
J Bild in Button einsetzen Java Basics - Anfänger-Themen 6
S button kommt durch bild Java Basics - Anfänger-Themen 13
M Ein Bild durch Objekterzeugung zeichnen Java Basics - Anfänger-Themen 5
B Greenscreen (grüner Hintergrund ersetzen mit Bild) Java Basics - Anfänger-Themen 49
K Interface Kein Bild im .jar-File Java Basics - Anfänger-Themen 15
S Bild in Jar-File mit ImageIO Java Basics - Anfänger-Themen 50
S Bild einfügen Java Basics - Anfänger-Themen 16
binop Bild anzeigen lassen Java Basics - Anfänger-Themen 2
D Bild zu Text Java Basics - Anfänger-Themen 4
I HTML Code in Bild (transparent) konvertieren Java Basics - Anfänger-Themen 0
I Watermark erstellen mit HTML in Bild? Java Basics - Anfänger-Themen 7
D Classpath Bild kann in .jar nicht geladen werden Java Basics - Anfänger-Themen 2
Anfänger2011 Bild programmieren?! Java Basics - Anfänger-Themen 3
8 Eigenes Bild in email einfügen Java Basics - Anfänger-Themen 1
K JTable Bild einfügen Java Basics - Anfänger-Themen 1
L BufferdImage schwarzes Bild nach zusammenfügen zweier Bilder Java Basics - Anfänger-Themen 8
S Bild in JOptionPane Java Basics - Anfänger-Themen 1
C Abfrage nach einem Bild im Array Java Basics - Anfänger-Themen 9
J Umgebungsvariable Programmfenster zeigt kein Bild an Java Basics - Anfänger-Themen 1
J Bild loopen Java Basics - Anfänger-Themen 6
M JFrame Bild einfügen Java Basics - Anfänger-Themen 3
S Bild bei Kontakt ändern Java Basics - Anfänger-Themen 2
C Erste Schritte Bild holen und speichern Java Basics - Anfänger-Themen 1
D Bild in Frame einfügen Java Basics - Anfänger-Themen 11
D Bild im Applet anzeigen Java Basics - Anfänger-Themen 3
F Bild in ein Runnable Jar File packen (eclipse) Java Basics - Anfänger-Themen 2
M Java-Applet: Bild einbinden (getImage) Java Basics - Anfänger-Themen 0
J Ganzes Bild Java Basics - Anfänger-Themen 4
T GUI anstatt Bild schwarzes Rechteck gespeichert Java Basics - Anfänger-Themen 0
A Bild verschwindet! Wieso?? Java Basics - Anfänger-Themen 2
I Bild aus Bereich laden Java Basics - Anfänger-Themen 3
P Bild in JFrame Titelleiste Java Basics - Anfänger-Themen 7
Y Nach Bild-Upload wird Bild nicht angezeigt Java Basics - Anfänger-Themen 1
M Button mit Bild und Text Java Basics - Anfänger-Themen 2
M JSP-Einfaches Bild anzeigen Java Basics - Anfänger-Themen 4
C Bild ins Frame laden und Objekte drüber legen Java Basics - Anfänger-Themen 1
Sogomn Bild will sich nicht skalieren lassen Java Basics - Anfänger-Themen 1
P Ein Bild für GUI (Java-Editor) Java Basics - Anfänger-Themen 4
D Bild für ein paar Sekunden einblenden und wieder ausblenden Java Basics - Anfänger-Themen 1
E Bild per Verzeichnis/JFileChooser auf JPanel laden Java Basics - Anfänger-Themen 13
S Bild auf eine Position rotieren?! Java Basics - Anfänger-Themen 4
P Bild bearbeiten Java Basics - Anfänger-Themen 9
Z Datenmatrix in Bild verwandeln Java Basics - Anfänger-Themen 4
C Bild verschwinden lassen Java Basics - Anfänger-Themen 7
S Bild Icon aus ID3Tag auslesen Java Basics - Anfänger-Themen 4
E Bild vom FileChooser aus via ImageIcon in DB schreiben Java Basics - Anfänger-Themen 16
D Bild zum Panel hinzufügen Java Basics - Anfänger-Themen 8
C Greenfoot: Bei Tastendruck und best. Wert Bild ändern Java Basics - Anfänger-Themen 2
O Auflösung einer Bild-Datei bekommen ohne sie herunterzuladen?? Java Basics - Anfänger-Themen 7
L Bild-Datein "zuschneiden" Java Basics - Anfänger-Themen 11
O DeviantArt-Bild Konverter: Fehler.. Java Basics - Anfänger-Themen 16
K Transparents Bild laden -> Fehlermeldung Java Basics - Anfänger-Themen 6
M Bild einbinden Java Basics - Anfänger-Themen 7
2 Bild auf JApplet zeichnen Java Basics - Anfänger-Themen 18
T Bild laden Java Basics - Anfänger-Themen 7
R Bild in GUI Java Basics - Anfänger-Themen 11
D Eclipse Juno zeigt Bild nicht bei Run Java Basics - Anfänger-Themen 3
Kenan89 Bild mit jar öffnen Java Basics - Anfänger-Themen 4
S Problem bei Bewegung von einem Bild! Java Basics - Anfänger-Themen 2
J Bild mit transparenter Farbe Java Basics - Anfänger-Themen 10
N Erste Schritte Applet zeichnet Bild nicht Java Basics - Anfänger-Themen 10
J Bild auf JLabel wird nicht angezeigt Java Basics - Anfänger-Themen 11
J Bild einfügen Java Basics - Anfänger-Themen 3
T ASCII Art von Bild erstellen. Java Basics - Anfänger-Themen 32
E Bild OS-unabhängig einbinden mit URL Java Basics - Anfänger-Themen 4
A BufferedImage in Android einbinden - Bild spiegeln -wie? Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben