JFrame startet bevor Panel zeichnet

KaTko

Cadet 2nd Year
Registriert
Apr. 2021
Beiträge
16
Hallo,
Der Titel ist vielleicht ein wenig doof gewählt.
Mein Problem ist dass ich gerade ein Brettspiel in Java programmiere und dabei ein JFrame benutze. Dieses enthält ein Panel, auf dessen (bei initialisierung) eine Graphic gemalt wird. Jedoch funktioniert das nur manchmal, bzw wird der Frame schneller "hochgeladen" als das Panel bemalt wird. Ich seh also nur ein leeres Panel. Wenn ich das Frame minimiere und dann wieder öffne lässt sich die Grafik sehen. Sehe ich da einerseits richtig, das Problem ist das das "bemalen" zu lange dauert, und wenn ja gibt es eine elegante Lösung das zu änder/vermeiden.
Vielen Dank
Ps: habe schon überlegt einen Timer zu machen, der das öffnen des fensters um 2-3 Sekunden verringert, würde das dann aber eigentlich doch lieber anders machen.
 
Also ohne Quellcode zu sehen ist das sehr schwer zu beurteilen, was konkret falsch läuft.
 
Wenn du ein Standard-Panel oder etwas daran angelehntes verwendest, wird dein Problem hier sein, dass du deine Grafik einmal darauf renderst und sich das Panel im Anschluss noch mindestens einmal selber neu zeichnet (bzw. zeichnen muss) und damit deine Grafik zwangsweise "übermalt".

Da gibst jetzt mehrere Möglichkeiten das zu lösen:
Du kannst die Methode dieser Komponente überschrieben, bzw. dich da dranhängen, mit der sich diese Komponente selber zeichnet und statt dessen, bzw. zusätzlich dazu deine Grafik rendern.
I.d.R. gibt es Komponenten, die dir im vorn herein die Möglichkeit über eine entsprechende Methode geben, in der du deine Zeichenroutine implementieren kannst, sodass da gleich deine Zeichenroutine angeschmissen wird, wenn sich die Komponente neu zeichnen muss.

Wenn du nur selten rendern musst/willst, könntest du statt auf ein Panel, auf dem Canvas einer passenden, grafischen Komponente zeichnen, bzw. direkt in eine Grafik (Bitmap u.ä.), die du von einer passenden Komponente anzeigen lässt.

Das Rendern in zeitlich kurzen, geeigneten Abständen ständig wiederholen. (Also so, wie es Spiele-Engines es i.d.R. machen.)
 
Zuletzt bearbeitet:
Man implementiert den Code zum Zeichnen des Spielbretts in der paint Methode der Komponente. Damit wird das Brett im immer automatisch gezeichnet, wenn das benötigt wird. Bei jeder Änderung der Größe des Frames ist das z.B. der Fall. Dann aktualisiert man den Zustand des Spielbretts und löst ein repaint aus.
Hier ist als Beispiel eine Animation, die eine vertikale Linie von links nach rechts wandern lässt. Die Animationsschleife im Beispiel ist für ein Brettspiel aber z.B. nicht notwendig, wenn das Brett sich nur bei Interaktion ändert.
Java:
import javax.swing.*;
import java.awt.*;

public class Spiel {
    public static void main(String[] args) throws Exception {
        JFrame f = new JFrame("PaintTest");
        SpielBrett p = new SpielBrett();
        f.getContentPane().add(p, BorderLayout.CENTER);
        f.setSize(640, 480);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);

        while (true) {
            Thread.sleep(10);
            p.brettAktualisieren();
        }
    }

    public static class SpielBrett extends JPanel {
        private int x = 0;

        public void brettAktualisieren() {
            x = ++x % getWidth();
            repaint();
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            // brett malen
            g.drawLine(0,0, getWidth(), getHeight());
            g.drawLine(x,0, x, getHeight());
        }
    }
}
 
Danke für die vielen Antworten. Haben mich definitiv auf den richtigen Weg gebracht und hab's nun auch gelöst :)
 
Zurück
Oben