# AWT Frame-Inhalt in Echtzeit skalieren



## subD (14. Apr 2005)

Hi zusammen, 
nach einiger Zeit des Mitlesens nun meine kleine Forenpremiere 
Zu meinem Problem:
Ich versuche schon die ganze Zeit den Inhalt eines Frames anständig zu skalieren, kriege es aber nicht  wirklich hin.
Das ganze soll so geschehen, dass sich beim Vergrößern (sprich auf eine Ecke klicken und ziehen) automatisch der Inhalt anpasst.
Wenn ich das Fenster vergrößere wird der Inhalt aufgrund des Aufrufs von paint() auch neu gezeichnet. Leider funktioniert das aber nicht beim Verkleinern des Fensters. Ich hab es auch schon mit einem ComponentListener probiert (Methode componendResized()) aber das funktioniert auch nicht.

Hat jemand evtl. eine Idee dazu?


Hier mein Beispiel-Code:

```
import java.awt.*;

public class awtProg_01{
	public static void main(String[] args){
		boolean[][] spielfeld = new boolean[15][18];
		for (int i=0; i<spielfeld.length; ++i)
			for (int j=0; j<spielfeld[0].length; ++j)
				spielfeld[i][j] = java.lang.Math.random() > 0.5;
		MyFrame wnd = new MyFrame("Spielfeld", spielfeld);
	}
}


class MyFrame extends Frame{
	private int stoneSize;
	private final boolean[][] spielfeld;
	private int shapeValue;
	private Dimension windowSize;
	
	MyFrame(String name, boolean[][] spielfeld){
		super(name);
		this.spielfeld = spielfeld;
		stoneSize = getStdSize();
			
		setSize(stoneSize * spielfeld.length, stoneSize * spielfeld[0].length);
		windowSize = getSize();
		setVisible(true);	
	}
	
	public void paint(Graphics g){
		paintGrid(g);
		paintStones(g);
		scaleSize();
		
		if (!getSize().equals(windowSize)){
		repaint();
			windowSize = getSize();
		}	
	}
	
	
	/** 
	 * liefert Standard-Spielsteingröße, errechnet sich aus halber Bildschirmauflösung
	 * und Anzahl der Steine in x- und y-Richtung. Der kleinere Wert wird gewählt.
	 */
	private int getStdSize(){
		int a = getToolkit().getScreenSize().width / 2 / spielfeld.length;
		int b = getToolkit().getScreenSize().height / 2 / spielfeld[0].length;
		return a<=b? a : b;
	}
	
	
	/**
	 * skaliert die Spielsteingröße 'stoneSize' abhängig von der Fenster-Auflösung
	 */
	private void scaleSize(){
		int a = getWidth() / spielfeld.length;
		int b = getHeight() / spielfeld[0].length;
		stoneSize = a <= b ? a: b;
	}
	
	
	/**
	 * zeichnet ein Grundgitter, Größe abhängig von der Anzahl
	 * von Steinen in x- und y-Richtung 'spielfeld.length' bzw 'spielfeld[0].length' 
	 * und der Spielsteingröße 'stoneSize'.
	 */
	private void paintGrid(Graphics g){
		for (int i=stoneSize; i<= stoneSize * spielfeld.length; i += stoneSize)
			g.drawLine(i, 0, i, stoneSize * spielfeld[0].length);					// Senkrechte
		for (int j=stoneSize; j<= stoneSize * spielfeld[0].length; j += stoneSize)
			g.drawLine(0, j, stoneSize * spielfeld.length, j);						// Waagerechte
	}
	
	
	private void paintStones(Graphics g){
		for (int pos_x=0; pos_x < spielfeld.length; ++pos_x){
			for (int pos_y=0; pos_y < spielfeld[0].length; ++pos_y){
				if (spielfeld[pos_x][pos_y]){						// zeichne nur, wenn Feld belegt
					g.fillOval(pos_x*stoneSize, pos_y*stoneSize, stoneSize, stoneSize);
				}
			}
		}
	}
	
}
```


----------



## Roar (14. Apr 2005)

Toolkit#setDynamicLayout()


----------



## Guest (15. Apr 2005)

Kann es sein, daß das nur mit JFrames funktioniert, nicht aber mit normalen Frames?


----------



## Roar (15. Apr 2005)

JFrames sind ebenfalls normale Frames


----------



## Guest (16. Apr 2005)

Also ich weiß nicht ob ich da jetzt nen riesigen Denkfehler habe, aber es funktioniert so einfach nicht. Hier mal meine Beobachtungen dazu: Mein Fenster wird aus Frame abgeleitet.

- ohne setDynamicLayout(true) wird die paint()-Methode immer während der Fenstervergrößerung aufgerufen. Der Clipping-Bereich wird gezeichnet.

- mit setDynamicLayout(true) gibt es keine Veränderung.


Ein deutlich anderes Verhalten erziele ich, wenn ich meine Klasse aus JFrame ableite:
- ohne setDynamicLayout(true) wird paint()  immer während der Fenstervergrößerung aufgerufen (der Clipping-Bereich wird gezeichnet, beim Loslassen der Maustaste aber der komplette Fensterinhalt gelöscht). 
Bei Verkleinerung gibt es den paint()-Aufruf nur beim Loslassen der Maustaste, wobei der Inhalt nicht gelöscht wird (aber auch nur dann, wenn ich in beiden Dimensionen gleichzeitig verkleinere.)

- mit setDynamicLayout(true) wird paint() nur während der Fensterverkleinerung ausgeführt. Bei Vergrößerung gibt es keinen Aufruf. Ein Löschen des Fensterinhalts geschieht hier ebenso.

Hoffe mir kann das mal jemand genauer erklären.

Mein Code, an dem ich das getestet habe:

```
import java.awt.*;
import javax.swing.*;
 
public class test04 extends Frame{
	Dimension wndSize;
	int i;
	boolean flip;
	public test04()
	{
		//this.getToolkit().setDynamicLayout(true);
	}
 
	public static void main(String[] args)
	{
		Frame frame = new test04();
		frame.setSize(300, 200);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	 }
	 
	 public void paint (Graphics g){
	 	//g.setClip(0,0, getSize().width, getSize().height);
	 	System.out.println("paint() zum " + ++i +".");
	 	System.out.println("Fenstergroesse: " + getSize());
	 	System.out.println("Clipping-Bereich: " + g.getClip() +"\n----------------------------");
	 	wndSize = getSize();
	 	if (flip)
	 		g.drawOval(0,0,wndSize.width, wndSize.height);
	 	else{
	 		g.drawLine(0,0,wndSize.width, wndSize.height);
	 		g.drawLine(0, wndSize.height, wndSize.width, 0);
	 	}
	 	flip = !flip;
	 }
}
```


----------



## Roar (16. Apr 2005)

ruf super.paint() am anfang auf!!


----------



## Beni (16. Apr 2005)

Also erklären kann ich dir das nicht. Was intern bei AWT abläuft, versteht niemand :wink:

Aber eine Alternative Lösung: nicht direkt auf ein Frame zeichnen, sondern auf ein Canvas. Dann das Canvas einem Frame hinzufügen, und mit setDynamicLayout sagen, dass bei einer Grössenänderung das Canvas auch verändert werden soll.

```
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Toolkit;

public class Test4 extends Canvas{
   private int i;
   private boolean flip;

   public static void main(String[] args){
      Frame frame = new Frame();
      frame.setSize(300, 200);
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
	  frame.setLayout( new GridLayout( 1, 1 ));
	 
	  frame.add( new Test4() );
	  
	  Toolkit.getDefaultToolkit().setDynamicLayout( true );
    }
   
    public void paint (Graphics g){
       //g.setClip(0,0, getSize().width, getSize().height);
		
       System.out.println("paint() zum " + ++i +".");
       System.out.println("Fenstergroesse: " + getSize());
       System.out.println("Clipping-Bereich: " + g.getClip() +"\n----------------------------");
       Dimension wndSize = getSize();
	   g.setColor( Color.BLACK );
       if (flip)
          g.drawOval(0,0,wndSize.width, wndSize.height);
       else{
          g.drawLine(0,0,wndSize.width, wndSize.height);
          g.drawLine(0, wndSize.height, wndSize.width, 0);
       }
       flip = !flip;
    }
}
```


----------

