Mesmo chamando repaint() o JComponent ignora o paintComponent, por algum motivo que eu desconheço. O único jeito foi dar um override no paint() e chamar o paintComponent na mão. Mas isso não é uma boa prática, segundo a própria Sun. Alguém consegue entender isso ??? Por que o puto do JComponent não gosta de chamar o paintComponent !!!???
Executem o código abaixo que vcs vão entender exatamente o que eu quero e o problema:
import java.awt.*;
import javax.swing.*;
public class VideoList extends JComponent {
private static final boolean DEBUG = true;
private ListModel model;
private JScrollPane scroll;
private JPanel panel;
public VideoList() {
this(null);
}
public VideoList(ListModel model) {
super();
this.model = model;
panel = new JPanel();
panel.setLayout(new FlowLayout());
scroll = new JScrollPane(panel);
setLayout(new BorderLayout());
add(BorderLayout.CENTER, scroll);
}
public void setModel(ListModel model) {
this.model = model;
}
public ListModel getModel() {
return model;
}
protected void paintComponent(Graphics g) {
if (DEBUG) System.out.println("PAINTCOMPONENT !!!");
super.paintComponent(g);
panel.removeAll();
if (model != null) {
synchronized(model) {
for(int i=0;i<model.getSize();i++) {
panel.add((Component) model.getElementAt(i));
}
}
}
scroll.revalidate();
}
// COMENTEI PARA VCS ENTENDEREM QUE SEM ISSO NAO FUNCIONA !!!
/*
public void paint(Graphics g) {
if (DEBUG) System.out.println("PAINT !!!");
super.paint(g);
paintComponent(g);
}
*/
public static void main(String [] args) throws Exception {
JFrame frame = new JFrame("Testando VideoList");
VideoList vl = new VideoList(new DefaultListModel());
DefaultListModel model = (DefaultListModel) vl.getModel();
frame.setContentPane(vl);
frame.setSize(200, 200);
frame.setVisible(true);
Thread.sleep(5000);
JLabel label = new JLabel("Sergio");
model.addElement(label);
vl.repaint();
System.out.println("FOI !!!");
}
}
Com isso o seu scroll ocupa toda a área de pintura do seu componente…
Dessa maneira o swing sabe que não precisa chamar paintComponent e chama apenas o paintChidren…
Vc até pode testar trocando o Layout para Flow ao invés do Border…
Então tudo que eu fiz foi dar um override no paintChildren que tudo funcionou as mil maravilhas, sem ter que dar um override no paint().
O Swing é cheio de pegadinhas…
Outra: Chamar repaint() numa scroll é inútil. Pra mim só funcionou o tal do revalidate(), isto é, quando eu adiciono um elemento na minha VideoList, tenho que chamar revalidate no scroll e não repaint. (Veja isso no código acima!)
O loprão é sinistro no swing…jah me ajudou algumas vezes com problemas nele…
Agora,esses bugs q por vezes descobrimos no swing é q mata…uma vez perdi3 dias para arrumar uma tela para depois descobri q era um Bug do swing lah no site da Sun… :roll: