Ich habe gerade begonnen, Videospiele zu programmieren, und ich habe gehört, dass das Zeichnen auf einem JPanel und das Anfügen dieses Panels an einen JFrame besser ist, als einfach auf den JFrame zu zeichnen. Ich habe mich nur gefragt, warum ist das besser?Warum wird ein JPanel besser angehängt?
Antwort
Es ist besser, aus verschiedenen Gründen, einschließlich:
- In den meisten Swing-Komponenten, individuelle Malerei durch Überschreiben der
paintComponent(Graphics)
Verfahren erreicht wird. Swing-Behälter der obersten Ebene (z. B.JFrame
,JApplet
,JWindow
) haben nurpaint(Graphics)
. Als Ergebnis der geläufigen Methode zum Malen vergessen Menschen, die antworten, oft diesen Unterschied zwischen herkömmlichen und Top-Level-Komponenten und schlagen daher dumme Ratschläge vor. ;) - A
JComponent
kann in einemJPanel
oder einJInternalFrame
oder einem an einJFrame
oder einJApplet
oder einJDialog
oder einen Constraint eines Layouts hinzugefügt werden ..Gerade wenn Sie denken, dass Ihre GUI komplett ist, sagt der Client "Hey, wäre es nicht toll, in eine Werkzeugleiste zu werfen & bieten Sie es auch als Applet?" Der AnsatzJComponent
passt sich leicht daran an. - Wie von Richante erklärt (komplett mit Code!), Ist es einfacher, die Koordinaten zu berechnen, die für die Bemalung der benutzerdefinierten Komponente erforderlich sind, und wenn sie eine bevorzugte Größe hat, die Größe
JFrame
auf "genau die richtige Größe" zu setzen um die GUI zu enthalten (unter Verwendung vonpack()
). Dies ist insbesondere dann der Fall, wenn andere Komponenten hinzugefügt werden.
nun zwei kleinere Unstimmigkeiten mit dem Rat angeboten.
Wenn die gesamte Komponente maßgefertigt ist, kann es besser sein, einfach eine BufferedImage
in eine ImageIcon
/JLabel
Combo zu legen. Hier ist ein Beispiel für painting to an image.
Wenn es an der Zeit, sie aktualisieren kommt:
- Anruf
getGraphics()
für eineGraphics
odercreateGraphics()
für eineGraphics2D
- Zeichnen Sie die benutzerdefinierte Malerei zu dieser Grafik Instanz
- Entsorgen Sie die Grafik Instanz
- Anruf
repaint()
auf das Etikett.
Es gibt einige Vorteile beim Abrufen des UI-Delegaten des Panels. – trashgod
@trashgod Danke für die Erinnerung an mich. Es gibt jedoch einige Dinge, die ich nicht verstehe. 1) Es scheint, dass die Benutzeroberfläche des Panels aus ['JPanel.getUI()'] (http://docs.oracle.com/javase/7/docs/api/javax/swing/JPanel.html#getUI%28) stammt % 29), ist das richtig? 2) Warum sollte eine 'JComponent' nicht einen eigenen UI-Delegaten haben (haben)? 3) Sollte ich meine eigenen Fragen zu diesen Fragen stellen? –
Eine 'JComponent' hat keinen Delegaten selbst, aber sie stellt eine grundlegende Infrastruktur für Unterklassen bereit, die dies tun. [* Wie schreibe ich eine benutzerdefinierte Swing-Komponente *] (http://today.java.net/pub/a/today/2007/02/22/how-to-write-custom-swing-component.html) ist ein Beispiel. – trashgod
Es ist eine einfache Möglichkeit, Double Buffering zu tun.
Lassen Sie mich etwas näher ausführen. Um in Videospielen das durch Neuzeichnen verursachte Flimmern zu vermeiden und glattere Grafiken anzuzeigen, verwenden Leute normalerweise eine doppelte Pufferung. Sie erstellen eine Offscreen-Oberfläche, zeichnen alles darauf und zeigen dann die gesamte Off-Screen-Oberfläche auf dem Bildschirm auf einmal an.
In Java2D und Swing, der einfachste Weg, dies zu tun, ist zu Ihrem Spiel Sprit Zeichnung auf einem JPanel einfach tun, und fügen Sie dann den JPanel zu einem JFrame.
Zweitens, indem Sie Dinge auf einem JPanel zeichnen, erlauben Sie, dass mehr GUI-Widgets und andere grafische Objekte auf dem JFrame angezeigt werden, ohne dass Sie sie manuell in der Spielschleife malen müssen. Zum Beispiel Buttons, Menüs, andere Panels, sogar andere Rendering JPanels.
Drittens ermöglicht es Ihnen, automatisch übersetzte Koordinaten für Ihr Spiel zu verwenden. Sie können alles von oben links nach unten rechts zeichnen, ohne sich um die Fenstermanager-spezifischen Dinge wie Fensterrahmenbreiten, Aufgabenbereiche, Titel usw. kümmern zu müssen!
Darüber hinaus ist dies nicht nur eine Konvention nur von Game Programmierer in Java verwendet. Erstellen eines separaten Spiel Board, Rendern Panel oder Grafik Widget ist sehr beliebt bei der Programmierung von Spielen mit einer Bibliothek mit einer internen Hauptschleife wie ein GUI-Toolkit. Sie können ein Benutzerformular in Windows Forms und ein Zeichenbrett in GTK + verwenden.
Ein Bild auf einem JPanel zu zeichnen und dann das JPanel zu dem JFrame hinzuzufügen, ist nicht, wie Doppelpufferung durchzuführen. Ich bin mir ziemlich sicher, dass Sie in einem JFrame doppelt puffern können. – Richante
@Richante Ich weiß sehr gut, Sie können Puffer in einem JFrame doppelt, was ich sagte, war mit einem JPanel ist der _easiest_ Weg, nicht die _only_ Möglichkeit, Doppel-Pufferung mit Java2D und Swing. – ApprenticeHacker
@Richante auch, warum ist es nicht eine Möglichkeit, Doppel-Pufferung zu tun? Es wird ziemlich oft für genau diesen Zweck verwendet. – ApprenticeHacker
Der JFrame enthält Dinge wie das Menü, Titelleiste und Rahmen. Wenn Sie also auf Koordinaten verweisen, müssen Sie diese berücksichtigen. Sie können auch entscheiden, dem Rahmen eine Menüleiste oder andere Komponenten hinzuzufügen. Wenn sich Ihr Bild in einem JPanel befindet, ändert sich nicht, wie Sie auf Koordinaten verweisen müssen.
Zum Beispiel versuchen:
public class Test extends JFrame {
public Test() {
super();
setVisible(true);
setBounds(100, 100, 200, 100);
}
@Override
public void paint(Graphics g) {
g.fillRect(0, 0, 50, 50);
}
public static void main(String[] args) {
new Test();
}
}
und Sie werden sehen, dass das schwarze Quadrat nicht quadratisch ist! Denn (0, 0) ist die obere linke Ecke des gesamten Rahmens, nicht die Ecke des sichtbaren Bereichs.
- 1. Warum wird jsessionid an jede URL angehängt?
- 2. Warum wird das nur einmal angehängt?
- 3. Docker wird nicht an ein Bild angehängt
- 4. C++ Warum wird die Datei nicht angehängt oder überschrieben?
- 5. JPanel wird als Null übergeben
- 6. Mailgun-Anhang wird nicht angehängt
- 7. Warum wird `cat` nicht an eine` Datei'-Verbindung angehängt?
- 8. Warum wird die Java-Komponente JPanel nicht verschwinden?
- 9. addMouseListener für ein JPanel
- 10. Warum wird dieses JPanel immer noch neu gezeichnet?
- 11. Swing JPanel wird nicht repaint
- 12. BorderLayout - JPanel in JPanel
- 13. JPanel auf einem JPanel in einem JFrame wird nicht angezeigt
- 14. JPanel Sichtbarkeit
- 15. Eclipse-Programm JPanel wird nicht laufen
- 16. Element auswählen, das an ein Eingabeelement angehängt wird HTML
- 17. Warum JPanel nie einen Reapint aufruft
- 18. Erhalten Fokus auf ein JPanel
- 19. Warum ist `[` besser als `Teilmenge`?
- 20. Zeichnen über ein JPanel und Hinzufügen der JPanel zu JFrame
- 21. JFileChooser eingebettet in ein JPanel
- 22. Warum wird das W3C-Boxmodell als besser angesehen?
- 23. Eingang wird nicht beim zweiten Klick angehängt
- 24. Wie wird GestureDetector an eine ListPreference angehängt?
- 25. String-Literal wird nicht an DOM angehängt
- 26. Warum werden meine JPanel-Komponenten automatisch ausgefüllt?
- 27. Open Stack Volume wird nicht angehängt
- 28. JComponent wird nicht in JPanel gezeichnet
- 29. Warum kann ich kein JPanel einzeichnen?
- 30. Alle Ereignishandler an ein Element angehängt
Was ist Ihre Quelle? – mre
@mre Es ist etwas, das ich allgemein empfehle (oder nah dran - siehe meine Antwort), aber ich bin auch daran interessiert, die genaue Quelle des OPs zu dieser Information zu hören. Zu der Person, die die Frage stellt. Dies würde mit dieser kleinen zusätzlichen Informationsmenge zu einer "guten Frage" werden. –
+1, eine der wenigen Java-Fragen, auf die ich die Antwort kenne. Einmal ein [Java RPG Game] erstellt (https://github.com/intermediate-hacker/Pro_RPG), hat es sehr genossen. :) – ApprenticeHacker