Swing Formularelemente - Anzeigefehler?
LazyWolf
- java
Hallo.
Ich habe letztens mein AWT Fenster Spaßeshalber in SWING umgeandelt und habe jetzt folgedes Problem.
Ich setze ein paar Elemente, JTextField, JRadioButton etc.
Jedoch werden die erst angezeigt, wenn ich sie (im unsichtbaren Zustand) benutze.
Wenn ich dann das Fenster minimiere, oder von einem einem anderen verdecke o.ä. sind sie wieder weg - bis zum anclicken.
Woran könnte das liegen?
Hallo,
Woran könnte das liegen?
Keine Ahnung.
Poste bitte mal den relevanten Code. (Oder die ganze Klasse, falls sie
noch nicht zu groß ist.)
Gruß
Slyh
Hallo,
Woran könnte das liegen?
Keine Ahnung.
Poste bitte mal den relevanten Code. (Oder die ganze Klasse, falls sie
noch nicht zu groß ist.)Gruß
Slyh
public void displayForms()
{
getContentPane().setLayout(null);
pl = new JLabel("Spieler 1:");
pl.setBounds(20, 250, 100, 20);
getContentPane().add(pl);
tf = new JTextField("",20);
tf.addActionListener(this);
tf.setBounds(20, 270, 140, 20);
getContentPane().add(tf);
lb = new JLabel(""); // NAME SELECTION DISPLAY
lb.setBounds(240, 270, 100, 20);
getContentPane().add(lb);
lb_ni = new JLabel(""); // CLASS SELECTION DISPLAY
lb_ni.setBounds(240, 290, 100, 20);
getContentPane().add(lb_ni);
group = new ButtonGroup();
check_ni = new JRadioButton("Mage", false);
check_ni.addActionListener(this);
check_ni.setBounds(20, 290, 80, 20);
getContentPane().add(check_ni);
group.add(check_ni);
check_ichi = new JRadioButton("Warrior", false);
check_ichi.addActionListener(this);
check_ichi.setBounds(100, 290, 80, 20);
getContentPane().add(check_ichi);
group.add(check_ichi);
ap = new JButton("apply");
ap.addActionListener(this);
ap.setBounds(330, 270, 70, 20);
ap.setEnabled(false);
getContentPane().add(ap);
go = new JButton("> start >");
go.addActionListener(this);
go.setBounds(20, 380, 100, 20);
go.setEnabled(false);
getContentPane().add(go);
saved_name_ichi = new JLabel(""); // NAME 1
saved_name_ichi.setBounds(80, 320, 100, 20);
getContentPane().add(saved_name_ichi);
saved_class_ichi = new JLabel(""); // CLASS 1
saved_class_ichi.setBounds(80, 340, 100, 20);
getContentPane().add(saved_class_ichi);
saved_name_ni = new JLabel(""); // NAME 2
saved_name_ni.setBounds(280, 320, 100, 20);
getContentPane().add(saved_name_ni);
saved_class_ni = new JLabel(""); // CLASS 2
saved_class_ni.setBounds(280, 340, 100, 20);
getContentPane().add(saved_class_ni);
}
Das rufe ich auf mit displayForms();
Hallo,
Das rufe ich auf mit displayForms();
Und displayForms() rufst du im Konstruktor oder einer der "Initalisierungs-
methoden" auf, richtig? (Also nur einmal.)
Sieht soweit ganz gut aus.
Hast du vielleicht die paint()- oder die update()-Methode überschrieben?
Der Fehler würde darauf hindeuten. Rufe in diesem Fall möglichst immer
die überschriebene Methode auf. Dies machst du, indem du irgendwo
in der "überschreibenden" Methode "super.paint();" (oder was auch immer
gerade deine überschriebene Methode ist) aufrufst.
Gruß
Slyh
Also bei mir sieht das so aus...
Es gibt eine paint() Methode, diese enthält alle Methoden zum setzen von "statischen" Grafiken. Das garantiert, dass auch nach dem Minimieren etc. die Grafiken wieder angezeigt werden.
Eine update() Methode kümmert sich um das Animieren von ein paar Gifs.
Mein Problem ist jedoch, dass die Formularelemente nichtmal beim Aufruf der genannten Methode angezeigt werden. Sie werden gesetzt, aber man sieht sie nicht. Wenn ich sie anclicke, erscheinen sie. Wenn ein event z.B. setEnabled ändert, dann erscheinen sie auch.
Minimiere und maximiere ich sie, sind sie wieder weg.
Ich habe versucht, sie in die paint(); Methode zu setzen, aber irgendwie hilft das nicht.
Ich verstehe es nicht.
Hallo,
Es gibt eine paint() Methode,
Und darin rufst du bestimmt super.paint() auf, die wiederum eine Methode
zur Anzeige der Swing-Dialogelemente aufruft, oder?
diese enthält alle Methoden zum setzen von "statischen" Grafiken.
Was sind statische Grafiken? Wieso machst du sowas in paint()?
Was willst du damit erreichen?
Das garantiert, dass auch nach dem Minimieren etc. die Grafiken wieder angezeigt werden.
Was es ja scheinbar nicht tut. :-)
Eine update() Methode kümmert sich um das Animieren von ein paar Gifs.
Wieso sowas in update()? Und was heißt "kümmert sich um das Animieren"?
Mein Problem ist jedoch, dass die Formularelemente nichtmal beim Aufruf der genannten Methode angezeigt werden.
Welche meinst du jetzt? Die super-Methoden?
Sie werden gesetzt, aber man sieht sie nicht. Wenn ich sie anclicke, erscheinen sie. Wenn ein event z.B. setEnabled ändert, dann erscheinen sie auch.
Ja, weil sie sich dann selbst zeichnen, initiiert durch den Klick.
Das erste mal werden sie aber von paint() gezeichnet.
Und auch dann, wenn z.B. Teile durch ein anderes Fenster überdeckt
wurden und diese Teile nun neu gezeichnet werden müsen.
Wenn nun paint() nicht mehr die Methode zum Zeichnen der Komponenten
aufruft, werden diese logischerweise auch nicht mehr angezeigt. Dann
werden eben nur noch deine "statischen Grafiken" oder wasauchimmer
angezeigt.
Übrigens steht das, was ich dir gerade erzähle, auch in der API-Doku
zu paint(): "Paints the container. This forwards the paint to any
lightweight components that are children of this container. If this
method is reimplemented, super.paint(g) should be called so that
lightweight components are properly rendered."
Hintergrund: JFrame ist ein Container, kann selbst also andere
Components enthalten. (JFrame ist von java.awt.Container abgeleitet.)
Damit diese Components gezeichnet werden, muß der Container allen
enthaltenen Components sagen "Los, zeichne dich mal". Das erfolgt -
wenn ich mich recht erinnere - in der Methode paintComponents().
Genau diese Methode wird in paint() aufgerufen. Damit das auch noch
dann erfolgt, wenn du paint() überschreibst, solltest du stets auch
immer super.paint() aufrufen.
Gruß
Slyh
Hoa...
...okay... *versuchnachzuvollziehen*
Mach's gut.
LazyWolf
Nochmal kurz nachgeschoben:
Wenn ich das zeichnen der Formulare in paint() oder update() setze, werden sie jedesmal überienandergezeichnet.
Das wirkt sich darauf aus, dass mit setText der Inhalt eines Labels nicht ersetzt, sondern drübergepappt wird...
Also irgendwie nicht so sinnig...
Hallo,
- Mit "statischen Grafiken" meine ich Bilder, die das "Design" ausmachen, also sich nicht bewegen, nicht erscheinen, nicht verschwinden, sondern einfach immer da sind.
Ja, das würde ich unter statisch verstehen.
Nur: Wo sind die Bilder? Zeichnest du die direkt in das JFrame rein?
Wieso so kompliziert? Wieso verwendest du nicht einfach z.B. ein Label,
das dieses Bild anzeigen soll. Dann hast du auch das Problem nicht
mehr. (Naja, gut, manchmal ist das nicht möglich.)
- Wenn ich ein AniGif zeichnen lasse, dann ruft es sich selbst immer wieder selbst auf, um die Animationsteile anzuzeigen, habe ich festgestellt. Da das sich aber durch ein Flackern aller anderen Grafiken bemerkbar machte, habe ich die Anigifs in update(), alle anderen Grafiken in Methoden, die von paint() gerufen werden. Wenn ich minimiere etc. wird paint aufgerufen, oder durch einen direkten aufruf. Der Befehl repaint(); startet lediglich das update().
Das flackert deshalb, weil in update() normalerweise vorher die
Zeichenfläche gelöscht wird. Wenn du update() überschreibst, also
durch deinen eigenen Code ersetzt, passiert das natürlich nicht mehr.
(Außer du würdest die Zeichenfläche wieder jedesmal löschen.)
In der Regel reicht es übrigens, wenn du in update() einfach paint()
aufrufst, also
void update(Graphics g) {
paint(g);
}
oder so ähnlich.
- Würde es dir etwas ausmachen, mir das mit dem super.paint() an einem kleinen Codebeispiel zu zeigen? Ich komme da nicht so ganz mit.
Klar.
void paint(Graphics g) {
// hier ist dein Grafik-Zeugs
// ...
super.paint(g);
}
Aber, nach meiner Erfahrung wirst du von deinen gerade gezeichneten
Grafiken anschließend nichts mehr sehen, weil super.paint() (oder
war's paintComponents(), das in super.paint() aufgerufen wird?) wohl
doch wieder die Zeichenfläche löscht. Ich könnte mich aber täuschen.
Ähm, ich will dich ja nicht entmutigen, aber vielleicht solltest du
von deinen bisherigen Experimenten mal ein wenig Abstand gewinnen und
dich erst einmal mit den Grundlagen der Java-Programmierung auseinander-
setzen. Das http://www.javabuch.de von Guido Krüger finde ich
ganz brauchbar. Dort steht auch was über die Grafikprogrammierung drin.
Erst wenn du soweit in Java fit bist, solltest du dich mit der Grafik-
programmierung beschäftigen - und auch wie diese ganzen Sachen bei
Swing so zusammenhängen. Es ist nicht trivial!
Am besten besorgst du dir noch eine anständigen Java-IDE, in der du
dir die Klassenhierarchie angucken kannst und direkt im API-Code
"rumsurfen" kannst. Eclipse (http://www.eclipse.org) ist da
zu empfehlen, auch wenn das evtl. für Einsteiger nicht so gut
verständlich ist. Am besten die Hilfe lesen.
Und lies doch gelegentlich mal die API-Doku, die du bei Sun runterladen
kannst. Da steht schon recht viel drin.
Gruß
Slyh
Ah, es funktioniert!
Für das Archiv:
Ich habe jetzt am Ende der Methode, die die Formulare zeichnen soll, super.paint(g); aufgerufen und innerhalb der paint() Methode zu Beginn.
Tut man es nicht zu beginn, löscht es die anderen Grafiken.
Vielen Dank für die Hilfe!
LazyWolf