2012-04-09 10 views
5

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?

+3

¿Cuál es su fuente? – mre

+0

@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. –

+0

+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

Respuesta

9

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 solo paint(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 un JFrame, o una JApplet, o una JDialog, o una restricción de un diseño de una JPanel, o una JInternalFrame, 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 enfoque JComponent 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 (usando pack()). 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:

  1. llamada getGraphics() para un Graphics o createGraphics() para un Graphics2D
  2. Dibuje la pintura personalizada a esa instancia gráficos
  3. Eliminar el ejemplo gráficos
  4. llamada repaint() en la etiqueta.
+1

Hay algunos beneficios para obtener el delegado de IU del panel. – trashgod

+0

@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? –

+0

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

6

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.

Double Buffering

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.

translated co-ordinates

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 +.

+0

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

+0

@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

+0

@Richante también, ¿por qué no es una forma de hacer doble buffering? Se usa con bastante frecuencia para ese mismo propósito. – ApprenticeHacker

5

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.

Cuestiones relacionadas