Já há algum tempo tenho uma dúvida. Desenvolvo aplicações desktop utilizando Java e procuro sempre usar o padrão MVC. Só que às vezes os programas precisam efetuar um processamento longo (recuperar e manipular um conjunto de clientes da base de dados, por exemplo), e, para que o usuário não fique com a impressão de que o programa travou, eu vou atualizando a tela aos poucos, conforme os resultados são obtidos.
O problema é que, para fazer isto, minha camada de controle precisa manipular minha camada de apresentação, usando o [i]SwingUtilities.invokeAndWait()[/i]. Mas, pelo que eu entendo do padrão MVC, a camada de controle não deveria se preocupar com qual objeto da camada de visão o está acessando, para que seja possível, por exemplo, portar uma aplicação desktop para web sem maiores transtornos do que criar novas classes na camada de visão. Meu entendimento está incorreto? alguém tem alguma sugestão?
Um jeito “limpinho” de lidar com esses casos é você passar uma interface de callback pra camada de negócios e essa camada sim é que faz o invokeAndWait conforme recebe atualizações.
Dei uma olhada no tutorial. Parece que atende ao que eu preciso. E pensar que estou com o Design Patterns lá em casa mas ainda não tive tempo de ler… :oops:
Luca
O foxtrot parece ser bem simples de usar, mas não sei se vale vale a pena embarcar em um projeto que não é atualizado desde 2003…
O spin me pareceu meio complicado, e acho que acabaria trocando um problema de alto acoplamento por um de complexidade de código. Com relação ao SwingWorker, no trabalho ainda estou amarrado ao maldito 1.4!!! Mas obrigado pelas dicas!
mister__m
Você poderia dar um pequeno exemplo ou indicar um lugar onde posso estudar essa técnica?
Obrigado a todos pelas sugestões. Se alguém mais quiser dar uns pitacos…
[quote=pango]
O foxtrot parece ser bem simples de usar, mas não sei se vale vale a pena embarcar em um projeto que não é atualizado desde 2003…
O spin me pareceu meio complicado, e acho que acabaria trocando um problema de alto acoplamento por um de complexidade de código. [/quote]
Pode usar o foxtrot tranqüilamente que é muito fácil. Ele não é atualizado porque não precisa. Usei ele no banco postal com Java 1.3 e foi perfeito. O Spin é mais complicado e faz algumas coisinhas a mais que nem sempre a gente precisa.
A sugestão do Mister__M é boa mas precisa do foxtrot. Ela não funcionaria bem se fosse usada apenas a invokeAndWait do Java pelos conhecidos problemas documentados inclusive no próprio site do foxtrot.
Não exatamente. A interface de callback pode funcionar mais como um pattern de notificação de progresso e está muito mais ligado a lógica de negócios do que um Observable, que tem a ver com notificação de eventos.
[quote=Luca]
A sugestão do Mister__M é boa mas precisa do foxtrot. Ela não funcionaria bem se fosse usada apenas a invokeAndWait do Java pelos conhecidos problemas documentados inclusive no próprio site do foxtrot.[/quote]
[quote=pango]
(…)
O problema é que, para fazer isto, minha camada de controle precisa manipular minha camada de apresentação, usando o SwingUtilities.invokeAndWait(). Mas, pelo que eu entendo do padrão MVC, a camada de controle não deveria se preocupar com qual objeto da camada de visão o está acessando, para que seja possível, por exemplo, portar uma aplicação desktop para web sem maiores transtornos do que criar novas classes na camada de visão. Meu entendimento está incorreto? alguém tem alguma sugestão?[/quote]
Não é incorreto usar SwingUtilities.invokeAndWait() no controlador já que esse método têm a ver com o ambiente grafico e não com a view em si. Ou seja, o V e o C estão dentro do framework gráfico por isso não tem problema executar isso. É como executar System.getProperty(). É algo do ambiente java que está lá e vc pode usar quando e onde quiser.
Mas se esta dependência o preocupa a solução é simples. Aquele método recebe um Runnable. Então vc pode implemenar um Executor que por detrás dos panos usa SwingUtilities.invokeAndWait() ou SwingUtilities.invokeLater() . Para deixar independente use a interface Executor no codigo do controlador e a obtenha de uma factory
Algo como:
Na verdade, na época em que eu usei o foxtrot, a solução puramente Swing não funcionava de jeito algum. Este assunto foi discutido até a exaustão em alguns sites. As opções eram usar a SwingWorker de um tutorial da Sun ou o foxtrot.
Lembro que li muitas críticas. Mas não deve ter sido no site do foxtrot cujo link que você me passou mostra uma situação com invokeAndWait funcionando e que o foxtrot pifa. No site do spin há alguma coisa em http://spin.sourceforge.net/problem.html
O principal ponto é que o Foxtrot resolveu meu problema de ficar com a tela cinza de forma bem fácil.
Não necessáriamente. Executor é apenas um interface, não é o Executor do java 5. (É executor.executeAndWait e não executor.execute())
Vcs estão falando do SwingWorker e tal, mas isso serve para deixar a interface livre enquanto o processamento acontece. A mensagem original perguntava se usar classes do swing no controler para deixar a interface livre não era uma violação do MVC. São dois problemas distintos.
Mesmos que use SwingWorker terá que usar a proposta da interface Executor ou algo semelhante, se quiser desacoplar o controlador do swing.
Se for usar SwingWorker é uma boa tb usar um ProgressMonitor ou algo semelhante para avisar o usuário de quanto falta, ou se isso não possivel saber, pelo menos mostra que algo está funcionando em background.
Esta solução de SwingWorker + ProgressMonitor + Interface de Desacoplamento é a solução ideal.