# ImageIcon in JLabel verkleinern



## markussch (9. Apr 2008)

Hallo zusammen

Ich habe ein kleines Layout mit dem GridBagLayout-Manager aufgebaut. Das Ganze in einem JFrame. Funktioniert soweit auch ganz gut.
In einer Zelle befindet sich ein JLabel mit einem ImageIcon. Verkleinere ich nun das JFrame werden die Komponenten schön verkleinert, das JLabel aber nicht (da es ja die Grösse haben muss wegen des Bildes). Ich möchte nun allerdings das Bild ebenfalls verkleinern. Wie stelle ich dies am besten an? Muss ich einen ComponentListener anlegen und dann verkleinern oder gibt es einen einfacheren Weg?


----------



## L-ectron-X (9. Apr 2008)

Über eine Verhältnisberechnung (Länge, Breite des Fensters in Ausgangszustand).
In dem Maße, wie sich das Fenster in seiner Größe verändert, skalierst du das Bild auf deinem JLabel.


----------



## markussch (10. Apr 2008)

OK. Aber wo und wann? Eigentlich könnte ich es folgendermassen machen: 


```
public class Test extends JPanel {
		ImageIcon test;
		public Test() {
			test=new ImageIcon("test.png");
			JLabel testen=new JLabel(test);
			this.setLayout(new GridBagLayout());
			GridBagConstraints eins=new GridBagConstraints();
			eins.gridx=0;
			eins.gridy=0;
			this.addComponentListener(new Listener());
			add(testen,eins);
		}
		public void GUI (){
			JFrame fenster=new JFrame ();
			fenster.setSize (800,600);
			fenster.setResizable(true);
			fenster.setTitle ("testen");
			fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			fenster.setContentPane(new Test());
			fenster.setVisible(true);
		}
		public ImageIcon groesse_anpassen(){
			Image original = test.getImage();
			Image scaled = original.getScaledInstance(this.getWidth()/5, this.getHeight()/5, Image.SCALE_SMOOTH);
			return new ImageIcon(scaled);
		}
		public static void main (String[] args) {
			new Test().GUI();
		}
	class Listener extends ComponentAdapter{
		public void componentResized(ComponentEvent e) {
			removeAll();
			add(new JLabel(groesse_anpassen()));
		}
	}
	

}
```

Aber gibt es nicht noch eine elegantere Methode? Ich habe mit der obigen folgende Probleme:
1. Das Bild wird zuerst gar nicht angezeigt, erst nach einigen resizes am Fenster.
2. Die Berechnung ist ziemlich langsam.


----------



## Guest (11. Apr 2008)

Ich habe leider keine Antwort auf deine Frage, aber wollte mal etwas zu deinem Code fragen.
Erst mal vielen Dank für die ImageIcon-Resize-Funktion! Habe gegoogelt und immer sehr umständliche Realisierungen (wie z.B. diese http://au.answers.yahoo.com/answers2/frontend.php/question?qid=20080327223212AAz04yG) gefunden (vielleicht hilft dir das ja auch)).
Jedenfalls habe ich mal deinen Resizecode übernommen und habe jetzt Schwierigkeiten, wenn ich schon direkt beim JFrame-Aufruf ein Bild aus meiner Datenbank laden und setzen will. Ich möchte nämlich das Bild so groß wie ein bestimmtes Label und ein Panel machen und beziehe daher die Scalewerte mit panel.getHeight/Width.
Beim Aufruf des JFrames und Resizen haben die Komponenten ja noch eine Höhe und Breite von 0, daher klappt das halt nicht. Jetzt ist die Frage, wie ich an die Größe schon beim ersten Aufruf komme? Ein updateUI() und repaint() und dann Abfragen der Größen liefert auch ein 0.
Wenn das JFrame schon steht ist es natürlich dann kein Problem ein ImageIcon entsprechend vernünftig auf das Label/Pabel zu sizen.


----------



## markussch (11. Apr 2008)

Ich bin nicht sicher, ob ich deine Frage richtig verstanden habe, aber warum baust du nicht zuerst das JFrame auf und setzt dann das ImageIcon drauf? Wenn es um die Verzögerung geht, könntest du z.B. zuerst das Frame initialisieren usw., dann das Icon hinzufügen und erst am Schluss mit setVisible sichtbar machen.


----------



## p3lotud0 (23. Apr 2008)

Hi,

sorry, dass ich erst jetzt antworte: Zuerst das JFrame aufbauen und dann das ImageIcon setzen? Wie mache ich das denn?

Habe ne öffentliche Methode geschrieben, die das ImageIcon setzt. Dann das JFrame aufgerufen und hinterher aus der Klasse, die das JFrame aufgerufen hat seine Methode zum Icon-Setzen aufgerufen. Trotzden bekomme ich in der Methode jeweils 0 für die Rückgabewerte des JPanels oder JLabels.

Wenn ich im besagten JFrame einen Button mit der Funktion des Icon-Setzens mache ist das ganze kein Problem...

Mhmm...


----------



## Tom299 (24. Apr 2008)

du könntest auch selbst eine ImageIcon-Klasse ableiten und getWidth und getHeight überschreiben, z.b.:


```
public class CategoryIcon extends ImageIcon {

    // icon color
    private Color iconColor = null;
    private boolean paintIcon = true;
    
    
    public CategoryIcon (Color iconColor) {
        super ();
        this.iconColor = iconColor;        
    }
    
    public CategoryIcon () {
        super ();
        this.paintIcon = false;
    }
    
    @Override
    public synchronized void paintIcon (Component c, Graphics g, int x, int y) {        
        if (paintIcon) {
            g.setColor (this.iconColor);
            g.fillRect (1, 1, getIconWidth () - 2, getIconHeight () -2);            
        }
    }
    
    @Override
    public int getIconHeight () {        
        return 16;
    }
    
    @Override
    public int getIconWidth () {
        return 16;
    }
}
```

ich meinem beispiel zeichne ich ein rechteck und hab die größe auf 16x16 festgelegt, aber das kann man ja auch dynamisch berechnen lassen (z.b. anhand der label-höhe in deinem fall)


----------



## p3lotud0 (24. Apr 2008)

Erstmal danke für den Code. Das setzen von einer festen Größe ist ja kein Thema. Da brauch mal ja auch nicht extra ne abgeleitete Klasse für. Das Problem ist ja, dass es dynamisch sein soll und das ich halt, wenn ich die Größe des Labels abfrage, immer 0 zurückbekomme. Irgendwie muss die GUI des JFrames dafür erst stehen. Wenn das der Fall ist, macht meine Methode schon eine flexible Größe für das ImageIcon abhängig von der Größe des Labels.
Ich bekomme es einfach nicht hin, die Methode dann aufzurufen, wenn das Label schon entsprechend eine Größe besitzt, obwohl ich das JFrame schon zeichne und danach (jedenfalls meiner Meinung nach) die SetzeImageIcon-Methode extern aufrufe...
Vielleicht reden wir jetzt auch aneinander vorbei, dann entschuldige bitte


----------



## Gast (5. Mai 2008)

Hi,
habe hier noch eine schöne Lösung gefunden.

http://forum.java.sun.com/thread.jspa?threadID=5244163&messageID=10006657

JPfoto.add(new JLabel(new ImageIcon("Your Image")) {
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(((ImageIcon)getIcon()).getImage(), 0, 0, getWidth(), getHeight(), null);
    }
});

Kann noch modiv. werden mit render hints um die Qualli des Bildes zu bestimmen.

Gruß Mirco


----------

