O popular Eclipse, é sem dúvida uma das IDE’s (Integrated Development Environment) mais utilizadas para desenvolvimento Java. O Eclipse se tornou famoso por utilizar SWT (Standard Widget Toolkit ) e por ser baseado numa arquitetura de plugins.

Porém o que poucos sabem é que é possível desenvolver aplicações “Rich Client” utilizando toda a arquitetura do Eclipse, de forma totalmente independente dele.

O Eclipse possui um ambiente chamado PDE (Plug-in Development Environment), que pode ser utilizado para desenvolver plugins ou aplicações Rich Client standalone.

Para entender melhor a aplicação que será construída neste artigo, nada melhor do que visualizar a imagem abaixo:

Hello RCP
Figura 1. Hello RCP

Ao clicar no aplicativo “eclipse.exe” a aplicação Hello RCP será iniciada. Note que a estrutura de diretórios é a mesma utilizada pelo eclipse, como a pasta plugins e workspace. Na pasta plugins estão os plugins obrigatórios para a aplicação, assim como o próprio plugin que será construído neste artigo. No exemplo da imagem acima, foram construídas 2 Views, mas outros componentes do Eclipse também poderiam ser utilizados, como por exemplo (Actions, Editors, Perspectives, Preferences, etc).

Criando o projeto

Crie um novo projeto do tipo “plugin” utilizado o wizard: File -> New -> Project -> Plug-in Project, digite Login no nome do projeto e clique em Next. Selecione Yes para desenvolver uma aplicação Rich Client, e clique Next.

Na próxima tela são exibidos alguns templates de aplicações pré-definidas, selecione o template Hello RCP e clique em Finish.

O wizard vai criar um projeto do tipo Plugin que pode ser disponibilizado como uma aplicação Rich Client standalone. Automaticamente após a criação do projeto, o arquivo MANIFEST.MF será aberto no editor. Para iniciar a aplicação basta clicar em Launch an Eclipse application.

MANIFEST.MF
Figura 2. MANIFEST.MF

Note que algumas classes foram criadas automaticamente pelo wizard:

  1. Activator: Classe que representa o plugin. Contém o método getImageDescriptor() que é útil para obter imagens.
  2. Application: Implementa a interface IplatformRunnable e representa a aplicação. Não é necessário alterar esta classe.
  3. ApplicationActionBarAdvisor: Classe responsável por construir os menus da aplicação, botões na barra de ferramentas, e definir as Actions responsáveis por executar as ações da aplicação. Posteriormente neste artigo, esta classe será alterada para criar o menu e Actions da aplicação de exemplo.
  4. ApplicationWorkbenchAdvisor: Classe que controla qual perspectiva deve ser exibida na tela.
  5. ApplicationWorkbenchWindowAdvisor: Contém configurações da aplicação, como o nome e tamanho da Janela, e alguns flags que indicam quais recursos estão habilitados, como por exemplo, se a barra de status será visível.
  6. Perspective: Classe que definie o layout das Views da aplicação. Conforme mostrado na Figura 1, a aplicação de exemplo define 2 Views, uma em cada lado da tela.

Desenvolvendo a aplicação

Conforme visualizado na Figura 1, a aplicação desenvolvida contém 2 Views, CadastroView e TabelaView. Cada View precisa herdar de org.eclipse.ui.part.ViewPart, e sobrescrever o método createPartControl para desenhar os componentes na tela utilizado SWT.

Também é necessário declarar a View no arquivo plugin.xml, conforme visualizado abaixo:

figcod01RCP.JPG

Note que a tag “class” no plugin.xml declara o nome completo da classe. Desta forma as Views precisam estar no pacote login.view, conforme declarado no arquivo.

Abaixo pode-se verificar o código fonte da classe CadastroView:


  public class CadastroView extends ViewPart {
  public static final String ID = "CadastroView";
 
  public Text nome = null;
  public Text fone = null;
 
  public void createPartControl(Composite parent) {
  parent.setLayout(new GridLayout(2,true));
 
  new Label(parent,SWT.NONE).setText("Nome: ");
  this.nome = new Text(parent, SWT.BORDER);
  new Label(parent,SWT.NONE).setText("Fone: ");
  this.fone = new Text(parent, SWT.BORDER);
 
  Button b = new Button(parent,SWT.PUSH);
  b.setText("Salvar");
  b.addSelectionListener(new SelectionAdapter() {
  public void widgetSelected(SelectionEvent e) {
  //Adicionar no Resultado
  TabelaView.addColumn(nome.getText(),fone.getText());
  }
  });
  }
 
  public void setFocus() {
 }
 }

E a seguir o código da classe TabelaView:


  public class TabelaView extends ViewPart {
 
  public static final String ID = "TabelaView";
  private static Table t;
 
  public void createPartControl(Composite parent) {
  t = new Table(parent, SWT.NONE);
  t.setHeaderVisible(true);
  t.setLinesVisible(true);
 
  TableColumn c = new TableColumn(t, SWT.NONE);
  c.setText(" Nome ");
  c = new TableColumn(t, SWT.NONE);
  c.setText(" Fone ");
 
  // mostrar as colunas
  for (int i = 0; i < t.getColumnCount(); i++) {
  t.getColumn(i).pack();
  }
  populateTable();
  }
 
  private void populateTable() {
  addColumn("Pessoa A", "111-1111");
  addColumn("Pessoa B", "222-2222");
  addColumn("Pessoa C", "333-3333");
  }
 
  // Adicionar valores na Tabela
  public static void addColumn(String nome, String fone) {
  TableItem item = new TableItem(t, SWT.NONE);
  item.setText(0, nome);
  item.setText(1, fone);
  }
 
  public void setFocus() {
  }
 }

Note que ambas as classes CadastroView e TabelaView declaram uma constante ID, onde o valor deve ser o mesmo declarado no plugin.xml. Este ID é utilizado pela classe “Perspective” para posicionar as Views na janela. No código abaixo, cada View foi configurada para ocupar 50% da tela, e as constantes LEFT e RIGHT são utilizadas para controlar o layout.


  public class Perspective implements IPerspectiveFactory {
  public void createInitialLayout(IPageLayout layout) {
  String editorArea = layout.getEditorArea();
  layout.setEditorAreaVisible(false);
 
  layout.addStandaloneView(CadastroView.ID, true, IPageLayout.LEFT, 0.50f, editorArea);
  layout.addStandaloneView(TabelaView.ID, true, IPageLayout.RIGHT, 0.50f, editorArea);
 
  layout.getViewLayout(TabelaView.ID).setCloseable(true);
  layout.getViewLayout(CadastroView.ID).setCloseable(true);
  }
 }

A classe ApplicationActionBarAdvisor é responsável por declarar as Actions e também montar o menu da aplicação. Esta classe foi criada automaticamente pelo Wizard, basta alterar o código fonte, conforme abaixo:


  public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
  private IWorkbenchAction exitAction;
  private OpenViewAction openTableViewAction;
  private OpenViewAction openCadastroViewAction;
  
  public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
  super(configurer);
  }
  
  protected void makeActions(final IWorkbenchWindow window) {
  exitAction = ActionFactory.QUIT.create(window);
  register(exitAction);
 
  openCadastroViewAction = new OpenViewAction(window, "Abrir Cadastro", CadastroView.ID);
  register(openCadastroViewAction);
 
  openTableViewAction = new OpenViewAction(window, "Abrir Resultado", TabelaView.ID);
  register(openTableViewAction);
  }
  
  protected void fillMenuBar(IMenuManager menuBar) {
  MenuManager fileMenu = new MenuManager("&File", IWorkbenchActionConstants.M_FILE); 
  menuBar.add(fileMenu);
 
  // File
  fileMenu.add(openTableViewAction);
  fileMenu.add(openCadastroViewAction);
  fileMenu.add(new Separator());
  fileMenu.add(exitAction); 
  }
 }

Note que o código utiliza uma Action chamada OpenViewAction, que pode ser visualizada abaixo. O código fonte simplesmente chama o método showView passando como argumento o ID da View desejada.


  public class OpenViewAction extends Action {
  
  private final IWorkbenchWindow window;
  private final String viewId;
 
  public OpenViewAction(IWorkbenchWindow window, String label, String viewId) {
  this.window = window;
  this.viewId = viewId;
 
  setText(label);
  setId("OpenView");
  }
 
  public void run() {
  if(window != null) { 
  try {
  window.getActivePage().showView(viewId);
  } catch (PartInitException e) {
  MessageDialog.openError(window.getShell(), "Error", "Error opening view:" + e.getMessage());
  }
  }
  }
 }

Agora que todo o código fonte está completo, é possível utilizar o editor do MANIFEST.MF para executar e debugar a aplicação dentro do Eclipse, conforme visualizado na Figura 2.

Criando o Produto (aplicação RCP)

O arquivo MANIFEST.MF pode ser utilizado para executar a aplicação e debugar o código dentro do ambiente do Eclipse. Porém a aplicação final, precisa rodar de forma totalmente independente. Para isto, é necessário criar uma configuração de “produto”, e exportá-la utilizando um wizard.

Clique em File -> New -> Other -> Product Configuration, digite login.product e selecione a pasta META-INF. Clique em Finish.

O editor de configuração do produto será aberto automaticamente quando o Wizard terminar. Através do Editor é possível exportar a aplicação clicando em Eclipse Product export wizard.

loginproduct (utilizado para exportar a aplicação)
Figura 3. login.product (utilizado para exportar a aplicação)

Antes de exportar o produto para o usuário final, é necessário criar um novo ID para o produto desenvolvido. Para isto clique em New no canto superior direito do editor. Selecione o Plugin “Login” que foi criado anteriormente, e digite LoginID no campo Product ID. Clique em Finish.

Agora clique na aba “Configuration” e clique em Add. Selecione o plugin “Login” criado anteriormente, e clique em Add Required Plug-ins. A imagem abaixo demonstra as configurações necesárias:

Configurações dos plugins obrigatórios
Figura 4. Configurações dos plugins obrigatórios

A configuração acima é utilizada no momento de exportar a aplicação RCP. Todos os plugins utilizados serão exportados na pasta “plugins” da aplicação.

Desta forma, uma estrutura de diretórios simular a Figura 1 será criada.

É recomendável sempre apagar o diretório antigo (caso existir) quando exportar o produto.

Editor visual para SWT

Dica: O VEP (Visual Editor Project) pode ser utilizado para construir as telas em SWT visualmente. Abaixo pode-se verificar a classe CadastroView mostrada neste artigo, sendo construída com o editor do VEP:
fig05RCP.JPG

Conclusão

Neste artigo foi apresentado como construir aplicações Rich Client usufruindo de alguns recursos disponíveis na plataforma Eclipse.

Confira mais sobre o Eclipse RCP Clicando Aqui. Alguns exemplos de aplicações RCP podem ser encontrados Aqui.