Jogo da Velha (Tic Tac Toe) RFCards Gratuitos
mar 05

Para quem não conhece existe um projeto do qual participei na elaboração e acho bastante útil pra todo mundo. É o GWT Window Manager o projeto consiste basicamente em usar um gerenciador de janelas para a sua aplicação aumentando ainda mais a sensação de se estar usando um desktop em vez do browser. Nesse post vou explicar o básico de como se usar o GWM como é conhecido no seu projeto.

Primeiramente crie um projeto usando o Project Creator e o Application Creator como explicado em posts anteriores. Em seguida acrescente o gwm.jar ao seu classpath e copie o diretório themes para a pasta public do seu projeto, é nela que se encontram todos os arquivos css e de imagem do gwm. Feito isso, o próximo passo é efetuar a ligação entre a página e esses arquivos. Acrescente as seguintes linhas no head do html da página:

HTML:
  1. <link href="themes/alphacube.css" rel="stylesheet" />
  2. <link href="themes/alphacube-off.css" rel="stylesheet" />
  3. <link href="themes/citrus.css" rel="stylesheet" />
  4. <link href="themes/citrus-off.css" rel="stylesheet" />
  5. <link href="themes/cloudy.css" rel="stylesheet" />
  6. <link href="themes/cloudy-off.css" rel="stylesheet" />
  7. <link href="themes/darkX.css" rel="stylesheet" />
  8. <link href="themes/darkX-off.css" rel="stylesheet" />
  9. <link href="themes/mac.css" rel="stylesheet" />
  10. <link href="themes/mac-off.css" rel="stylesheet" />
  11. <link href="themes/sky.css" rel="stylesheet" />
  12. <link href="themes/sky-off.css" rel="stylesheet" />
  13. <link href="themes/spread.css" rel="stylesheet" />
  14. <link href="themes/spread-off.css" rel="stylesheet" />
  15. <link href="themes/theme1.css" rel="stylesheet" />
  16. <link href="themes/theme1-off.css" rel="stylesheet" />
  17. <link />

Agora falta pouco para poder usar o framework :)O seu arquivo de módulo do projeto deve ficar parecido com este:

XML:
  1. <module>
  2. <inherits name="com.google.gwt.user.User"></inherits>
  3. <inherits name="org.gwm.GwtWindowManager"></inherits>
  4. <entry class="&lt;br.com.gwt.client.GWM"></entry>
  5. </module>

Modificando o código que foi gerado pelo application creator ficamos com o entry point da seguinte forma:

JAVA:
  1. package br.com.gwt.client;
  2.  
  3. import org.gwm.client.GDesktopPane;
  4. import org.gwm.client.GInternalFrame;
  5. import org.gwm.client.impl.DefaultGDesktopPane;
  6.  
  7. import com.google.gwt.core.client.EntryPoint;
  8. import com.google.gwt.user.client.ui.RootPanel;
  9. import com.google.gwt.user.client.ui.Widget;
  10.  
  11. /**
  12. * Entry point classes define <code>onModuleLoad()</code>.
  13. */
  14. public class GWM implements EntryPoint {
  15.  
  16. private GDesktopPane    desktop;
  17. private static GWM    instance;
  18. /**
  19. * This is the entry point method.
  20. */
  21. public void onModuleLoad() {
  22. instance = this;
  23. desktop = new DefaultGDesktopPane();
  24.  
  25. RootPanel.get().add((Widget) desktop);
  26. }
  27.  
  28. /**
  29. * Singleton
  30. * @return
  31. */
  32. public static GWM getInstance() {
  33. return instance;
  34. }
  35.  
  36. /**
  37. * Adicione os seus GInternalFrames ao desktop :D
  38. * @param iframe
  39. */
  40. public void addWindow(GInternalFrame iframe) {
  41. desktop.addFrame(iframe);
  42. iframe.setVisible(true);
  43. }
  44. }

Agora vejamos alguns detalhes do código:

Primeiramente declaramos que iria ser usado um Desktop, o desktop nada mais é do que um objeto capaz de receber janelas e gerenciá-las. Além disso, implementamos um dos mais usados e simples padrões de projeto um singleton. O Singleton garante que somente uma instancia de um determinado objeto será criado. Como o método onModuleLoad é o primeiro a ser chamado pelo gwt, e somente é executado uma única vez, é bastante adequado inicializar o singleton nesse ponto. No caso de se adicionar construtores ao entryPoint eles devem ser construtores padrão sem argumentos, podendo até mesmo ser privados caso contrário o compilador irá reclamar. Após a execução do onModuleLoad a qualquer momento será possível se obter uma instancia do entryPoint através do método getInstance().

Observem que a inicialização do desktop se dá através da classe DefaultGDesktop o que indica que a classe GDesktop na verdade é uma interface, isso configura um dos vários pontos de extensão do framework. Caso seja necessário implementar um desktop com comportamentos diferentes do original tudo que se tem que fazer após a implementação é alterar esta linha.

Por ultimo, no método onModuleLoad é adicionado esse objeto desktop ao RootPanel, que como já explicado anteriormente, é a página html. Repare aqui que a referência ao desktop não é de um widget, embora a implementação o seja, daí a necessidade do cast.

Agora analisemos o método addWindow(GInternalFrame iframe) ele faz duas coisas:

1. Adiciona o GInternalFrame ao desktop, porém isso não a torna visível;
2. Mostra a janela finalmente. Uma chamada ao método setVisible sem que a janela esteja previamente adicionada a um desktop provocaria uma Exceção em tempo de execução por isso ela só é feita nesse ponto.

Até agora temos uma aplicação com um desktop. Nada além disso, entretanto visualmente já pode-se observado o seguinte:

Desktop sem janelas

Entretanto isso não é nem de longe o suficiente para uma aplicação :)
Vamos criar pelo menos uma janela e brincar um pouco com ela :D

Para se criar uma janela que possa ser usada em conjunto com o GDesktop devemos criar uma classe que extenda de DefaultGInternalFrame ou então uma que a implemente, embora eu não recomende a implementação do início por que a DefaultGInternalFrame já possui bastante funcionalidades e sem contar que você pode extendê-la facilmente.

Assim, vejamos, vamos criar uma janela que possa utilizar o método singleton que criamos anteriormente e que tenha alguma utilidade também :) ai vai o código:

JAVA:
  1. package br.com.gwt.client;
  2.  
  3. import org.gwm.client.impl.DefaultGInternalFrame;
  4.  
  5. import com.google.gwt.user.client.ui.ChangeListener;
  6. import com.google.gwt.user.client.ui.ListBox;
  7. import com.google.gwt.user.client.ui.Widget;
  8.  
  9. /**
  10. * Cria uma janela com um combo box com os temas disponíveis. Ao selecionar um
  11. * tema diferente altera o desktop completo.
  12. * @author Marcelo Emanoel
  13. *
  14. */
  15. public class ThemeChanger extends DefaultGInternalFrame {
  16.  
  17. private ListBox combo;
  18.  
  19. public ThemeChanger() {
  20. init();
  21. initLayout();
  22. attachListeners();
  23. }
  24.  
  25. /**
  26. *Inicializa os componentes da janela
  27. */
  28. private void init() {
  29. combo = new ListBox();
  30. combo.addItem("default");
  31. combo.addItem("alphacube");
  32. combo.addItem("citrus");
  33. combo.addItem("cloudy");
  34. combo.addItem("darkX");
  35. combo.addItem("mac");
  36. combo.addItem("sky");
  37. combo.addItem("spread");
  38. combo.addItem("theme1");
  39. }
  40. /**
  41. *Inicializa o layout da Janela
  42. */
  43. private void initLayout() {
  44. setCaption("Seletor de temas");
  45. setContent(combo);
  46. }
  47. /**
  48. *Adiciona algum possível listener da janela
  49. */
  50. private void attachListeners() {
  51. combo.addChangeListener(new ChangeListener() {
  52. public void onChange(Widget sender) {
  53. int selecao = combo.getSelectedIndex();
  54. String tema = combo.getValue(selecao);
  55. GWM.getInstance().changeTheme(tema);
  56. }
  57. });
  58. }
  59. }

Repare que a janela é a mais simples possível, contém apenas um combobox com o nome dos estilos css que foram adicionados no início. No método attachListeners acrescentei um ChangeListener ao combobox de maneira que sempre que ouvesse a mudança de valor fosse possível interceptar essa mudança e reagir de alguma maneira, no caso chamei o método getInstance() que retorna a instancia do singleton de GWM e em seguida o método changeTheme passando o valor do combobox. abaixo segue o código que realiza a mudança de tema:

JAVA:
  1. public void changeTheme(String newTheme){
  2. desktop.setTheme(newTheme);
  3. }

Simples e direto. No método initLayout() foi alterada a propriedade Caption que nada mais é senão o Título da janela e em seguida o conteudo da janela foi setado para ser o combo box. O método utilizado para isso, setContent() foi sobrecarregado de 3 maneiras:

1. Receber um widget, a que provavelmente será a mais usada nas suas aplicações.
2. Receber uma String, supondo que seja de interesse do usuário adicionar somente texto à janela.
3. Receber uma url, também bastante usada para carregar uma página html dentro da janela em si.

Existem também outros métodos que facilitam bastante a vida, como por exemplo, o bloqueio ou não de propriedades como Maximizable, Minimizable, Draggable, Closable. Permitindo ou bloqueando respectivamente, maximizar, minimizar, arrastar e fechar a janela. Além disso, é possível acrescentar ouvintes à janela de maneira a interceptar os eventos anteriores além de outros permitindo uma reação a cada um deles.

Vamos revisitar agora a classe GWM já que vamos adicionar uma janela ao desktop. O código segue abaixo:

JAVA:
  1. package br.com.gwt.client;
  2.  
  3. import org.gwm.client.GDesktopPane;
  4. import org.gwm.client.GInternalFrame;
  5. import org.gwm.client.impl.DefaultGDesktopPane;
  6.  
  7. import com.google.gwt.core.client.EntryPoint;
  8. import com.google.gwt.user.client.ui.RootPanel;
  9. import com.google.gwt.user.client.ui.Widget;
  10.  
  11. /**
  12. * Entry point classes define <code>onModuleLoad()</code>.
  13. */
  14. public class GWM implements EntryPoint {
  15.  
  16. private GDesktopPane    desktop;
  17. private ThemeChanger    themeChanger;
  18. private static GWM    instance;
  19.  
  20. /**
  21. * This is the entry point method.
  22. */
  23. public void onModuleLoad() {
  24.  
  25. instance = this;
  26. desktop = new DefaultGDesktopPane();
  27.  
  28. themeChanger = new ThemeChanger();
  29.  
  30. changeTheme("default");
  31. addWindow(themeChanger);
  32.  
  33. RootPanel.get().add((Widget) desktop);
  34. }
  35.  
  36. /**
  37. * Singleton
  38. * @return
  39. */
  40. public static GWM getInstance() {
  41. return instance;
  42. }
  43.  
  44. /**
  45. * Adicione os seus GInternalFrames ao desktop :D
  46. * @param iframe
  47. */
  48. public void addWindow(GInternalFrame iframe) {
  49. desktop.addFrame(iframe);
  50. iframe.setVisible(true);
  51. }
  52.  
  53. public void changeTheme(String newTheme){
  54. desktop.setTheme(newTheme);
  55. }
  56. }

Veja que criamos uma instancia da janela ThemeChanger e a adicionamos ao desktop. Feito isso é só atualizar a página do projeto e finalmente ver a janela em ação.

desktopcomjanela.JPG

A janela por default pode ser maximizada, minimizada, fechada e ser arrastada. Aproveitem e brinquem um pouco. :)

Segue o código implementado no post. Aguardo comentários! :D

Projeto GWM

Deixe uma resposta