2011-01-13 19 views
7

JLayeredPane permite apilar varios componentes uno encima del otro usando JLayeredPane.add(Component, Integer). Los componentes en "capas" superiores se muestran en la parte superior de los Componentes en las "capas" inferiores.JLayeredPane versus Container layering

Container.add(Component, int) proporciona un mecanismo similar por el que los componentes con índices inferiores se muestran en la parte superior de los componentes con índices más altos.

Tenga en cuenta que el primer mecanismo utiliza Entero y el segundo mecanismo utiliza int. Además, uno representa valores altos sobre los bajos, y el otro hace lo contrario. No mezcle los dos :)

Mi pregunta es: ¿de qué sirve usar JLayeredPane cuando el contenedor ya proporciona el mismo mecanismo? ¿Una capa de componentes es mejor que la otra?

ACTUALIZACIÓN: También hay Container.setComponentZOrder(Component, int) a considerar.

Respuesta

6

responder a mi propia pregunta:

Container.add(Component, int)Container.setComponentZOrder(Component, int) y son prácticamente idénticos. El primero invoca removeNotify() mientras que el último no (por motivos de rendimiento).

El contenedor de capas solo funciona si JComponent.isOptimizedDrawingEnabled() devuelve falso. Una implementación que sucede que devuelve falso es ... lo adivinó: JLayeredPane

No se recomienda el uso de Envases de contenedor porque puede tener unexpected side-effects.

Finalmente, vale la pena señalar que, aunque Container declara add(Component, int), en realidad no pinta adecuadamente los componentes en capas. JComponent y sus subclases do.

Otro hallazgo interesante: nunca invoque repaint() en un hijo de JLayeredPane. Esto hará que el componente se pintee en la parte superior independientemente de su orden z. Solo debe invocar repintado() en el propio JLayeredPane.

+0

Re "nunca invoque repintado() en un hijo de JLayeredPane": Tengo curiosidad acerca de con qué tipo de componente hijo encontró esto. Me encontré con [un problema similar] (http://stackoverflow.com/questions/5668721/jmenuitems-painting-over-higher-components-in-jlayeredpane) y determiné que, en mi caso al menos, era un problema con JMenuItems específicamente. Se comportan como si siempre estuvieran en la parte superior (a menos que sean transparentes). –

+0

@ Aaron, no recuerdo qué componente utilicé, pero cuando lo piensas, tiene sentido que todos los componentes se comporten, siempre están en la parte superior. paint() pretende suponer que establecerá los límites del clip para evitar que dibuje fuera de los límites deseados. Cuando invoca repintar() directamente en un componente secundario (sin límites), básicamente le está pidiendo que ignore a su padre. En otras palabras, esto no es un error en la implementación de Swing. Es un error del usuario. – Gili

+0

En realidad eso no es correcto. Consulte [Pintura en AWT y Swing] (http://java.sun.com/products/jfc/tsc/articles/painting/), específicamente la sección de Procesamiento de pintura.Establece que cuando se llama a 'repaint()' en un JComponent, RepaintManager usa el rectángulo del clip y las propiedades 'opaque' y' isOptimizedDrawingEnabled' del componente para determinar el componente 'raíz' desde el que debe comenzar la operación de pintura. La mayoría de los componentes, de hecho, no se comportan como si siempre estuvieran en la parte superior (es decir, 'alwaysOnTop()' devuelve 'false' de manera predeterminada). –

0

Mi opinión sobre esto es que las funciones Container.add(Component,int) y JLayeredPane.add(Component,Integer) establecen el componente que se agrega en un índice determinado. Es entonces este índice el que utilizan los administradores del diseño para manejar la posición, el diseño y el orden de la pintura del componente. Creo que JLayeredPane.setLayer(Component c, int layer) es más lo que buscas en cuanto a capas. Está creado específicamente para superponer los componentes. Solo mi dos sentidos.

Cuestiones relacionadas