# Problem: Größe von Komponenten festlegen



## ernst (6. Mrz 2009)

Hallo allerseits,
in dem Programm unten (das einwandfrei funktioniert) werden verschiedene Größen festgelegt:
// Größe eines Panels
MyZeichenflaeche myZf = new MyZeichenflaeche(400, 400);              
// Größe JFrame -Objekt
f.setSize(550,550);  
// Größe eines images
myimg = createImage(sx, sy);


Fragen:
1)
Warum gibt
sx = this.getSize().width; 
sy = this.getSize().height;
die folgenden Werte: 
sx = 542
sy = 516
Die Zeichenfläche wurde doch auf 400 x 400 festgelegt!!

2)
Egal, was man in 
MyZeichenflaeche myZf = new MyZeichenflaeche(400, 400);              
als Größe festlegt, die Zeichenfläche wird optisch auf dem _ganzen_ JFrame - Objekt (550 x 550) dargestellt. Welchen Sinn hat dann die Festlegung von den 400 x 400 ?
Wo wirkt sich dies optisch aus?

3)
Warum wird mit 
sx = this.getSize().width; 
sy = this.getSize().height;
myimg = createImage(sx, sy);
das Image auf diese Größe festgesetzt, wo doch mit
myimg = createImage(100, 100);            
oder irgendeinem anderen Wert optisch genau das gleiche passiert?

Ich verstehe die dahinter steckende Logik nicht!

mfg
Ernst



-------------------------------------------------------------------------------
[HIGHLIGHT="Java"]package verzoegertzeichnen3;

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

public class MainVerzoegertZeichnen3 {
    public static void main(String[] args){
        int kreisNummer;
        kreisNummer = 1;
        MyZeichenflaeche myZf = new MyZeichenflaeche(400, 400);              
        JFrame f = new JFrame();
        f.setSize(550,550);
        f.getContentPane().add(myZf);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);	  	

        while(kreisNummer<=10){
            try{
                Thread.sleep(10);
            }
            catch(Exception e){}
            kreisNummer=kreisNummer+1;

            MyRunnable myR = new MyRunnable(myZf, kreisNummer);
            // invokeLater() ist eine static-Methode
            SwingUtilities.invokeLater(myR);
        }
    }
} [/HIGHLIGHT]       


[HIGHLIGHT="Java"]class MyZeichenflaeche extends JPanel{
    private int xpAnz;
    private int ypAnz;
    private int kreisNummer;
    private Image myimg;
    private Graphics myg;
    private int sx;
    private int sy;

    public MyZeichenflaeche(int xpAnz, int ypAnz){ 
        kreisNummer=0;
        this.xpAnz=xpAnz;
        this.ypAnz=ypAnz;   
        myimg=null; 
    }

    public void setKreisNummer(int pKreisnummer){
        kreisNummer=pKreisnummer;  		
    }

    public int getKreisNummer(){
        return (kreisNummer);
    }

    public void male(){
        if(myimg==null){
            sx = this.getSize().width; 
            sy = this.getSize().height;
            System.out.println("sx="+sx);
            System.out.println("sy="+sy);            
            //myimg = createImage(100, 100);            
            myimg = createImage(sx, sy);
            myg = myimg.getGraphics();
        }
        // Schreibzugriff auf myimg
        myg.setColor(Color.red);
        myg.drawOval(kreisNummer*20 , kreisNummer*20, 20, 20);                        
    }

    // ist im EDT                        
    public void paintComponent(Graphics g){
        // Lesezugriff auf myimg                
	g.drawImage(myimg,0,0,null);
    }
}[/HIGHLIGHT]


[HIGHLIGHT="Java"]class MyRunnable implements Runnable{
    private MyZeichenflaeche myZf;
    private int kreisNummer;
    public void run(){
        // ist im EDT
        // Schreibzugriff auf das myZf von main
        // setzt kreisnummer von myZf in main !! auf einen neuen Wert !!!!
        myZf.setKreisNummer(kreisNummer); 
        // Schreibzugriff auf mying        
        myZf.male();
        // Lesezugriff auf mying in paintComponent
        myZf.repaint();                    
    }

    public MyRunnable(MyZeichenflaeche pZeichenflaeche, int pKreisnummer){
        myZf = pZeichenflaeche;
        kreisNummer = pKreisnummer;
    }
}[/HIGHLIGHT]
-------------------------------------------------------------------------------


----------



## Marco13 (6. Mrz 2009)

_
Fragen:
1)
Warum gibt
sx = this.getSize().width; 
sy = this.getSize().height;
die folgenden Werte: 
sx = 542
sy = 516
Die Zeichenfläche wurde doch auf 400 x 400 festgelegt!!
_
Die Größe des Frames ist aber auf einen anderen Wert gesetzt, und wenn man Layoutmanager verwendet (was standardmäßig der Fall ist) bringt ein setSize() nichts, und stattdessen wird die Größe der enthaltenen Componenten aus dem Layout und der Größe der übergeordneten Component berechnet.

_
2)
Egal, was man in 
MyZeichenflaeche myZf = new MyZeichenflaeche(400, 400);              
als Größe festlegt, die Zeichenfläche wird optisch auf dem _ganzen_ JFrame - Objekt (550 x 550) dargestellt. Welchen Sinn hat dann die Festlegung von den 400 x 400 ?
Wo wirkt sich dies optisch aus?
_
Bezieht sich fast auf das gleiche: ein JFrame (bzw. sein ContentPane) hat standardmäßig... ich glaub... ein BorderLayout, und die Zeichenfläche liegt im CENTER des BorderLayouts, und nimmt deswegen automatisch den gesamten verfügbaren Platz ein. Man könnte das verhindern, indem man ein 'null'-Layout verwendet, aber das ist nur SEHR selten angebracht. Wenn die Größe des JPanels soooo relevant ist, kannst du sagen
zeichenflaeche.setPreferredSize(new Dimension(400,400));
frame.add(zeichenflaeche);
frame.pack();
Durch das "pack" wird der Frame so groß, dass er seine enthaltenen Components mit ihrer bevorzugten (preferred) Size anzeigen kann.


_3)_ Kapier' ich nicht.


LESEN: Using Layout Managers (The Java™ Tutorials > Creating a GUI with JFC/Swing > Laying Out Components Within a Container)


----------



## ernst (6. Mrz 2009)

1)
An den JFrame f wird die Zeichenfläche myZf "geklebt".
Was bedeutet dann konkret deine Aussage "und stattdessen wird die Größe der enthaltenen Componenten aus dem Layout und der Größe der übergeordneten Component berechnet." und wie wird dann sx und sy berechnet

2)
Du hast geschrieben: "Kapier' ich nicht".
Deswegen will ich mich genauer ausdrücken:

Es wird wie folgt sx und sy berechnet 
a) sx = this.getSize().width;
b) sy = this.getSize().height;
und dann mit diesen Größen ein Bild erzeugt:
c) myimg = createImage(sx, sy);
Allerdings bekomme ich mit beliebigen von mir erfundenen Werten wie z.B. 100, 200 mit
d) myimg = createImage(100, 200);
optisch auf dem Bildschirm genau das gleiche. 
Ich verstehe die dahinter steckende Logik nicht:
Warum erzeugt a) und b) und c)
das gleiche wie d) ??

mfg
Ernst


----------



## Marco13 (7. Mrz 2009)

_Was bedeutet dann konkret deine Aussage "und stattdessen wird die Größe der enthaltenen Componenten aus dem Layout und der Größe der übergeordneten Component berechnet." und wie wird dann sx und sy berechnet_

Die Größe (sx = 542, sy = 516) wid berechnet, indem 
1. Der Frame auf eine Gesamtgröße von 550,550 gesetzt wird (was du ja geschrieben hast)
2. Ausgerechnet wird, wie viel Platz in so einem Frame ist (d.h. es werden die Titelleiste und die Ränder abgezogen - ich weiß jetzt z.B. dass der linke Rand deines Frames genau 4 Pixel breit ist )
3. Der gesamte verfügbare Platz der - in diesem Fall - einzigen, in der Mitte liegenenden Component zugewiesen wird - darum wird diese Component (also die Zeichenfläche) genau (542,516) Pixel groß



_2)
Du hast geschrieben: "Kapier' ich nicht".
_
Das hatte ich bei 3 geschrieben. Ich kapiere in erster linie nicht, was das "createImage" soll. Man SIEHT nichts, wenn man createImage aufruft. createImage erstellt nur ein Bild, mit der übergebenen Größe, aber das wird ja nirgendwo hingemalt - darum ist es _optisch auf dem Bildschirm genau das gleiche _, egal, wie groß das Bild ist, das man da erstellt (und nicht sieht...)


----------



## ernst (8. Mrz 2009)

> Das hatte ich bei 3 geschrieben. Ich kapiere in erster linie nicht, was das "createImage" soll. Man SIEHT nichts, wenn man createImage aufruft. createImage erstellt nur ein Bild, mit der übergebenen Größe, aber das wird ja nirgendwo hingemalt - darum ist es _optisch auf dem Bildschirm genau das gleiche _, egal, wie groß das Bild ist, das man da erstellt (und nicht sieht...)



Du hast recht!
Danke für eure Antworten.


----------

