Cara, não é bem isso, o que acontece é que o que vc envia pelo socket (essa parte, todos concordamos, mas só pra introduzir) é uma estrutura onde tá escrito “a minha classe é xxx.yyy.Emailrec”. O cliente vai tentar carregar essa classe.
O objetivo disso é que alguém no futuro possa fazer:
em = (Emailrec) painel;
o fato de todas essas classes existirem no seu cliente não necessariamente quebra o data hiding (embora eu seja cético ante a necessidade de passar um JPanel pelo socket). Mas se vc quer independência da implementação, vc não pode usar herança.
eu não sei exatamente o que é diferente entre todas as implementações possíveis, mas antes de sair brincando com class loaders, descubra qual é o mínimo que vc pode enviar e ainda assim ter escolhas. Eu explico…
Vc tem que mandar código?? Vc sobrescreve algum dos métodos do JPanel? Tem polimorfismo aí??
Se não tem, ótimo, refatora seus objetos pra que eles usem um JPanel em vez de serem um, e envie instãncias de JPanel puro.
Se tem código, vc tem que enviar esse código. Daí as possibilidades abrem muito, a mais simples é obviamente mandar os .class pro cliente, e uma boa opção é usar o java.net.URLClassLoader, se vc tem um webserver que pode abrigar seus jars, fica bíltifou.
Outras opções (que dependem do quanto suas subclasses podem sobrescrever do código do JPanel) são criar uma classe específica, que delega o código em questão pra alguém, e com esse delegado vc pode:
- deixar o .class disponível na web (pra acessar com URLClassLoader)
- abstrair mais ainda e pular pra uma linguagem de scripts (Groovy?) que vc compile na hora e use. Por exemplo:
public void paintComponent(Graphics g) {
if (delegate == null) return;
delegate.invokeMethod("paintComponent", new Object[]{this, g});
}
public void setDelegate(GroovyObject delegate) {
this.delegate = delegate;
}
Boa sorte e []s!