Acabo de comenzar a codificar videojuegos y he oído que hacer todo el dibujo en un JPanel y unir ese panel a un JFrame es mejor que simplemente recurrir al JFrame. Me preguntaba por qué es esto mejor?¿Por qué es mejor adjuntar un JPanel?
Respuesta
Es mejor, por diversas razones, entre ellas:
- En la mayoría de los componentes Swing, pintura personalizada se logra reemplazando el método
paintComponent(Graphics)
. Los contenedores Swing de nivel superior (por ejemplo,JFrame
,JApplet
,JWindow
) tienen solopaint(Graphics)
. Como resultado del método común para pintar, las personas que responden a menudo se olvidan de esta diferencia entre componentes comunes y de nivel superior, y por lo tanto sugieren consejos tontos. ;) - A
JComponent
se puede añadir a unJFrame
, o unaJApplet
, o unaJDialog
, o una restricción de un diseño de unaJPanel
, o unaJInternalFrame
, o una ..Justo cuando crees que tu GUI está completa, el cliente dice "Oye, ¿no sería genial incluir una barra de herramientas & ofreciéndolo como un applet también?" El enfoqueJComponent
se adapta fácilmente a eso. - Según lo explica Richante (¡con el código!), Es más fácil calcular las coordenadas necesarias para pintar el componente personalizado, y si tiene un tamaño preferido, para que el tamaño
JFrame
sea "exactamente el tamaño correcto" para contener la GUI (usandopack()
). Ese es especialmente el caso cuando se agregan otros componentes también.
Ahora, dos pequeños desacuerdos con el asesoramiento ofrecido.
Si todo el componente está pintado de encargo, tal vez sería mejor poner simplemente un BufferedImage
dentro de un combo ImageIcon
/JLabel
. Aquí hay un ejemplo de painting to an image.
Cuando llega el momento de actualizarlo:
- llamada
getGraphics()
para unGraphics
ocreateGraphics()
para unGraphics2D
- Dibuje la pintura personalizada a esa instancia gráficos
- Eliminar el ejemplo gráficos
- llamada
repaint()
en la etiqueta.
Hay algunos beneficios para obtener el delegado de IU del panel. – trashgod
@trashgod Gracias por recordarme. Sin embargo, hay algunas cosas que no entiendo. 1) Parece que la interfaz de usuario del panel se obtiene de ['JPanel.getUI()'] (http://docs.oracle.com/javase/7/docs/api/javax/swing/JPanel.html#getUI%28 % 29), ¿es correcto? 2) ¿Por qué un 'JComponent' no (tiene/tiene acceso) a un delegado de IU propio? 3) ¿Debo comenzar mi propia (s) pregunta (s) sobre estos asuntos? –
Un 'JComponent' no tiene ningún delegado, pero proporciona cierta infraestructura básica para las subclases que sí lo hacen. [* Cómo escribir un componente personalizado Swing *] (http://today.java.net/pub/a/today/2007/02/22/how-to-write-custom-swing-component.html) es una ejemplo. – trashgod
Es una forma fácil de realizar doble búfer.
Déjame elaborar un poco. En los videojuegos, para evitar el parpadeo causado por el redibujado y mostrar gráficos más suaves, las personas suelen usar doble almacenamiento en búfer. Crean una superficie fuera de pantalla, dibujan todo sobre eso y luego muestran toda la superficie fuera de la pantalla en la pantalla de una vez.
En Java2D y Swing, la manera más fácil de hacer esto, es simplemente hacer su dibujo juego de sprites en un JPanel, y luego añadir el JPanel a un JFrame.
En segundo lugar, dibujando cosas en un JPanel, permite que se visualicen más widgets de GUI y otros objetos gráficos en el JFrame sin tener que pintarlos manualmente en el bucle del juego. Por ejemplo botones, menús, otros paneles, incluso otros PDF de renderización.
En tercer lugar, le permite usar coordenadas traducidas automáticamente para su juego. Puede dibujar todo desde la parte superior izquierda a la inferior derecha sin tener que preocuparse por las cosas específicas del administrador de ventanas como el ancho de los bordes de la ventana, paneles de tareas, títulos, etc.
Por otra parte, esto no es sólo una convención única de juego utilizado por los programadores en Java. Creación de un Game Board, Render Panel o El widget de gráficos es bastante popular cuando se programan juegos que usan una biblioteca con un mainloop interno como GUI Toolkit. Puede usar un formulario de usuario en Windows Forms y un Drawing Board en GTK +.
Dibujar una imagen en un JPanel y luego agregar JPanel al JFrame no es cómo hacer el doble almacenamiento en el búfer. Estoy bastante seguro de que puedes duplicar el búfer en un JFrame. – Richante
@Richante Sé muy bien que puede duplicar el búfer en un JFrame, lo que dije fue que usar un JPanel es la manera más fácil, no la única manera de hacer doble almacenamiento en búfer con Java2D y Swing. – ApprenticeHacker
@Richante también, ¿por qué no es una forma de hacer doble buffering? Se usa con bastante frecuencia para ese mismo propósito. – ApprenticeHacker
El JFrame incluye elementos como el menú, la barra de título y el borde. Por lo tanto, cuando te refieres a las coordenadas debes contabilizarlas. También puede decidir agregar una barra de menú u otros componentes al marco. Si su pintura está en un JPanel, esto no cambiará la forma en que necesita consultar las coordenadas.
Por ejemplo, trate de:
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();
}
}
y verá que el cuadrado negro no es cuadrada! Porque (0, 0) es la esquina superior izquierda de todo el fotograma, no la esquina del área visible.
- 1. JPanel Sustitución con JPanel en un JFrame
- 2. ¿Qué es un mejor diseño?
- 3. ¿Qué contrato (Diseño por contrato) es mejor?
- 4. ¿Por qué ENUM es mejor que INT
- 5. ¿Por qué es mejor usar filter_input()?
- 6. Por qué ArrayDeque es mejor que LinkedList
- 7. JPanel tamaño por componentes internos
- 8. JPanel dice que es opaco, ¿qué significa eso?
- 9. ¿Qué es mejor y por qué? RaphaelJS o HTML5 Canvas?
- 10. ¿Es esto un cierre? Si es así, ¿por qué?
- 11. ¿Qué caso es mejor?
- 12. Desplazamiento de un JPanel
- 13. JFileChooser incrustado en un JPanel
- 14. ¿Qué es mejor?
- 15. ¿Por qué es mejor struct con menos de 16 bytes?
- 16. SVN? VSS? ¿Por qué es uno mejor que el otro?
- 17. ¿Por qué es mejor el mergesort para listas enlazadas?
- 18. ¿Por qué es un puntero
- 19. SVN Repository Structure - ¿Por qué es esto mejor?
- 20. ¿Por qué NoSQL es mejor para "escalar" que RDBMS?
- 21. MVC: ¿Qué es mejor, un gran repositorio por db o uno por entidad comercial?
- 22. Agregar JScrollPane a un JPanel
- 23. ¿Por qué el uso es mejor que el uso?
- 24. Cuál es mejor usar y por qué en C#
- 25. ¿Por qué es mejor administrar explícitamente matrices en OpenGL?
- 26. ¿Por qué `boost :: any` es mejor que` void * `?
- 27. ¿Qué es mejor: secuencia global única vs. secuencia por tabla?
- 28. agregar JMenuBar a un JPanel?
- 29. Agregue un JFreeChart en JPanel
- 30. Alias variable de C++: ¿qué es eso exactamente y por qué es mejor desactivarlo?
¿Cuál es su fuente? – mre
@mre Es algo que comúnmente recomiendo (o cerca de eso - vea mi respuesta), pero también me interesa escuchar la fuente exacta del OP sobre esa información. A la persona que hace la pregunta. Esto se convertiría en una 'buena pregunta' con esa pequeña cantidad extra de información. –
+1, una de las pocas preguntas de Java que conozco como respuesta. Una vez creado un [Juego de rol de Java] (https://github.com/intermediate-hacker/Pro_RPG), lo disfruté muchísimo. :) – ApprenticeHacker