2012-08-31 12 views
5

Tengo un JFrame con 2 JPanel en él: un PaintPanel (con un método paint()) y un ButtonPanel (con botones). Cuando invoco el repaint() del PaintPanel (pero haciendo clic en el botón), el botón del ButtonPanel se está pintando en el PaintPanel. No se puede hacer clic ni nada, solo está allí.J ¿Se ha copiado el botón para volver a pintar?

Me trataron de recrear el problema con este código:

public class Main { 

    public static void main(String[] args) { 
     JFrame frame = new JFrame("frame"); 
     frame.setSize(400,400); 
     frame.setLayout(new GridLayout(2,1)); 
     PaintPanel paint = new PaintPanel(); 
     ButtonPanel buttons = new ButtonPanel(paint); 
     frame.add(paint); 
     frame.add(buttons); 
     frame.setVisible(true); 
    } 
} 

public class PaintPanel extends JPanel{ 
    public void paint(Graphics g){ 
     g.drawRect(10, 10, 10, 10); 
    } 
} 

public class ButtonPanel extends JPanel implements ActionListener{ 

    private PaintPanel paintPanel; 

    public ButtonPanel(PaintPanel paintPanel){ 
     this.paintPanel=paintPanel; 
     JButton button = new JButton("button"); 
     button.addActionListener(this); 
     add(button); 
    } 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     paintPanel.repaint();   
    } 
} 

Este sould recrear el problema que tengo (lo siento por las marcas de código impares, parece que no puede hacerlo bien).

realmente espero uno de ustedes sabe lo que está sucediendo aquí porque yo no ...

+1

Tales artefactos de representación a menudo surgen de no cumplir con la [opacidad] (http://java.sun.com/products/jfc/tsc/articles/painting/index.html#props) propiedad. Además, "los programas Swing deben anular' paintComponent() 'en lugar de anular' paint() '." - [* Pintar en AWT y Swing: The Paint Methods *] (http://java.sun.com/products/jfc /tsc/articles/painting/index.html#callbacks). – trashgod

Respuesta

6

En primer lugar, se debe anular paintComponent() en lugar de paint(). Es parte de las mejores prácticas en Swing cuando se trata de hacer algunas personalizaciones de panel.

En segundo lugar, aquí está el código que funciona para mí (no sé por qué el suyo no sin embargo: S):

public class Main { 

    public static void main(String[] args) { 

     JFrame frame = new JFrame("frame"); 
     frame.setSize(400, 400); 
     // frame.setLayout(new GridLayout(2, 1)); 
     PaintPanel paint = new PaintPanel(); 
     ButtonPanel buttons = new ButtonPanel(paint); 
     // frame.add(paint); 
     // frame.add(buttons); 
     frame.setVisible(true); 

     JPanel pan = new JPanel(new BorderLayout()); 
     pan.add(paint); 
     pan.add(buttons, BorderLayout.SOUTH); 
     frame.add(pan); 

    } 
} 

class PaintPanel extends JPanel { 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.setColor(new Color(new Random().nextInt())); 
     g.drawRect(10, 10, 10, 10); 
    } 
} 

class ButtonPanel extends JPanel implements ActionListener { 

    private final PaintPanel paintPanel; 

    public ButtonPanel(PaintPanel paintPanel) { 

     this.paintPanel = paintPanel; 
     JButton button = new JButton("button"); 
     button.addActionListener(this); 
     add(button); 
    } 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     if (getParent() != null) { 
      getParent().repaint(); 
     } 
    } 
} 
+1

A menudo quiere tener super.paintComponent (g); como la primera línea en su método paintComponent reemplazado. Va a borrar todo lo que no está dibujando en esa llamada particular para volver a pintar. – mrranstrom

+0

@mrranstrom ¡Eso es! Arreglé mi ejemplo, ¡gracias! – aymeric

+2

+1 para paintComponent y super.paintCompont. @aymeric tienes que recordar que el objeto Graphics se reutiliza, por lo que si no te tomas el tiempo para asegurarte de haberlo limpiado primero, terminarás con artefactos de pintura inesperados – MadProgrammer

Cuestiones relacionadas