2012-10-06 22 views
6

Tengo un componente personalizado que amplía JComponent, que anula el método paintComponent (Graphics g) pero cuando intento agregarlo a mi JPanel simplemente no funciona, no se dibuja nada. Aquí está mi código:JComponent no Drawing to JPanel

public class SimpleComponent extends JComponent{ 

int x, y, width, height; 

public SimpleComponent(int x, int y, int width, int height){ 
    this.x = x; 
    this.y = y; 
} 

@Override 
public void paintComponent(Graphics g){ 
    Graphics2D g2 = (Graphics2D) g; 
    g2.setColor(Color.BLACK); 
    g2.fillRect(x, y, width, height); 
} 
} 


public class TestFrame{ 
public static void main(String[] args){ 
    JFrame frame = new JFrame(); 
    JPanel panel = new JPanel(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    panel.setPreferredSize(new Dimension(400, 400)); 
    frame.add(panel); 
    frame.pack(); 
    frame.setResizable(false); 

    SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
    panel.add(comp); 
    frame.setVisible(true); 
} 
} 

Respuesta

4

Funciona bien - el componente se añade a la JPanel, pero ¿cómo es de grande? Si marca esta después de la interfaz gráfica de usuario se ha rendido, lo más probable es encontrar que el tamaño de su componente es 0, 0.

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
panel.add(comp); 
frame.setVisible(true); 

System.out.println(comp.getSize()); 

Considere hacer que su JComponent anular getPreferredSize y devolver una dimensión que tenga sentido:

public Dimension getPreferredSize() { 
    return new Dimension(width, height); 
} 

Si desea utilizar la x y la y, también puede omitir getLocation().

Editar
¡También debe establecer los campos de ancho y alto!

public SimpleComponent(int x, int y, int width, int height) { 
    this.x = x; 
    this.y = y; 
    this.width = width; // *** added 
    this.height = height; // *** added 
} 
+0

Eso es realmente extraño, he replicado este problema en Windows y Mac y siempre es exactamente el mismo – lilroo

+0

Ah, el ancho y alto está establecido en cero – lilroo

+0

Después de recordar establecer los campos de ancho y alto todavía no funcionaba pero cuando anulé el método getPreferredSize() funcionó. – lilroo

-2

Whoaa! ¡Absolutamente no es la respuesta correcta!

La primera absoluta CARDINAL SIN que se ha comprometido es hacer todo esto en un hilo no EDT !!! No hay espacio para explicar esto aquí ... solo hay alrededor de 30 mil millones de lugares en la red para aprender sobre esto.

Una vez que todo este código se ejecuta en un Runnable en el EDT (Evento de Despacho de rosca), entonces:

Usted no que sobreescribir preferredSize (aunque puede hacerlo si lo desea), pero ... necesitas configurarlo

Es absolutamente no debe establecer los tamaños (height y width o setSize()) directamente!

Lo que HACER necesidad de hacer es conseguir la java.awt.Container, panel, en su ejemplo, "poner a sí misma" ... hay un método Container.doLayout(), pero como se dice en la documentación de la API:

Hace que este contenedor despliegue sus componentes. La mayoría de los programas deben llamar al directamente, pero deben invocar el método de validación .

la solución, por tanto, es:

SimpleComponent comp = new SimpleComponent(10, 10, 100, 100); 
comp.setPreferredSize(new Dimension(90, 90)); 
panel.add(comp); 

// the key to unlocking the mystery 
panel.validate(); 

frame.setVisible(true); 

Por cierto, por favor beneficiarse de mi experiencia: He pasado horas y horas rasgando mi pelo a cabo tratando de entender todo esto validate, invalidate, paintComponent, paint, etc ... y cosas Todavía siento que solo he arañado la superficie.

+0

Consulte http://stackoverflow.com/questions/10866762/use-of-overriding-getpreferredsize-instead-of-using-setpreferredsize-for-fix?rq=1 –

+0

OK gracias ... pero si fuera la persona quien desestimó mi respuesta aquí que no fue terriblemente útil para los futuros visitantes a esta pregunta: mi respuesta es mucho, mucho mejor que la respuesta aceptada, y el matiz sobre 'setPreferredSize' /' getPreferredSize' no cambia eso. –

+0

¡Oh ... veo que respondiste la respuesta aceptada! Pero con un representante de 214k seguramente debes saber que cada punto que dije es correcto, y que tu respuesta verdaderamente, um, cómo lo pondré, ¡deja espacio para la mejora! –