/*
Datei............: Aufg2002.java
Projekt..........: Einführung in die Java-Programmierung
Erstellt.........: 05.12.97, Guido Krüger
Geändert.........: --
Aufgabe..........: Musterlösung zu Aufgabe 20.02
Kommentare.......:

Die Lösung der Aufgabe besteht darin, eine neue Klasse aus Panel 
abzuleiten und darauf ein Label und ein TextField zu plazieren.
Beide Dialogelemente werde als Instanzmerkmale gehalten und die
Methoden getLabelText, setLabelText, getFieldText und setFieldText 
dienen zum Zugriff auf den Inhalt und die Beschriftung des neuen
Dialogelements. Weitere Methoden der Klassen Label und TextField
können bei Bedarf auf dieselbe Weise nach außen gereicht werden.

Die Anordnung der beiden Dialogelemente kann auf unterschiedliche
Weise erfolgen. Wir wollen hier nicht die Hilfe eines LayoutManagers
in Anspruch nehmen, wie es im Buch verschiedentlich gezeigt wurde,
sondern das Layout selbst vornehmen. Dabei soll die linke Spalte
(also die mit den Beschriftungen) jeweils eine feste Breite haben,
die von außen vorgegeben wird. Die rechte Spalte soll dynamisch 
an die aktuelle Größe des Panels angepaßt werden. 

Um die Anordnung vorzunehmen, überlagern wir die Methode doLayout.
Sie wird bei Elementen der Klasse Container aufgerufen, um die
Dialogelemente mit Hilfe des zugeordneten LayoutManagers zu 
skalieren und anzuordnen. In doLayout bestimmen wir zunächst den
zur Ausgabe nutzbaren Bereich des Panels und setzen dann das
Label in der von außen angegeben Breite in die linke obere Ecke. 
Die Höhe entspricht dem von Panel gelieferten Defaultwert. Rechts
daneben wird das TextField in der noch verbleibenden Breite angeordnet.
Auch hier entspricht die Höhe der Defaulthöhe. An den Rändern und
zwischen Label und Textfield wird jeweils eine Lücke gelassen.

Das Panel kann nun beliebig skaliert werden. Solange genügend Platz
zur Anzeige des Textfields verbleibt, wird das Layout immer den 
o.g. Bedingungen genügen. Die initiale Größe des Panels wird durch
Aufruf von pack() im Frame bestimmt. Jedes der im Frame enthaltenen
Komponenten wird dabei durch Aufruf von getPreferredSize nach seiner
gewünschten Größe gefragt. Besitzt eine Komponente seinerseits
Unterkomponenten, wird die Befragung rekursiv fortgesetzt. Hat 
eine an der Befragung beteiligte Komponente einen Layoutmanager,
so wird die Bestimmung der gewünschten Größe an diesen übertragen.

In unserer Implementierung liefert getPreferredSize als Höhe das
Maximum der Defaulthöhen von Label und Textfield. Als Breite wird
die Summe aus dreimal der Breite der Lücke plus der angegeben
Breite des Labels plus der Defaultbreite des Textfelds mit dem
aktuellen Inhalt zurückgegeben.

Zum Testen der Klasse labeledTextField erzeugt unser Programm einen
Frame mit zwei derartigen Objekten. Durch die identische Breite der
Labels werden die TextFelder bündig untereinander angeordnet. Mit
Hilfe des Buttons werden die Beschriftungen von Labeels und Textfeldern
entgegen dem Uhrzeigersinn vertauscht. Auf diese Weise können die
Methoden getLabelText, setLabelText, getFieldText und setFieldText 
getestet werden.
*/
import java.awt.*;
import java.awt.event.*;

public class Aufg2002
extends Frame
implements ActionListener
{
  //Instanzmerkmale
  labeledTextField lt1, lt2;
  Button button;

  public static void main(String[] args)
  {
	Aufg2002 wnd = new Aufg2002();
	wnd.setVisible(true);
  }

  public Aufg2002()
  {
	super("Aufg2002");
	setBackground(Color.lightGray);
	//labeledTextFields hinzufügen
	setLayout(new GridLayout(3, 1));
	add((lt1 = new labeledTextField("Name", "Müller-Lüdenscheid", 100)));
	add((lt2 = new labeledTextField("Vorname", "Erwin", 100)));
	//Buttons hinzufügen
	Panel panel = new Panel();
	panel.setLayout(new FlowLayout(FlowLayout.CENTER));
	panel.add((button = new Button("Tauschen")));
	add(panel);
	//Listener registrieren
	addWindowListener(
	  new WindowAdapter() {
	    public void windowClosing(WindowEvent event) {
		  System.exit(0);
		}
	  }
    );
	button.addActionListener(this);
	//Dialogelemente anordnen
	pack();
	printComponentSizes();
  }

  public void actionPerformed(ActionEvent event)
  {
	if (event.getActionCommand().equals("Tauschen")) {
	  String tmp = lt1.getLabelText();
	  lt1.setLabelText(lt1.getFieldText());
	  lt1.setFieldText(lt2.getFieldText());
	  lt2.setFieldText(lt2.getLabelText());
	  lt2.setLabelText(tmp);
	}
  }

  public void printComponentSizes()
  {
	Component components[] = getComponents();
	for (int i = 0; i < components.length; ++i) {
	  System.out.println(
		i + ": " +
		components[i].getClass().getName() + " (" + 
		components[i].getBounds() + ")"
      );
	}
  }
}

class labeledTextField
extends Panel
{
  //Konstanten
  static final int GAP = 2;

  //Instanzmerkmale
  Label label;
  TextField textfield;
  int labelwidth;

  public labeledTextField(String labeltext, String fieldtext, int labelwidth)
  {
	setLayout(null);
	add(label = new Label(labeltext));
	add(textfield = new TextField(fieldtext));
	this.labelwidth = labelwidth;
  }

  public void setLabelText(String text)
  {
	label.setText(text);
  }

  public String getLabelText()
  {
	return label.getText();
  }

  public void setFieldText(String text)
  {
	textfield.setText(text);
  }

  public String getFieldText()
  {
	return textfield.getText();
  }

  public Dimension getPreferredSize()
  {
	int width = 3 * GAP + labelwidth + textfield.getPreferredSize().width;
	int height = 2 * GAP + Math.max(
	  label.getPreferredSize().height, 
	  textfield.getPreferredSize().height
	);
	return new Dimension(width, height);
  }

  public void doLayout()
  {
	Insets insets = getInsets();
	Dimension size = getSize();
	int top = insets.top;
	int bottom = size.height - insets.bottom;
	int left = insets.left;
	int right = size.width - insets.right;

	label.setBounds(
	  left + GAP,
	  top + GAP, 
	  labelwidth, 
	  label.getPreferredSize().height
	);
	textfield.setBounds(
	  left + labelwidth + GAP + GAP,
	  top + GAP,
	  right - left - labelwidth - 3 * GAP, 
	  textfield.getPreferredSize().height
	);
  }

}

