2012-08-31 13 views
5

Mam JFrame z 2 JPanel w nim: a PaintPanel (z metodą paint()) i ButtonPanel (z przyciskami). Kiedy wywołuję repaint() z PaintPanel (ale kliknięcie przycisku) przycisk ButtonPanel jest malowany w PaintPanel! To nie jest klikalne ani nic, tylko tam jest.JButton skopiowany podczas odświeżania?

Starałem się odtworzyć problem z tym kodem:

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();   
    } 
} 

sould Ten odtworzyć problem mam (przepraszam za dziwnych oznaczeń kodowych, nie wydaje się uzyskać to prawo).

Mam nadzieję, że ktoś z was wie, co się tu dzieje, bo nie ...

+1

Takie artefakty wykończeniowych często wynikają z braku na cześć [krycie] (http://java.sun.com/products/jfc/tsc/articles/painting/index.html#props) Właściwość. Co więcej, "Programy Swing powinny przesłonić' paintComponent() 'zamiast przesłonić' paint() '." - [* Malowanie w AWT i Swing: The Paint Methods *] (http://java.sun.com/products/jfc /tsc/articles/painting/index.html#callbacks). – trashgod

Odpowiedz

6

Przede wszystkim należy zastąpić paintComponent() zamiast paint(). Jest to część najlepszych praktyk w Swingu, jeśli chodzi o dostosowywanie paneli.

drugie, tutaj jest kod, który pracuje dla mnie (nie wiem dlaczego twoje nie mimo: 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

Często chcesz mieć super.paintComponent (g); jako pierwszy wiersz w nadpisanej metodzie paintComponent. Oczyści to wszystko, czego nie rysujesz w tym konkretnym wezwaniu do odświeżenia. – mrranstrom

+0

@mrranstrom Zgadza się! Naprawiłem mój przykład, dzięki! – aymeric

+2

+1 dla paintComponent & super.paintCompont. @Aymeryczny, o którym musisz pamiętać, obiekt Graphics jest ponownie wykorzystywany, więc jeśli nie poświęcisz czasu, aby się upewnić, że najpierw go wyczyścisz, otrzymasz nieoczekiwane artefakty farby – MadProgrammer

Powiązane problemy