# Fenstergröße automatisch skalieren



## b1zarRe (17. Okt 2011)

Hi,

Ich habe eine Aufgabe, in welcher ich ein Balkendiagramm erstellen muss. (Das habe ich auch realisiert mit Graphics). Ich habe es auch geschafft, dass sich alle Elemente (Kästchen, Legende etc.) prozentual verschiebt, wenn ich ein neues Fenster erstelle.

Jedoch sollen wir es hinbekommen, dass die Methode setResizable() auf true gesetzt werden sollen und beim skalieren zur Laufzeit alles sich direkt proportional skaliert. Ich glaube ich muss irgendetwas mit repaint() machen, finde aber nichts passendes zu dem Thema :/. Wie gesagt, leider dürfen wir nicht einfach das Fenster auf einer Größe lassen.


----------



## vanny (17. Okt 2011)

Also generell sind für sowas die LayoutManager zuständig.

Nun weiß ich aber nicht, wie du deine grafische Darstellung umgesetzt hast und ohne Code wird das dann wohl schwierig, dir da weiter zu helfen.


----------



## b1zarRe (17. Okt 2011)

Naja, Layoutmanager hatten wir noch nicht besprochen und dürfen die somit nicht einsetzen.
Code ist nichts besonderes hier mal als Pseudo-Code weil ich den Originalen grade nicht hierhabe:


```
public EinFramet() {
        super();
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setBounds(100, 150, 500, 250);
        this.setTitle("Mein großes Fenster");
        this.getContentPane().add(new RechteckJPanel (10,20,30,40));
    }

    public class RechteckJPanel extends JPanel {

        private int x, y, w, h;

        RechteckJPanel(int x, int y, int w, int h) {
            super();
            this.setRect(x, y, w, h);
        }

        void setRect(int x, int y, int w, int h) {
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawRect(x, y, w, h);
            g.drawLine(10, 10, 100, 102);
            
            Graphics2D neuesG = (Graphics2D) g; //2d Grafik
            neuesG.drawString("Ein Text", 1000, 20);
            
        }
    }


    public static void main(String[] args) {
        einFramet jF = new einFrame();
        jF.setVisible(true);
        
    }
}
```


----------



## vanny (18. Okt 2011)

Hihi,
sry wenn ich dich  enttäuschen muss aber du benutzt bereits LayoutManager, denn dein JFrame hat default ein BorderLayout und dein JPanel ein FlowLayout.

Ich muss jetzt leider zur Arbeit, melde mich aber heute Abend nochmal falls dann noch Bedarf besteht.

Gruß Vanny


----------



## jgh (18. Okt 2011)

so könnte man es bspw. machen, den Text habe ich jetzt einfach reingesetzt...wenn du den bspw. in deinem Rechteck haben willst, musst halt noch ein wenig nachdenken^^


```
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class RechteckJPanel extends JPanel {

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawRect(this.getX() + 20, this.getY() + 20, this.getWidth() - 40,
				this.getHeight() - 40);
		g.drawLine(getX(), getY(), getWidth(), getHeight());

		Graphics2D neuesG = (Graphics2D) g; // 2d Grafik
		String s = "Ein Text";
		neuesG.drawString(s, getWidth() - 100, getHeight() - 100);

	}

	public static void main(String[] args) {
		EinFrame jF = new EinFrame();
		jF.setVisible(true);

	}
}

class EinFrame extends JFrame {
	public EinFrame() {
		super();
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setBounds(100, 150, 500, 250);
		this.setTitle("Mein großes Fenster");
		RechteckJPanel rjp = new RechteckJPanel();
		this.getContentPane().add(rjp);
	}
}
```


----------



## b1zarRe (20. Okt 2011)

Kannst Du vielleicht erläutern warum das so klappt?! Bin ein wenig überrascht, weil ich in dem Code nichts mit repaint() finde. Liegt es daran, dass du this.getX() etc. eingefügt hast?! Und Java jedes mal das "neu berechnet"?

Und falls ja, cool danke... Gibt es eine alternative Methode dies mit repaint() zu realisieren??? Weil unser Prof. das 1-2 mal erwähnt hatte und ich es gerne auch so lernen würde (-> Klausur).


----------



## jgh (21. Okt 2011)

genau, das liegt daran das ich jetzt keine festen Werte habe, sondern in der paintComponent mir die Größe und Positionen vom JPanel hole. 

Die paintComponent - Methode wird aufgerufen, wenn sich das JPanel, bzw. das RechteckJPanel neuzeichnen soll, bspw. beim resizen.

Entsprechend dem Layoutverhalten des BorderLayouts (Default beim JFrame) erhält die geaddete Komponente allen zur verfügung stehenden Platz. Änderst du die Größe des Frames, wird die paintComponent -Methode aufgerufen und das JPanel/RechteckJPanel soll sich neu zeichnen.
get(X), bzw. this.getX() ist das gleiche...

repaint müsstest du nur aufrufen, wenn du irgendwas änderst ohne das sich was neuzeichnen müsste.
Bspw. könnte man bei Knopfdruck den Text ändern, solange sich die Komponente aber nicht neuzeichnen muss, wird der neue Text nicht angezeigt. Hier unten im Bspcode kannst du nach klicken des Buttons den Frame vergrößern, verkleinern, maximieren oder minimieren und der "neue" Text wird dann erst angezeigt. Wenn du das "repaint()" einkommentierst  und somit ein neuzeichnen anforderst, wird der geänderte Text sofort angezeigt.
Im Bsp ist es natürlich nur 1x möglich dieses Verhalten aufzuzeichnen.


```
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class RechteckJPanel extends JPanel {
	String s = "Ein Text";

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawRect(this.getX() + 20, this.getY() + 20, this.getWidth() - 40,
				this.getHeight() - 40);
		g.drawLine(getX(), getY(), getWidth(), getHeight());

		Graphics2D neuesG = (Graphics2D) g; // 2d Grafik

		neuesG.drawString(s, getWidth() - 150, getHeight() - 100);

	}

	public static void main(String[] args) {
		EinFrame jF = new EinFrame();
		jF.setVisible(true);

	}
}

class EinFrame extends JFrame {
	public EinFrame() {
		super();
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setBounds(100, 150, 500, 250);
		this.setTitle("Mein großes Fenster");
		final RechteckJPanel rjp = new RechteckJPanel();
		JButton b = new JButton("ändere Text");
		b.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				rjp.s = "Ein anderer Text";
				// repaint();

			}
		});
		add(b, BorderLayout.NORTH);

		this.getContentPane().add(rjp);

	}
}
```


----------



## b1zarRe (21. Okt 2011)

Danke schonmal für die Hilfe!!! Ich glaube ich habe es gecheckt! 

Aber sofort kam das nächste Problem:
Wenn ich zb. in der Statistik ein Balken erzeuge soll direkt dadrunter zb. eine Jahreszahl stehen UND wenn ich das Fenster vergrößer oder verkleiner soll es prozentuell immer gleich bleiben... das klappt bei mir nur bedingt, da x Positionsachse sich kaum ändert (was auch richtig ist) aber die y Achse des Textes zum Rand des Quadrats immer anders und nicht prozentuell gleich bleibt... Hast du da vielleicht eine Idee?


----------

