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 JPanelaintComponent() 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:
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
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 JPanelaintComponent() 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);
}
}
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