Bild an Fenstergröße anpassen und skalieren

Den Kern der Frage hat AmunRa ja schon beantwortet. Ein paar Punkte:

  • Ich finde ja, dass ein ActionListener nur eine Methode aufrufen sollte. Also, in der actionPerformed sollten nicht zig Zeilen Code stehen.

      button.addActionListener(e -> showRandomImage());
      ....
      private void showRandomImage() {
          // HIER der code hin!
      }
    
  • Das ganze scheint sich irgendwie auf einen JFrame f zu beziehen. Überleg’ oder schau’ mal, ob man diese Abhängigkeit nicht irgendwie rausbekommt oder wegabstrahieren kann. Als minimalen Schritt dahin könnte man schon

      private void showRandomImage(int maxWidth, int maxHeight) { ... }
    

    definieren, und dort dieses Gefrickel mit übergeben, was jetzt so händisch gemacht wird - also etwa

      private void showRandomImage() { 
          int maxWidth = f.getWidth() - button.getWidth();
          int maxHeight = f.getHeight() - button.getHeight();
          showRandomImage(maxWidth, maxHeight);
      }
      private void showRandomImage(int maxWidth, int maxHeight) { ... }
    

    AAABER: Diese Berechnungen sehen stark danach aus, als würdest du höchst fragwürdige Sachen machen, die eigentlich einem LayoutManager überlassen sein sollten.

  • getScaledInstance ist langsam. Teilweise wirklich absurd langsam. Dazu hatte ich mal ein bißchen was unter 1 geschrieben.

Und nebenbei… vielleicht findest du

interessant.


1:

Der relevanteste Code-Teil davon ist (leicht angepasst)

private static BufferedImage scale(BufferedImage image, double factor) {
    RenderingHints renderingHints = new RenderingHints(null);
    renderingHints.put(
        RenderingHints.KEY_INTERPOLATION, 
        RenderingHints.VALUE_INTERPOLATION_BILINEAR);        
    }
    int w = (int)(factor * image.getWidth());
    int h = (int)(factor * image.getHeight());
    return scale(image, w, h, renderingHints);
}

private static BufferedImage scale(
    BufferedImage image, int w, int h,
    RenderingHints renderingHints)
{
    BufferedImage scaledImage = new BufferedImage(w, h, image.getType());
    double scaleX = (double) w / image.getWidth();
    double scaleY = (double) h / image.getHeight();
    AffineTransform affineTransform = 
        AffineTransform.getScaleInstance(scaleX, scaleY);
    AffineTransformOp affineTransformOp = new AffineTransformOp(
        affineTransform, renderingHints);
    return affineTransformOp.filter(
        image, scaledImage);
}