JPG's in eigenem Panel anzeigen klappt nicht

vfl_freak

Premium-User
Moin zusammen,

habe als Java-Neuling ein unschönes Problem mit der Anzeige von mehreren Bilder in einem eigenen Panel.
Ich habe hier eine bestehende Anwendung übernommen, in der bei bestimmten Aktionen an einer definierten Stelle (eigenes Panel) einzelne Webcam-Bilder dargestellt werden!
Nun soll diese Logik dahingehend erweitert werden, dass in einem bestimmten Zustand (Button-Click) alle 'restlichen' zugehörigen Bildnamen auf einmal bestimmt und nacheinander in einer Schleife dargestellt werden!
Leider scheitert dieser Aufbau daran, dass stets nur das Letzte dieser ermittelten Bild angezeigt wird :mad: !

Hier zunächst mal die (wie ich hoffe) relevanten Code-Ausschnitte:
Java:
// Klasse mit eigenem Panel, die Bilder holen und darstellen soll
public final class WebCamImagePanelEx extends JPanel implements ActionListener,
        ComponentListener, IWebcamLoadingStatus,
        xxxr.status.IWebcamLoadingStatusSubject 
{
    // Bild aus Datei einlesen
    private boolean loadImage(String strImage)
    {
        boolean bErg = false;
        ... // Loggen o.ä.
        BufferedImage myImage = null;
        myImage = ImageIO.read(new File(strImage));
        if (myImage != null) 
        {
            setImage(myImage);
            resizePicPanel();
            bErg = true;
        }
        ... // Loggen o.ä. 
        return bErg;
    }

    // Größe des Panel anpassen
    public synchronized void resizePicPanel() 
    {
        ...
        double x = 0;
        bildHeight = pnPic.getHeight();
        bildWidth = pnPic.getWidth();
        if ((bildWidth == 0)) 
        {
            return;
        }
        x = ((double) bildWidth / (double) pic.getIconWidth());
        if (x != oldX) 
        {
            pic.setImage(picBuffer.getImage().getScaledInstance(
                        (int) (pic.getIconWidth() * x) - 1,
                        (int) (pic.getIconHeight() * x) - 1, Image.SCALE_FAST));
        }
        oldX = x;
        int nDividerPos = 0;
        if ((m_mainFrm != null) && (m_mainFrm.jSplitPaneImage != null)) 
        {
            nDividerPos = m_mainFrm.jSplitPaneImage.getDividerLocation();
            ...            
        }
    }

}



// Hier sollen die entspr. Bilddatei geladen und nacheinander angezeigt werden
// Die Funktion liegt im Hauptprogramm der Anwendung ....
public void btnAbschluss_actionPerformed(ActionEvent e) 
{
    ...

    // dann die Bilder holen und anzeigen 
    // strBlocks = Stringarray, das die Bild-Dateinamen entält, die dann 
    // jew. nach 'strBild' geschrieben werden
          for( int i = 0; i < strBlocks.length; i++ )
          {
        String strBild;  // Pfad + Dateiname des zu ladenden Bildes
        ... // Holen der Daten, um den Ort 'strBild' zu ermitteln

        boolean bIsLoad = pnImageWebcam.loadImage( strBild ); // s. o.
        if( bIsLoad )
        {
            // ###################################################################
            // mit diesen Funktionen soll das Bild im Panel dargestellt werden .....
            // ###################################################################
            pnImageWebcam.resizePicPanel(); // s. o. 
                  pnImageWebcam.repaint();        // = java.awt.Component.repaint()
                  pnImageWeb.repaint();           // = java.awt.Component.repaint()
                  repaint();                      // = java.awt.Component.repaint()
        }
        ...
    }
    ...
}
Grundsätzlich klappt das holen einzelner Bilder (zuvor an anderer Stelle in einem Timer) mit den genannten Funktionen sehr zuverlässig! Wenn ich aber, wie hier beschrieben, mehrere Bilder nacheinander anzeigen will, kommt immer nur das Letzte! Allerdings habe ich gestern Abend im Debugger festgestellt, dass die ganzen 'repaint'-Geschichten nicht wirklich das Gewünschte auslösen, sondern das die Anzeige dieses letzten Bildes erst deutlich nach Verlassen des "...actionPerformed" passiert -- irgendwo in den Untiefen irgendwelcher Event-Handler .....

Bin leider ziemlich ratlos, wie ich dies hinbekommen soll? :confused::confused:
Ich hoffe, dass meine Code-Auszüge zum Nachvollziehen des Problems ausreichen ...

Bin selbst mit meinem Latein (sprich: Java-Kenntnissen) ziemlich am Ende
Hat irgendwer hierzu eine Idee
Gibt es vielleicht sowas, wie eine Refresh-Funktion o.ä.?

Danke im voraus für Vorschläge!
LG aus OS
Klaus
 
Zuletzt bearbeitet:
Hi Klaus,

was macht denn die Methode setImage(myImage) und wie sollen mehrere Bilder im Panel angezeigt werden?

Gruß
joschi
 
Moin Joschi,

erstmal Danke für Deine Antwort!

Wenn ich es richtig verstehe, bestimmt sie wohl (irgendwie :confused:) Größe und Lage ......

Java:
    /**
     * Setzen des Bildes
     * 
     * @param theImage   Bild als Image
     */
    public void setImage(Image theImage) 
    {
        mainImage = theImage;
        pic = new ImageIcon(mainImage);
        
        picBuffer = new ImageIcon(pic.getImage());
        bildHeight = pnPic.getHeight();
        bildWidth = pnPic.getWidth();
        
        if ((bildHeight == 0) || (bildWidth == 0)) 
        {
            return;
        }
        
        double x = ((double) bildWidth / (double) pic.getIconWidth());
        pic.setImage(picBuffer.getImage().getScaledInstance(
                (int) (pic.getIconWidth() * x) - 1,
                (int) (pic.getIconHeight() * x) - 1, Image.SCALE_FAST) );

        lblIcon.setIcon(pic);
    }

Gruß
Klaus
 
Zuletzt bearbeitet von einem Moderator:
Hi Klaus,

so wie ich das sehe, wird dem Label lblIcon immer das jeweilig Bild zugwiesen. Wenn das mehrere Bilder sind, ist im Label das letzte Bild sichtbar.
Wie soll das denn aussehen, wenn's mehrere Bilder sind?

Gruß
joschi
 
Hi Joschi,

das ist ja die Frage aller Fragen ... ;)

Meine Idee war, in der for-Schleife im btnAbschluss_actionPerformed (s. 1. Post) alle verfügbaren Bildnamen zu ermitteln (sie stehen dann im Stringarray strBlocks) und nacheinander abzuarbeiten:
- also zuerst mit 'loadImage' holen und dem Panel zuweisen
- dann mit 'repaint' anzeigen lassen (hier ggf. dafür sorgen, dass ein zeitlicher Abstand besteht
(Letzteres ist aber wegen der aktuellen Probleme derzeit auskommentiert)

Das Problem ist nun, das die einzelnen aufgeführten 'repaints' nicht das bewirken, was ich erwartet hatte, nämlich das Anzeigen des Bildes! Es gibt hier in der Anwendung etliche ähnliche Stellen wo das scheinbar so gemacht wird, aber auch dort hat mir gestern der Debugger gezeigt,
dass dem wohl nicht so ist :-(
Die Bildanzeige (egal ob an den anderen Stellen oder hier mit mehreren) passiert eben erst deutlich später ... so ca. 10 - 15 Aufrufe (von div. Listenern, Eventfiring-Funktionen usw. usw.)

Also das Anzeigen von bspw. 5 Bildern innerhalb dieser Schleife bringt immer nur das letzte dieser Bilder auf den Screen .....

Gruß
Klaus
 
Hi Klaus,

ne tolle Idee habe ich auch nicht, aber hast Du's schonmal mit 'nem

Java:
lblIcon.revalidate();

versucht?

Gruß
joschi
 
Hallo Joschi,

nein, werde ich aber gleich mal machen, sobald ich wieder compilierfähig bin :)

Habe just mal geschaut, und die Hilfe dazu sagt allerdings folgendes
This method will automatically be called on this component when a property value changes such that size, location, or internal layout of this component has been affected. This automatic updating differs from the AWT because programs generally no longer need to invoke validate to get the contents of the GUI to update.

Klingt für eigentlich so, als ob ein händischer Aufruf eigentlich überflüssig ist, oder?

Sollte vielleicht noch dabei sagen, dass ich hier mit dem JBuilder2007 und (notgedrungen) Java 1.4.irgendwas unterwegs bin .....

Gruß
Klaus
 
Hi Klaus,

hast Recht :D, ich meinte
Java:
lblIcon.validate();

Hierzu sagt die JavaDoc:

Validates this container and all of its subcomponents.

The validate method is used to cause a container to lay out its subcomponents again. It should be invoked when this container's subcomponents are modified (added to or removed from the container, or layout-related information changed) after the container has been displayed.

Gruß
joschi
 
Hallo Joschi,

Danke - werde es, wie gesagt, nachher mal ausprobieren.
Bauer derzeit gerade eine andere Stelle in diesem Zusammenhang um - und die läuft noch nicht sauber .....

Bin aber im Web vermutlich auf den Grund meiner Probleme gestossen (leider noch auf keine echte Lösung) :
die 'repaints', die ich aufrufe, führen noch keine wirkliche Aktion durch, sondern stellen wohl nur eine "Anforderung" hierfür dar! Sie wird (wie ich ja auch schon im Debugger sah) erst 'später' wirklich ausgeführt.
Somit ist mein Ansatz mit der Schleife und mehreren 'repaints' hierin wohl hinfällig - und ich darf großflächiger umbauen ..... :-(

Aber erstmal Danke für die Denksanstösse!

Gruß
Klaus
 
Hallo Joschi,

wie schon befürchtet, hat das "lblIcon.validate();" leider auch nicht den gewünschten Effekt erzielt!

Somit habe ich jetzt die gesamte Logik des Webcambild-Holens mittels eigener Thread- und Timerlogik umbauen müssen :(.... aber dafür scheint es jetzt (bis auf einige Feinheiten) zu funktionukelnen :p

Somit war der Arbeitstag dann doch nicht ganz umsonst ... äääh ... vergeblich :D

tschüss
Klaus
 
Zuletzt bearbeitet:
Zurück