windowStateChanged macht exakt das Gegenteil

Hm. Man kann mit Java+Swing so schönen Code schreiben :frowning:

Aber ok…

Grob gesagt: Der WindowStateListener wird „zuerst“ informiert. Da wird nur gesagt: Hey, hier hat sich was am Fensterzustand geändert. Mehr erstmal nicht. Dass da dieses imageLabel drin ist, und dass das Bild in diesem label immer so groß sein soll, wie das Label, hat damit erstmal nichts zu tun.

Nachdem die Fenstergröße geändert wurde, laufen innerhalb von Swing die ganzen Mechanismen los, die dafür sorgen, dass das Fenster irgendwann „schön“ aussieht (d.h. die LayoutManager erledigen ihren Job).

Dabei wird unter anderen die Größe des imageLabel geändert. Und das wäre der Zeitpunkt, um etwas zu machen, wofür man die Größe braucht.

Lösen könnte man das, indem man einen ComponentListener an das imageLabel hängt, der bei componentResized immer die richtige Größe abfragen kann. Das ist unten im Code mal angedeutet.

Aber: Wenn es nur darum geht, ein Bild immer so zu zeichnen, dass es das imageLabel ausfüllt, sollte man das anders machen. Im einfachsten Fall könntest/solltest du das imageLabel durch sowas hier ersetzen:

class SimpleImageComponent extends JComponent
{
    private BufferedImage image;
    
    public void setImage(BufferedImage image)
    {
        this.image = image;
    }
    
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if (image != null)
        {
            g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
        }
    }
}

Das bekommt das komplette Bild, und malt es immer so groß, wie die component halt gerade ist. (Kein getScaledInstance mehr. getScaledInstance ist in vieler Hinsicht schlecht (vor allem ineffizient), und es gibt praktisch keinen Grund, warum man das noch verwenden sollte).

Natürlich stellen sich dann gleich ein paar Fragen: Soll das Bild ggf. nur vergrößert oder auch verkleinert werden? Soll das Seitenverhältnis des Bildes beibehalten werden? Wenn ja: Soll das Bild links, mittig oder rechts ausgerichtet sein? Die meisten dieser Fragen hatte ich man angegangen:

Aber hier noch das mit dem ComponentListener, auch wenn das sicher nicht die sinnvollste Lösung ist:

package bytewelt;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class WindowStateTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui()
    {
        WindowStateTest t = new WindowStateTest();
        t.getMainFrame().setVisible(true);
    }

    private JFrame mainFrame;
    private JLabel imageLabel;

    private ComponentListener imageLabelSizeListener = new ComponentAdapter()
    {
        @Override
        public void componentResized(ComponentEvent e)
        {
            System.out.println("Label size is now "+imageLabel.getSize());
        }
    };
    
    public WindowStateTest()
    {
        mainFrame = new JFrame();
        
        imageLabel = new JLabel("Boo!");
        imageLabel.addComponentListener(imageLabelSizeListener);
        
        mainFrame.getContentPane().add(imageLabel, BorderLayout.CENTER);

        mainFrame.setTitle("Captured image preview");
        mainFrame.setBounds(100, 100, 500, 500);
        mainFrame.setSize(500, 500);
        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        mainFrame.addWindowStateListener(new WindowStateListener()
        {
            public void windowStateChanged(WindowEvent arg0)
            {
                windowStateChanged_mainFrame(arg0);
            }
        });
    }
    
    
    JFrame getMainFrame()
    {
        return mainFrame;
    }

    private void windowStateChanged_mainFrame(WindowEvent e)
    {
        boolean max = false;
        boolean min = false;

        if ((e.getNewState() & Frame.NORMAL) == Frame.NORMAL)
        {
            min = !min;
        }
        if ((e.getNewState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH)
        {
            max = !max;
        }

        int imageLabelWidth = imageLabel.getWidth();
        int imageLabelHeight = imageLabel.getHeight();
        if (max && min)
        {
            System.out.println("Max. window size ... ");
        }
        else
        {
            if (!max && min)
            {
                System.out.println("Smaller than max. window size ... ");
            }
        }
        System.out.println("imageLabelWidth: " + imageLabelWidth
            + ", imageLabelHeight: " + imageLabelHeight);

    }
}