AWT mehrere Panels in einem Frame

fred741

Mitglied
Hallo!

Wir haben in der uni vor kurzem AWT (nicht SWING!!!) in der uni angestochen, und der dozent meinte, dass er AWT beispiele gerne zu klausuren bringen würde. Anhand von alten klausuren kann ich dies auch bestätigen 😀😀

B2T: Ich wollte soeben 2 Panels in einer Klasse, die Frame erweitert anordnen.
Jedoch zeigt es mir immer nur eines davon auch wirklich am screen an.
Wie bekomme ich es her, dass sowohl "myPanel" als auch "myPanel2" sichtbar sind?


anbei mein java code
Java:
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Panel;

public class MyWindow extends Frame {
    public MyWindow(){
        Panel myPanel = new Panel();
        myPanel.setLayout(new FlowLayout()); 
     
        Panel myPanel2 = new Panel(); 
        myPanel2.setLayout(new GridLayout(20, 4));     
     
        Button b1 = new Button("OK");
        Button b2 = new Button("Close");
        Button b3 = new Button("Back");
        Button b4 = new Button("Tester");
        Button b5 = new Button("2.Tester");
     
        myPanel.add(b1);
        myPanel.add(b2);
        myPanel.add(b3);

        myPanel2.add(b4);
        myPanel2.add(b5);
     
        this.add(myPanel);
        this.add(myPanel2);
 
    
    }
}

--- neue unabhängige klasse:

public class Starter {
    public static void main(String[] args) {
        MyWindow frame = new MyWindow();
        frame.pack();
        frame.setVisible(true);
    }
}
f8127b-1499976132.png
ich danke euch schon mal für eure hilfe
 
Probier mal die beiden Panels auch in ein Layout zu packen, bespielsweisr ein FlowLayout. Oder setze mal deine Fenstergröße selber(mit setSize(int x, int y), anstatt die pack() Methode zu nutzen. Oder versuch beides in Kombination. Mir scheint es so, als würden die Panels übereinanderliegen oder nebeneinander im "verborgenen" Bereich
 
ich danke dir für die schnelle antwort, jedoch wird das 2. panel trotzdem nicht angezeigt.

ich habe wie du gesagt hast den folgenden Code:
Java:
myPanel.setLayout(new FlowLayout());
myPanel2.setLayout(new GridLayout(20, 4));

in diesen abgeändert:
Java:
myPanel.setLayout(new FlowLayout());
myPanel2.setLayout(new FlowLayout());
,das pack() entfernt und stattdessen frame.setSize(800,400);
eingefügt.

Das ergebnis bleibt außer der größenänderung das selbe.

mfg fred[/code]
 
Du musst deinem Frame einen anderen Layoutmanager mitgeben, nicht den Panels.

Das bei dir nur ein Panel angezeigt wird liegt weder an dem pack() noch an der Größe deines Fensters.
Der Default-Layoutmanager von einem Frame ist ein BorderLayout. Wird bei einem BorderLayout die add() Methode ohne zweiten Parameter aufgerufen, wird automatisch die Komponente ins CENTER gesetzt.
Die einzelnen Abschnitte eines BorderLayouts (NORTH, SOUTH, EAST, WEST, CENTER) können aber nur jeweils eine Komponente haben. Wenn man mehrere hinzufügt, wird die vorherige Komponente überschrieben (rausgeschmissen). Da du beide male die add() Methode ohne Parameter aufrufst, wird beim 2. mal dein 1. Panel überschrieben.
 
Wenn du die Anordnung der beiden Panels beeinflussen willst, bringt es nicht so viel, deren LayoutManager zu verändern, sondern du musst dich mit dem LayoutManager der Komponente beschäftigen, in der sich die beiden Panels befinden. Aktuell müsste das das BorderLayout sein. Du kannst ja mal testweise die Zeile für MyPanel wie folgt ändern:
this.add(myPanel, BorderLayout.SOUTH);
 
Vielen Dank für die vielen schnellen Antworten, der fehler ist behoben 😎
Es lag wie Robat und Meniskusschaden schrieben wohl am nicht festgelegten standardlayoutmanager der klasse frame, sodass das 2. Panel immer das 1. überlagert hat.

Für alle, die später ähnliche Probleme mit mehreren Panels oä in einer Klasse haben befindet sich im Folgendem die laufende version des programms:

Java:
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Panel;

public class MyWindow extends Frame {
    public MyWindow(){
     
        // LayoutManager hinzufügen, der die Anordnung der
          // einzelnen Komponenten (hier Panels) bestimmt.
        setLayout(new FlowLayout());    //////   <-- hier lag der Fehler
     
        // erzeuge Panels und weise ihnen einen Layoutmanager zu:
        Panel myPanel = new Panel();
        myPanel.setLayout(new FlowLayout()); 
     
        Panel myPanel2 = new Panel(); 
        myPanel2.setLayout(new GridLayout(4,1));     
     
        // erstelle Buttons:
        Button b1 = new Button("OK");
        Button b2 = new Button("Close");
        Button b3 = new Button("Back");
        Button b4 = new Button("1.Tester");
        Button b5 = new Button("2.Tester");
     
        // dem 1. Panel 3 Buttons anhängen:
        myPanel.add(b1);
        myPanel.add(b2);
        myPanel.add(b3);
     
        // dem 2. Panel 2 Buttons anhängen:
        myPanel2.add(b4);
        myPanel2.add(b5);
     
        // Panel der Klasse MyWindow anhängen:
        this.add(myPanel);
        this.add(myPanel2);
     
    }
}
// neue Klasse
public class Starter {
    public static void main(String[] args) {
        MyWindow frame = new MyWindow();
        frame.setSize(800,400);
        frame.setVisible(true); 
    }
}

2 kleine fragen hätte ich aber noch:
* zum einen ob ich es richtig verstanden habe, dass der LayoutManager in der 1.Zeile des Konstruktors der Klasse Frame gilt, die ja von mir erweitert wird;
*und zum anderen inwiefern das THIS vom this.add(myPanel) sinnvoll ist oder ob man es generell weglassen soll.

Ich bedanke mich nochmal speziell bei @Robat und auch bei @Meniskusschaden .
Mit zufriedenen Grüßen,
Fred 🙂

EDIT: hier findet ihr quasi dasselbe programm, leider fandich das 1h zu spät und ich musste euch mit meiner frage beglücken
https://way2java.com/awt-components/java-awt-panels/
 
Zuletzt bearbeitet:
Es lag wie Robat und Meniskusschaden schrieben wohl am nicht festgelegten standardlayoutmanager der klasse frame
Ich habe nie geschrieben dass die Frame-Klasse keinen Layoutmanager standartmäßig festlegt 😉

* zum einen ob ich es richtig verstanden habe, dass der LayoutManager in der 1.Zeile des Konstruktors der Klasse Frame gilt, die ja von mir erweitert wird;
Wenn du damit fragen willst, ob so ein Layoutmanager gesetzt wird: Ja

*und zum anderen inwiefern das THIS vom this.add(myPanel) sinnvoll ist oder ob man es generell weglassen soll.
Sinnvoll oder nicht. Nun ja - geschmackssache würde ich mal sagen. Ich schreibs so gut wie nie.

Nebenbei mal was Off-Topic:
In deinem Usecase von Frame zu erben ist mMn bad-practise. Man sollte nur von einer Klasse erben wenn man dessen Funktionalität erweitern will. Das machst du aber nicht. Es reicht vollkommen aus eine Instanz von Frame zu erstellen und darüber die Methoden auf zu rufen. Du machst dir ja auch nicht für jeden String eine eigene Klasse 😉
 
War ein Beispiel? Aber man sieht dieses Pattern am Häufigsten bei Konstruktoren und settern (hmm man könnte sagen bei DI oder bei parameterübergaben - auch bei normalen Methoden möglich)
Java:
class Box<T> {
  private T value;
  public Box(T value) {
    this.value = value; // <-- häufig
  }

  public void setValue(T value) {
    this.value = value; // <-- auch häufig
  }
}
 
es gibt natürlich ausnahmen wo man es explizit braucht - z.B. Konstruktor
Du hast nicht vollständig zitiert ! 🙂🙂 Der Konstruktor ist kein Beispiel dafür wo man es explizit braucht.

Edit: die Bemerkung müsste richtig heissen:

es gibt natürlich Ausnahmen wo man es explizit braucht - z.B. um Shadowing zu vermeiden
 
Äh was? Post #12?

Edit: Der Satz passt schon so! Ich sagte WO man es braucht und nicht WARUM man es braucht.
WO: Konstruktor, Methoden, Subklassen, ... (mehr fällt mir gerade nicht ein)
WARUM: Shadowing
 
Zuletzt bearbeitet:
Post #12 hatte ich dir bestätigt. 😉😉 da warst du aber auch irgendwie nicht zufrieden mit.
Dann habe ich dir erläutert warum ein Konstruktor kein Beispiel dafür ist. Du könntest ja genau so gut schreiben: "... - z.B. überall", gemeint hattest du aber "... z.B. um Shadowing zu vermeiden"
 
Wow wir reden aneinander vorbei ... 🙄

TL;DR: this wird explizit verwendet um Shadowing zu vermeiden und konkrete Instanzen (z.B. äußere Instanz) direkt anzusprechen bei inneren Klassen.
 

Neue Themen


Zurück
Oben