# PNG-Grafiken verwenden



## ToterTag (2. Nov 2010)

Ich habe 10 verschiedene PNG-Grafiken. Diese will ich nach Belieben in ein 2D-Array mit 200x200 packen. Also immer wieder die selben Grafiken. Alle Grafiken haben die selbe Größe und sind quadratisch. Dieses Array soll grafisch in einem bestimmten Bereich sichtbar sein. Natürlich will ich nicht alle 200x200 Bilder anzeigen. Gezeigt werden sollen auf einmal nur 20x20 - 30x30 Grafiken. Das ganze sollte also in ein JScrollPane.

Leider bekomme ich da überhaupt nichts auf die Reihe. Ich bringe es nicht mal fertig, eine PNG-Grafik an zeigen zu lassen. Davon, sie in einer Tabelle an zu ordnen kann noch gar nicht die Rede sein.

Vielleicht könnt ihr mir ja auf die Sprünge helfen


----------



## JohannisderKaeufer (3. Nov 2010)

Ja, was hast du denn bereits versucht?

KSKB?

Wie sieht es mit anderen Grafiktypen aus(jpg, png)?


----------



## slawaweis (3. Nov 2010)

1. Bilderreferenzen per Math.random() auf ein 200x200 Array verteilen.
2. Eigene Klasse (z.B. ImageGridPanel) von JPanel ableiten und das 200x200 Array als Parameter übergeben
3. Abhängig von der theoretischen gesamten Größe (200*image_width, 200*image_height) setPreferredSize() in ImageGridPanel setzen
4. ImageGridPanel in ein JScrollPane legen
5. paintComponent in ImageGridPanel überschreiben
6. Bei jedem Aufruf von paintComponent sich den JViewport von oben (getParent) holen und nachsehen, im welchen Ausschnitt man gerade ist. Diesen Ausschnitt dann rendern. Wenn der Parent kein JViewport ist, getBounds() verwenden.

Slawa


----------



## ToterTag (4. Nov 2010)

Danke, Slawaweis, aber wie binde ich ein Bild ein? Ich kenne das bis jetzt nur in einem jLabel und in den Codebeispielen, die sonst noch kursieren ist meistens nicht klar erkennbar was man denn nun wirklich braucht.


----------



## Landei (4. Nov 2010)

```
class Bla extends JComponent {

   public void paintComponent(Graphics g) {
     ...
     //width und height sind optional
     g.drawImage(myImage, xPosition, yPosition, width, height, null); 
     ... 
   }
}
```


----------



## ToterTag (5. Nov 2010)

Ich habe jetzt 3 Klassen zum Testen:


```
import javax.swing.*;
import java.awt.*;

public class Img extends JComponent
{
    @Override
   public void paintComponent(Graphics g)
    {
     Image file = Toolkit.getDefaultToolkit().getImage("/home/christoph/Desktop/icons/message.png");
     g.drawImage(file, 20, 20, 16, 13, null);
    }
}
```


```
import javax.swing.*;

public class Bild
{

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setVisible(true);
        frame.setSize(950, 600);
        Img test = new Img();
        frame.add(test);
    }

}
```


```
import javax.swing.*;

public class Bild2
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setVisible(true);
        frame.setSize(950, 600);
        JPanel panel = new JPanel();
        panel.setSize(200, 300);
        frame.add(panel);
        //panel.setVisible(true);
        Img test = new Img();
        frame.add(test);
    }

}
```

Die Klasse Bild lässt sich problemlos ausführen. Die Grafik, die ich anfordere wird im Frame gezeigt. Wenn ich in der Klasse Bild2 die Zeile, in der ich das JPanel zum Frame hinzu füge auskommentiere, wird die Grafik auch gezeigt. So, wie der Code aber jetzt ist, funktioniert es nicht. Wieso nicht? Ich möchte das Bild dann zum JPanel hinzu fügen. Aber wieso klappt es jetzt noch nicht einmal?


----------



## slawaweis (5. Nov 2010)

ToterTag hat gesagt.:


> Die Klasse Bild lässt sich problemlos ausführen. Die Grafik, die ich anfordere wird im Frame gezeigt. Wenn ich in der Klasse Bild2 die Zeile, in der ich das JPanel zum Frame hinzu füge auskommentiere, wird die Grafik auch gezeigt. So, wie der Code aber jetzt ist, funktioniert es nicht. Wieso nicht? Ich möchte das Bild dann zum JPanel hinzu fügen. Aber wieso klappt es jetzt noch nicht einmal?


das hat was mit dem Layout zu tun. JFrame hat per Default das BorderLayout, welches höchstens 5 andere Komponenten aufnehmen kann. Jeder dieser Komponente muss man zusätzlichen den Ort im BorderLayout mitgeben, was CENTER, NORTH, SOUTH, WEST und EAST wären, Beispiel:


```
JFrame frame = ...;
frame.add(panel1, BorderLayout.SOUTH);
frame.add(panel2, BorderLayout.NORTH);
```

Fehlt der zweite Parameter in add(), wird es als BorderLayout.CENTER interpretiert. Du rufst zwei Mal add() ohne den zweiten Parameter auf. Beim ersten Mal wird das Panel als BorderLayout.CENTER hinzugefügt. Beim zweiten Mal passiert nix, weil BorderLayout.CENTER bereits besetzt ist. Du könntest es z.B. als BorderLayout.NORTH versuchen, aber visuell wäre es nicht das, was Du willst.

Slawa


----------



## Landei (5. Nov 2010)

Das Layout eines JFrames lässt sich natürlich auch ändern: jFrame.getContentPane().setLayout(new FlowLayout()); oder was immer du willst.


----------



## ToterTag (7. Nov 2010)

Das mit Nord und Süd hat nicht geklappt. Jetzt wollte ich das eigentlich Ziel in Angriff nehmen und das Bild in das Panel hinein packen. Dazu habe ich den Code so abgeändert: 
	
	
	
	





```
import javax.swing.*;
import java.awt.*;

public class Bild2
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.getContentPane().setLayout(new BorderLayout());
        frame.setVisible(true);
        frame.setSize(950, 600);

        Img test = new Img();
        test.setVisible(true);

        JPanel panel = new JPanel();
        panel.add(test);
        panel.setSize(200, 300);
        panel.setVisible(true);

        frame.add(panel, BorderLayout.SOUTH);
    }

}
```

Es wird nichts gezeigt. Nur ein leeres Fenster. Wenn ich frame.pack(); hinzu füge, macht er mir das Fenster gänzlich zu. Bedeutet das nicht idr., dass nicht mal etwas vorhanden ist? Denn wäre etwas vorhanden, wäre die kleinst mögliche Größe bestimmt nicht "kein Fenster".


----------



## L-ectron-X (7. Nov 2010)

Das Image in der Klasse 
	
	
	
	





```
Img
```
 sollte niemals in der 
	
	
	
	





```
paint()
```
- oder 
	
	
	
	





```
paintComponent()
```
-Methode geladen werden. Ein allgemeiner und besonders performancetechnischer Fauxpas.

Die Zeile 9 in 
	
	
	
	





```
Bild2
```
 ist in dieser Form überflüssig. Ein JFrame hat das BorderLayout bereits standardmäßig gesetzt.


```
setVisible(true);
```
 sollte die letzte Anweisung auf einem JFrame sein, also erst aufrufen, wenn alle Einstellungen für den JFrame getroffen und alle anzuzeigenden Komponenten hinzugefügt wurden.
Es werden sonst u.U. nicht alle Komponenten angezeigt.

Zeile 14 sowie 18 und 19 machen erst mal keinen Sinn...

Zum Bilder laden und anzeigen kann das weiter helfen: Grafikdateien laden und anzeigen - Byte-Welt Wiki


----------

