Buscar

AJAX em Java sem HTML

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 24 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 24 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 24 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Maurício Linhares de Aragão Junior – http://maujr.org/ 
AJAX em Java sem HTML nem JavaScript usando 
Thinwire
Maurício Linhares de Aragão Junior
Desenvolva aplicações web utilizando técnicas AJAX sem ter que escrever nenhuma linha de 
HTML ou JavaScript, utilizando a biblioteca de componentes para web Thinwire
Introdução
O Thinwire é um framework para o desenvolvimento de aplicações web utilizando técnicas AJAX 
baseado em componentes visuais, como as bibliotecas gráficas para desktop como Swing ou SWT. Nele, 
todo o seu código é escrito em Java e uma aplicação web é gerada baseada no que você programou. 
Diferentemente de outros frameworks para o desenvolvimento AJAX em Java, como o Google Web 
Toolkit, o Thinwire não utiliza de forma alguma geradores de código ou transformações, todo o código é 
sempre escrito em Java e executa normalmente dentro de qualquer servidor web Java.
Antes de iniciar o tutorial você deve fazer o download do Thinwire na página oficial do projeto: 
http://www.thinwire.com/ , se já usa o Java 1.5 ou mais recente, pode baixar a versão própria para o 
Java 1.5 e basta apenas adicionar o JAR do “commons-fileupload” que está dentro do download do SDK 
do Thinwire, se você usa uma versão anterior ao Java 1.5, deve colocar todos os arquivos JAR que estão 
no SDK do Thinwire no seu classpath.
Se você utiliza o Maven 2 para gerenciar o seus projetos
Se você utiliza o Maven 2 para gerenciar os seus projetos, vai preceber que os 
arquivos do projeto existe uma pasta chamada “maven”, nela você vai encontrar uma 
pasta “project” com os arquivos do projeto do Maven 2 (incluindo um pom.xml) e 
uma pasta “repository” que contém a dependência do Thinwire configurada.
A única configuração adicional que você precisa fazer é adicionar a dependência do 
Thinwire no seu repositório, para fazer isso, basta copiar a pasta que está dentro da 
pasta “repository” dos arquivos do projeto para dentro do seu repositório local do 
Maven 2.
Se você não sabe o que é o Maven 2, pode saber mais no tutorial “Automatizando os 
seus projetos com o Maven 2” (http://guj.com.br/java.tutorial.artigo.185.1.guj )
Olá Mundo!
Para começar os nossos estudos, vamos para o caso clássico de “Olá mundo”. Nós vamos criar uma 
janela (com o component Dialog) e nessa janela nós vamos adicionar um componente Label com o nosso 
texto.
Listagem 1 – Olá Mundo com o Thinwire
public class Main {
public static void main(String[] args) {
Application.current().getFrame().setTitle("Olá Mundo No Thinwire!");
Dialog dialog = new Dialog();
dialog.setTitle("Janela");
dialog.setBounds(100, 100, 400, 200);
Label label = new Label();
label.setText("Olá Mundo Pelo Thinwire!");
label.setSize( 150, 50 );
dialog.getChildren().add(label);
GUJ – http://www.guj.com.br – Página 1
http://www.guj.com.br/
http://maujr.org/
http://guj.com.br/java.tutorial.artigo.185.1.guj
http://guj.com.br/java.tutorial.artigo.185.1.guj
http://guj.com.br/java.tutorial.artigo.185.1.guj
http://www.thinwire.com/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
dialog.setVisible(true);
}
}
O exemplo mostra um uso simples do Thinwire, na primeira linha nós acessamos a uma referência da 
aplicação corrente (a que está disponível para o usuário atual), depois acessamos o objeto Frame da 
aplicação, que é a tela (ou aba) do navegador que está mostrando a aplicação, e alteramos o título dele. 
Após essa alteração, criamos um objeto do tipo Dialog (uma janela), criamos um Label e adicionamos ele 
a janela e no fim do código nós alteramos a propriedade “visible” da janela para que ela torne-se visível.
O código é extremamente simples e parecido com qualquer outro código de desenvolvimento de 
interfaces gráficas para desktops que você já tenha desenvolvido, a única diferença é que esse código é 
para o desenvolvimento de aplicações web que usam AJAX. 
As únicas partes diferentes que nós podemos perceber é quando em vez de usar o método “setSize()” 
na janela, nós usamos o método “setBounds()”, que posiciona o componente de forma absoluta em seu 
componente pai e não de forma relativa. Os dois primeiros parâmetros do método são as posições x e y 
iniciais no plano cartesiano representado pelo componente pai, que no nosso caso é o próprio Frame da 
janela do navegador. Se esses valores houvessem sido definidos em um componente com outro pai, 
esses valores teriam sido absolutos com relação ao atual pai do componente. Todos os componentes no 
Thinwire devem, obrigatoriamente, ter um tamanho, se você adicionar um componente sem colocar o 
seu tamanho ele simplesmente não vai ser desenhado na tela.
Para podermos implantar essa aplicação web em um servidor web Java comum, nós precisamos 
configurar ela no web.xml da aplicação web, vejamos como seria essa configuração do web.xml:
Listagem 2 – web.xml do primeiro exemplo
<?xml version="1.0" encoding="UTF-8"?>
<web-app
version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>thinwire</servlet-name>
<servlet-class>thinwire.render.web.WebServlet</servlet-class>
<init-param>
<param-name>styleSheet</param-name>
<param-value>DefaultStyle</param-value>
</init-param>
<init-param>
<param-name>mainClass</param-name>
<param-value>org.maujr.thinwire.hello.Main</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>thinwire</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
O web.xml em questão define um servlet do Thinwire que é responsável por carregar a nossa 
aplicação. Na configuração do servlet nós passamos as informações pelos valores dos “init-param”, o 
parâmetro “mainClass” diz qual é a classe que tem o método “public static void main (String[] args)”, é 
essa classe que define o ponto de entrada de nossa aplicação e é através dela que o Thinwire começa a 
inicialização do código.
O segundo parâmetro, “styleSheet”, define o estilo visual que os componentes do Thinwire devem 
mostrar para o usuário, algo como um “skin” do seu sistema operacional. Nós definimos como estilo o 
“DefaultStyle” que é o estilo padrão da ferramenta. A pasta “DefaultStyle” deve estar no diretório raiz da 
GUJ – http://www.guj.com.br – Página 2
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
sua aplicação web para que ela possa ser utilizada pelo Thinwire dentro da sua aplicação. Os arquivos 
necessários para o “DefaultStyle” vem dentro do arquivo JAR do Thinwire e você também pode encontra-
los nos arquivos do projeto do tutorial.
Vejamos então a tela do nosso primeiro exemplo:
Imagem 1 – Olá Mundo no Thinwire
Labels e campos de entrada de texto
Agora que já vimos o que é necessário configurar para fazer uma aplicação Thinwire executar, 
vejamos como utilizar os componentes de entrada de texto disponíveis no toolkit. Como campos de 
entrada para o usuário, nós temos:
• Label – Campo de texto que normalmente serve para explicar um outro componente;
• TextField – Componente que desenha um campo de texto simples de uma única linha, que 
pode ter uma máscara e também funcionar como um campo do tipo “password”, onde o texto 
escrito é escondido do usuário;
• TextArea – Componehte que desenha um campo de texto que pode ter várias linhas de texto;
• DateBox – Componente que desenha um calendário para que o usuário possa selecionar uma 
data (também já o DropDownDateBox que é um DateBox dentro de um componente 
DropDown);
Vejamos um exemplo de código do uso desses componentes:
Listagem 3 – Exemplo de labels e inputs
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Campos de 
Entrada");
GUJ – http://www.guj.com.br – Página 3
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de AragãoJunior – http://maujr.org/ 
Dialog dialog = new Dialog();
dialog.setTitle("Exemplo de Campos de Entrada");
dialog.setModal(false);
dialog.setResizeAllowed(true);
dialog.setBounds( 50, 50, 300, 200 );
Label labelInput = new Label();
labelInput.setBounds( 10, 10, 100, 20 );
labelInput.setText("InputText");
TextField inputField = new TextField();
inputField.setBounds(60, 10, 100, 20);
Label labelPassword = new Label();
labelPassword.setBounds( 10, 40, 100, 20 );
labelPassword.setText("Password");
TextField inputPassword = new TextField();
/* Colocar a propriedade inputHidden com o valor TRUE faz
 * com que o componente não exiba o seu texto */
inputPassword.setInputHidden(true);
inputPassword.setBounds(60, 40, 100, 20);
Label labelMask = new Label();
labelMask.setBounds( 10, 70, 100, 20 );
labelMask.setText("Masked");
TextField inputMask = new TextField();
inputMask.setBounds(60, 70, 100, 20);
/* Para criar um editor com máscara, basta dizer 
 * qual o formato na propriedade editMask */
inputMask.setEditMask("##,##");
dialog.getChildren().add(labelInput);
dialog.getChildren().add(inputField);
dialog.getChildren().add(labelPassword);
dialog.getChildren().add(inputPassword);
dialog.getChildren().add(labelMask);
dialog.getChildren().add(inputMask);
dialog.setVisible(true);
}
Como você pode perceber, o exemplo segue a mesma lógica do anterior, nós criamos os componentes, 
damos uma posição a eles através da chamada do método “setBounds()”, se nós não tivéssemos feito as 
chamadas ao método “setBouds()” dos componentes, todos eles teriam sido desenhados na posição “0,0” 
do seu componente pai e apareciam todos um por cima dos outros, por isso é necessário posicionar todos 
absolutamente dentro dos seus componentes pai. No fim do exemplo nós adicionamos os componentes 
na janela e alteramos a propriedade “visible” da janela para que ela fique visível.
As únicas partes diferentes deste código, são o início, onde alteramos algumas propriedades da janela 
(o objeto Dialog), nós fazemos com que ela seja não modal e que possa ter o seu tamanho alterado pelo 
usuário. Após isso, criamos um TextField alterando a sua propriedade “inputHidden” para transforma-lo 
em um campo que esconde o que o usuário digitou e no terceiro TextField nós alteramos a propriedade 
“editMask” para que ela formate a entrada que o usuário digitar.
Imagem 2 – Imagem com o exemplo dos componentes de texto
GUJ – http://www.guj.com.br – Página 4
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Vejamos como está o nosso arquivo de configuração agora:
Listagem 5 – Arquivo de configuração das aplicações do Thinwire
<?xml version="1.0" encoding="UTF-8"?>
<web-app
version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>helloworld</servlet-name>
<servlet-class>thinwire.render.web.WebServlet</servlet-class>
<init-param>
<param-name>mainClass</param-name>
<param-value>org.maujr.thinwire.hello.Main</param-value>
</init-param>
<init-param>
<param-name>styleSheet</param-name>
<param-value>DefaultStyle</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>helloworld</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
GUJ – http://www.guj.com.br – Página 5
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
<servlet>
<servlet-name>text</servlet-name>
<servlet-class>thinwire.render.web.WebServlet</servlet-class>
<init-param>
<param-name>styleSheet</param-name>
<param-value>DefaultStyle</param-value>
</init-param>
<init-param>
<param-name>mainClass</param-name>
<param-value>org.maujr.thinwire.text.Main</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>text</servlet-name>
<url-pattern>/text</url-pattern>
</servlet-mapping>
</web-app>
Agora nós temos duas aplicações do Thinwire configuradas. Devido a um bug ainda não resolvido na 
versão utilizada desse tutorial (a 1.2rc1), é necessário que sempre haja uma aplicação mapeada para a 
URL “/*”, então, se você vai colocar várias aplicações do Thinwire em uma única aplicação web, lembre-
se sempre de adicionar uma delas mapeada para o contexto raiz em “/*”, as outras aplicações podem ter 
as suas URLs normalmente (o mapeamento genérico não vai afetar o seu funcionamento). Você também 
pode simplesmente mapear o mesmo servlet para dois caminhos de URL distintos.
Vejamos agora um exemplo que use TextBoxes e os campos de entrada de data:
Listagem 4 – Exemplos de labels, TextBoxes e DateBoxes
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Campos de 
Entrada");
Dialog dialog = new Dialog();
dialog.setTitle("Exemplo de Campos de Entrada");
dialog.setModal(false);
dialog.setResizeAllowed(true);
dialog.setBounds( 50, 50, 400, 400 );
Label labelArea = new Label();
labelArea.setBounds( 10, 10, 100, 20 );
labelArea.setText("TextArea");
final Label labelResult = new Label();
labelResult.setBounds( 170, 10, 100, 100 );
labelResult.setWrapText(true);
labelResult.setText("");
TextArea textArea = new TextArea();
textArea.setBounds(60, 10, 100, 100);
textArea.addPropertyChangeListener( TextComponent.PROPERTY_TEXT , 
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent ev) {
labelResult.setText( ((TextComponent) 
ev.getSource()).getText() );
}
});
Label labelDate = new Label();
labelDate.setBounds(10, 120, 100, 20);
GUJ – http://www.guj.com.br – Página 6
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
labelDate.setText("Date");
DateBox dateBox = new DateBox();
dateBox.setBounds(60, 120, 100, 150);
Label labelDateDropDown = new Label();
labelDateDropDown.setText("DropDate");
labelDateDropDown.setBounds(10, 280, 100, 20);
DropDownDateBox dropDownDateBox = new DropDownDateBox();
dropDownDateBox.setBounds(60, 280, 100, 20);
dialog.getChildren().add(labelArea);
dialog.getChildren().add(textArea);
dialog.getChildren().add(labelResult);
dialog.getChildren().add(labelDate);
dialog.getChildren().add(dateBox);
dialog.getChildren().add(labelDateDropDown);
dialog.getChildren().add(dropDownDateBox);
dialog.setVisible(true);
}
Neste exemplo, temos de novo os componentes que desenham calendários para que o usuário 
possa selecionar uma data. Além dos componentes de data, nós também criamos um “listener”, que é 
um objeto que responde a um evento, e registramos ele no evento de alteração da propriedade “text” do 
TextArea, pois assim, a cada vez que alguém digitar alguma coisa naquele componente o código vai 
receber o evento e vai escrever o atual valor do TextArea em um Label que está ao seu lado.
Imagem 3 – Imagem do exemplo de uso de TextAreas e Dates
GUJ – http://www.guj.com.br – Página 7
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Lidando com botões
O Thinwire define os três tipos mais comuns de botões, o botão comum de clicar, o checkbox, que é 
um botão que serve como um marcador e os botões de radio, que funcionam como uma lista onde você 
pode selecionar um único valor.
Vejamos o nosso exemplo de código:
Listagem 5 – Exemplo do uso de botões
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Botões");
Dialog dialog = new Dialog();
dialog.setTitle("Exemplo de Botões");
dialog.setModal(false);
dialog.setResizeAllowed(true);
dialog.setBounds( 50, 50, 400, 400 );
Button button = new Button();
button.setText("Clique Aqui!");
button.setBounds(50, 50, 100, 30);
button.addActionListener( Button.ACTION_CLICK , new ActionListener() 
{
public void actionPerformed(ActionEvent ev) {
Button button = (Button) ev.getSource();
if ( "Clique Aqui!".equals( button.getText()) ) {
GUJ – http://www.guj.com.br – Página 8
http://www.guj.com.br/http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
button.setText("Clique Ali!");
} else {
button.setText("Clique Aqui!");
}
}
} );
CheckBox checkBox1 = new CheckBox();
checkBox1.setText("Opção 1");
checkBox1.setBounds(50, 90, 100, 30);
CheckBox checkBox2 = new CheckBox();
checkBox2.setText("Opção 2");
checkBox2.setBounds(50, 130, 100, 30);
CheckBox checkBox3 = new CheckBox();
checkBox3.setText("Opção 3");
checkBox3.setBounds(50, 170, 100, 30);
RadioButton radio1 = new RadioButton();
radio1.setText("Radio 1");
radio1.setBounds(50, 230, 100, 30);
RadioButton radio2 = new RadioButton();
radio2.setText("Radio 2");
radio2.setBounds(50, 270, 100, 30);
RadioButton.Group radioGroup = new RadioButton.Group();
radioGroup.add(radio1);
radioGroup.add(radio2);
dialog.getChildren().add(button);
dialog.getChildren().add(checkBox1);
dialog.getChildren().add(checkBox2);
dialog.getChildren().add(checkBox3);
dialog.getChildren().add(radio1);
dialog.getChildren().add(radio2);
dialog.setVisible(true);
}
A criação de componentes é igual a que nós já havíamos visto antes, a única diferença que nós 
podemos notar nesse código é a forma que o ActionListener é implementado. Ele não é registrado 
simplesmente para o evento de clique do botão, mas para um tipo de clique, que é o clique simples, se o 
evento fosse para o clique duplo, o evento utilizado seria o Button.ACTION_DOUBLE_CLICK. Então, 
no nosso caso, a cada vez que o usuário clicar no botão, o evento vai ser chamado.
Outro detalhe importante é o objeto RadioButton.Group, que serve para agrupar um conjunto de 
RadioButtons, é através dele que nós garantimos que apenas um dos RadioButtons está selecionado em 
uma interface. Após criar os RadioButtons nós adicionamos eles no Group para que eles possam ser 
utilizados corretamente.
Imagem 4 – Exemplo do uso de botões
GUJ – http://www.guj.com.br – Página 9
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Painéis com abas - TabFolders
Painéis com abas são comuns em aplicações, eles costumam representar opções de configurações, 
vários documentos abertos (como em navegadores que tem suporte a abas). Vejamos como criar painéis 
com abas no Thinwire:
Listagem 6 – Exemplo do uso de TabFolders
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Painéis com 
Abas");
Dialog dialog = new Dialog();
dialog.setTitle("Exemplo de Painéis com Abas");
dialog.setBounds(100, 100, 400, 400);
TabFolder tabFolder = new TabFolder();
tabFolder.setSize(300, 300);
TabSheet firstTabSheet = new TabSheet();;
firstTabSheet.setText("Aba 1");
Label label = new Label();
label.setText("Label na primeira Aba");
label.setSize(150, 30);
firstTabSheet.getChildren().add(label);
TabSheet secondTabSheet = new TabSheet();
secondTabSheet.setText("Aba 2");
Button button = new Button();
button.setText("Button na segunda aba");
button.setSize(150, 30);
secondTabSheet.getChildren().add(button);
tabFolder.getChildren().add(firstTabSheet);
tabFolder.getChildren().add(secondTabSheet);
dialog.getChildren().add(tabFolder);
dialog.setVisible(true);
}
GUJ – http://www.guj.com.br – Página 10
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
O componente que representa o “container” de abas é o TabFolder, cada aba é um objeto do tipo 
TabSheet. Para adicionar um componente em uma das abas, basta usar a referência para o TabSheet no 
qual você deseja adicionar novos componentes e adicioná-los a a sua lista. Você pode selecionar uma aba 
específica usando o método “setCurrentIndex()” da classe TabFolder, passando como parâmetro o 
índice da TabSheet que você deseja selecionar.
Imagem 5 – Exemplo do uso de painéis com abas
Mostrando dados na forma de tabelas
Exibir informação na forma de tabelas é lugar comum na maioria das aplicações desenvolvidas, seja 
qual for o seu trabalho real. Tabelas bem organizadas facilitam até mesmo o entendimento do que está 
sendo mostrado por parte dos usuários, então um bom framework de interface não poderia deixar de ter 
um componente tabela para mostrar informações. O componente que representa as tabelas no Thinwire 
é o GridBox, que além de mostrar os dados de forma tabular, também torna possível a seleção de suas 
linhas, vejamos um exemplo do uso desse componente:
Listagem 7 – Exemplo do uso de tabelas
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Tabela");
Dialog dialog = new Dialog();
dialog.setTitle("Exemplo de Tabela");
dialog.setModal(false);
dialog.setResizeAllowed(true);
dialog.setBounds( 100, 100, 400, 400 );
GridBox table = new GridBox();
table.setVisibleHeader(true);
Column firstColumn = new Column();
firstColumn.setName("ID");
table.getColumns().add(firstColumn);
Column secondColumn = new Column();
GUJ – http://www.guj.com.br – Página 11
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
secondColumn.setName("Nome");
table.getColumns().add(secondColumn);
Column thirdColumn = new Column();
thirdColumn.setName("Preço");
table.getColumns().add(thirdColumn);
for ( int x = 0; x < NOMES.length; x++ ) {
Row row = new Row();
row.add( x);
row.add( NOMES[x]);
row.add( x * 10);
table.getRows().add(row);
}
table.setSize(250, 250);
dialog.getChildren().add(table);
dialog.setVisible(true);
}
Para criar uma tabela no Thinwire nós precisamos apenas criar o componente GridBox, criar os objetos 
GridBox.Column, que representam as colunas da tabela e depois popular a tabela com os objetos 
GridBox.Row, cada objeto Row representa uma linha de informações na tabela, pra preencher a linha 
você deve usar os métodos “add()” disponíveis no objeto Row. A cada objeto Row que você adicionar, 
uma nova linha vai ser mostrada na tabela.
A única configuração além da normal que nós fazemos na nossa tabela é a chamada do método 
“setVisibleHeaders()”, que faz com que as colunas sejam mostradas como cabeçalhos na tabela, se você 
não chamar esse método, os cabeçalhos de coluna não vão ser mostrados na sua tabela, ela já vai 
começar mostrando os dados da primeira linha que você criou.
O GridBox também apresenta outras características, como a possibilidade de se selecionar as linhas da 
tabela (e de se registrar para o evento de seleção da tabela). Para saber qual é a atual linha selecionada 
basta chamar o método “getSelectedRow()”, que retorna a linha que está atualmente selecionada na 
tabela. Vejamos como registrar um evento que seja chamado na hora que o usuário selecionar uma linha 
no GridBox:
Listagem 8 – Exemplo de listener registrado para a seleção de linha
table.addPropertyChangeListener( 
GridBox.Row.PROPERTY_ROW_SELECTED, 
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent ev) {
Row row = (Row) ev.getSource(); 
}
}
);
Nós registramos o listener no GridBox (o objeto “table”), mas a propriedade registrada é a propriedade 
do objeto linha, então o objeto que vai ser enviado como “fonte” do evento é o objeto que representa a 
linha atualmente selecionda.
Imagem 6 – Exemplo de tabela
GUJ – http://www.guj.com.br – Página 12
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Árvores
Mostrar informações de forma hierárquica utilizando árvores é uma necessidade comum e o Thinwire 
oferece suporte a esse tipo de representação através do componente Tree e dos objetos Tree.Item, 
vejamos um exemplo de uso de árvores para mostrar informações de forma hierárquica:
Listagem 9 – Árvores no Thinwire
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Árvore");
Dialog dialog = new Dialog();
dialog.setTitle("Exemplo de Árvore");
dialog.setModal(false);
dialog.setResizeAllowed(true);
dialog.setBounds( 200, 200, 400, 400 );
Tree tree = new Tree();
tree.setSize(300,300);
tree.setRootItemVisible(false);Item firstItem = new Item();
firstItem.setText("Item 1");
tree.getRootItem().getChildren().add(firstItem);
Item secondItem = new Item();
secondItem.setText("Item 2");
tree.getRootItem().getChildren().add(secondItem);
GUJ – http://www.guj.com.br – Página 13
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Item thirdItem = new Item();
thirdItem.setText("Item 3");
tree.getRootItem().getChildren().add(thirdItem);
Item firstInternalItem = new Item();
firstInternalItem.setText("Internal 1");
firstItem.getChildren().add(firstInternalItem);
Item secondInternalItem = new Item();
secondInternalItem.setText("Internal 1");
firstItem.getChildren().add(secondInternalItem);
dialog.getChildren().add(tree);
dialog.setVisible(true);
}
Para criar uma árvore, você primeiro precisa de um objeto árvore, depois você precisa criar objetos do 
tipo Tree.Item para representar cada um dos itens da árvore. Se você deseja que um dos itens tenha 
sub-itens, basta criar os objetos Tree.Item correspondentes e adicioná-los no item que você deseja que 
tenha os sub-itens.
Imagem 7 – Exemplo de Árvore
Barras de menu
Janelas com barras de menu são uma necessidade comum em aplicações, para que o usuário possa 
selecionar facilmente as ações que deseja realizar. O Thinwire define o componente Menu para que essas 
barras de menu possam ser criadas e apenas os componentes que implementam a interface Window 
podem receber barras de menu, atualmente, os dois componentes que implementam Window são o 
componente Frame (que é a janela do navegador) e o componente Dialog, que é a janela do Thinwire. 
Vejamos um exemplo do uso de menus no Thinwire:
Listagem 10 – Exemplo da criação de menus
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Menu");
Dialog dialog = new Dialog();
dialog.setTitle("Exemplo de Menu");
dialog.setBounds(100, 100, 200, 200);
Menu menu = new Menu();
//acessando o item raiz do menu
GUJ – http://www.guj.com.br – Página 14
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Item rootItem = menu.getRootItem();
Item fileItem = new Item();
fileItem.setText("Arquivo");
rootItem.getChildren().add(fileItem);
Item newFileItem = new Item();
newFileItem.setText("Novo");
fileItem.getChildren().add(newFileItem);
Item newProjectItem = new Item();
newProjectItem.setText("Projeto");
newFileItem.getChildren().add(newProjectItem);
Item exitFileItem = new Item();
exitFileItem.setText("Sair");
fileItem.getChildren().add(exitFileItem);
Item editItem = new Item();
editItem.setText("Editar");
rootItem.getChildren().add(editItem);
Item helpItem = new Item();
helpItem.setText("Ajuda");
rootItem.getChildren().add(helpItem);
Item openHelpItem = new Item();
openHelpItem.setText("Abrir Ajuda");
helpItem.getChildren().add(openHelpItem);
menu.addActionListener(Component.ACTION_CLICK, 
new ActionListener() {
public void actionPerformed(ActionEvent event) {
MessageBox.confirm( 
"Selecionando um item do menu",
String.format(
"The selected menu item was -> 
%s", 
event.getSource()));
}
} );
// Dialogs e Frames implementam a interface Window, 
//portanto ambos podem ter uma barra de menu
dialog.setMenu(menu);
dialog.setVisible(true);
}
Um Menu no Thinwire é um componente que tem vários objetos Menu.Item como seus filhos. Para 
criar um menu você precisa primeiro criar um objeto do tipo Menu, acessar a referência ao Menu.Item 
raiz desse menu através do seu método “getRootItem()” e depois basta adicionar os itens nesse root 
item e em seus itens filhos (de forma parecida com a do componente árvore, a diferença aqui é que esse 
item raiz nunca é desenhado na tela).
Para registrar eventos em um Menu, você normalmente vai registrar um “ActionListener” no menu em 
questão. O objeto que é retornado como fonte dos eventos (através do método “getSource()” do objeto 
ActionEvent) é o Menu.Item que foi selecionado pelo usuário, então no tratamento do evento você deve 
implementar uma lógica saiba identificar qual item foi selecionado e o que deve ser feito.
GUJ – http://www.guj.com.br – Página 15
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Um menu não é “adicionado” a um componente através da coleção de filhos (o método 
“getChildren()”), ele é uma propriedade do objeto no qual vai ser colocado. Menus são sempre colocados 
através do método “setMenu()” no objeto que você deseja que o menu apareça. Lembre-se que apenas 
objetos que implementam a interface Window do Thinwire podem ter barras de menu.
Imagem 8 – Exemplo de Menu
Fazendo upload de arquivos
Fazer upload de arquivos em aplicações web costuma ser um trabalho complicado, com a adição de 
bibliotecas que não são padrão e o uso de objetos que não fazem, necessariamente, parte de uma 
aplicação web. No Thinwire, toda a lógica de upload de arquivos é abstraída do programador, que 
simplesmente cria o componente e espera que o usuário selecione o arquivo para ser enviado. Vejamos 
como fazer upload de arquivos com o Thinwire:
Listagem 11 – Upload de arquivos com o Thinwire
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Upload de 
Arquivo");
Dialog dialog = new Dialog("Exemplo de Upload de Arquivo");
dialog.setBounds(0, 0, 400, 400);
final FileChooser fileChooser = new FileChooser();
fileChooser.setSize(300, 30);
Button uploadButton = new Button();
uploadButton.setText("Enviar Arquivo");
uploadButton.setBounds(0, 40, 100, 30);
final Label label = new Label();
label.setBounds(0, 80, 300, 30);
uploadButton.addActionListener( Component.ACTION_CLICK , new 
ActionListener() {
public void actionPerformed(ActionEvent event) {
FileInfo fileInfo = fileChooser.getFileInfo();
GUJ – http://www.guj.com.br – Página 16
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
File file = new File(new 
File(fileInfo.getName()).getName());
System.out.printf("AbsolutePath -> %s%n", 
file.getAbsolutePath());
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
fileInfo.saveToFile( file );
label.setText("Salvo em -> " + file.getAbsolutePath());
}
});
dialog.getChildren().add(fileChooser);
dialog.getChildren().add(uploadButton);
dialog.getChildren().add(label);
dialog.setVisible(true);
}
Na nossa interface, nós criamos o componente que faz o upload de arquivos, o FileChooser e criamos 
mais um botão, que vai ser clicado pelo usuário na hora que ele quiser que o arquivo seja enviado. O 
componente FileChooser é um campo de upload comum de aplicações web, mas nós não precisamos 
mais nos preocupar em receber requisições ou fazer qualquer outra coisa, basta esperar que o usuário 
selecione o arquivo e recebê-lo, vejamos como isso acontece:
Listagem 12 – Tratamento do evento
public void actionPerformed(ActionEvent event) {
FileInfo fileInfo = fileChooser.getFileInfo();
File file = new File(new File(fileInfo.getName()).getName());
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
fileInfo.saveToFile( file );
label.setText("Salvo em -> " + file.getAbsolutePath());
}
Nós acessamos a propriede “fileInfo” do objeto FileChooser, criamos um arquivo onde o conteúdo que 
está sendo enviado vai ser gravado e chamamos o método “saveToFile()” do objeto FileInfo, que vai 
escrever todo o conteúdo do arquivo enviado no arquivo que nós criamos.
Imagem 8 – Upload de arquivos
GUJ – http://www.guj.com.br – Página 17
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Simulando Listas e combos no Thinwire
Após mostrar tantos componentes, alguns comuns outros nem tanto, você deve ter sentido falta de 
dois componentes que são lugar comum em aplicações web e desktop, que são as listas de seleção e os 
“combo boxes”.No Thinwire, por uma decisão da própria equipe de desenvolvimento, esses componentes 
não “existem” de fato, mas isso não quer dizer que nós não possamos ter componentes que façam o 
mesmo. Apenas não existem classes, como TextField, que implementam as funcionalidades desses 
componentes, mas elas podem ser conseguidas com o uso dos componentes padrão da biblioteca. 
Vejamos então como nós poderíamos criar esses componentes:
Listagem 13 – Exemplo de listas e combos
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Listas e 
Combos");
Dialog dialog = new Dialog("Exemplo de Listas e Combos");
dialog.setBounds(200, 200, 600, 400);
GridBox listaSelecaoSimples = new GridBox();
listaSelecaoSimples.setVisibleHeader(false);
listaSelecaoSimples.setBounds(0, 0, 100, 100);
fillGridBox(listaSelecaoSimples);
GridBox listaSelecaoMultipla = new GridBox();
listaSelecaoMultipla.setVisibleCheckBoxes(true);
listaSelecaoMultipla.setVisibleHeader(false);
listaSelecaoMultipla.setFullRowCheckBox(true);
listaSelecaoMultipla.setBounds(0, 120, 100, 100);
fillGridBox(listaSelecaoMultipla);
DropDownGridBox comboBox = new DropDownGridBox();
comboBox.getComponent().setVisibleHeader(false);
comboBox.setBounds(0, 240, 100, 30);
fillGridBox( comboBox.getComponent() );
GUJ – http://www.guj.com.br – Página 18
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
dialog.getChildren().add(listaSelecaoSimples);
dialog.getChildren().add(listaSelecaoMultipla);
dialog.getChildren().add(comboBox);
dialog.setVisible(true);
}
Como você pôde ver pelo código, as listas de seleção única e múltipla são apenas objetos do tipo 
GridBox que tem apenas uma coluna e que não mostram os seus cabeçalhos (a propriedade 
“visibleHeaders” está como “false”). A única diferença entre a de seleção simples da de seleção múltipla é 
que a de seleção múltipla tem seu estado mantido por um conjunto de checkboxes e não apenas pela 
seleção da linha do componente. Para saber qual a linha selecionada no de seleção simples, use o 
método “getSelectedRow()”, para saber quais as linhas selecionadas no de seleção múltipla, você deve 
usar o método “getCheckedRows()”.
O combo box no fim do exemplo é apenas um GridBox dentro de um componente DropDown (que é 
um componente que desenha o seu componente filho dentro de uma caixa “drop-down”) que funciona 
exatamente da mesma forma que um GridBox comum funcionaria.
Imagem 9 – Exemplo de listas e combos
Componentes diversos
Vejamos agora alguns componentes diversos do Thinwire que não tem um uso freqüente, mas que 
podem simplificar tarefas que seriam complexas de se fazer com componentes padrão. Vejamos alguns 
exemplos de uso desses componentes:
Componente Image
O componente Image mostra uma imagem qualquer no lugar onde ele for adicionado. As imagens 
podem ser de qualquer tipo que o navegador puder aceitar.
Listagem 13 – Componente Image
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Imagem");
Dialog dialog = new Dialog();
dialog.setTitle("Janela com Imagem");
dialog.setBounds(100, 100, 400, 400);
Image image = new Image("images/logo-guj.gif");
image.setSize(289, 70);
dialog.getChildren().add(image);
GUJ – http://www.guj.com.br – Página 19
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
dialog.setVisible(true);
}
Parar criar um componente Image, precisamos apenas passar o caminho para a imagem que vai ser 
mostrada no seu construtor. Os caminhos que podem ser passados são caminhos relativos ao contexto 
da aplicação (que é o caso desse exemplo), o caminho completo no sistema de arquivos ou o caminho 
dentro do classpath, caminhos dentro do classpath deve ter como prefixo a palavra “classpath”, como em 
“class:///thinwire.ui.layout.SplitLayout/resources/Image.png”.
Imagem 9 – Exemplo do componente Image
Componente ProgressBar
Uma ProgressBar (ou barra de progresso) normalmente mede a execução de alguma tarefa longa ou o 
tamanho de alguma coisa que tem tendência a se alterar durante a execução da aplicação, ela 
normalmente vai “enchendo” conforme as ações vão acontecendo. Vejamos um exemplo:
Listagem 14 – Componente ProgressBar
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Barra de 
Progresso");
Dialog dialog = new Dialog();
dialog.setTitle("Janela com Barra de Progresso");
dialog.setBounds(100, 100, 400, 400);
final ProgressBar progressBar = new ProgressBar(100, 0);
progressBar.setSize(100, 30);
Button fillButton = new Button();
fillButton.setText("Preencher");
fillButton.setBounds(0, 40, 50, 30);
fillButton.addActionListener(Component.ACTION_CLICK, new 
ActionListener() {
public void actionPerformed(ActionEvent event) {
for ( int x = 0; x < 100; x ++ ) {
progressBar.setCurrentIndex(x);
try {
GUJ – http://www.guj.com.br – Página 20
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Button resetButton = new Button();
resetButton.setText("Zerar");
resetButton.setBounds(60, 40, 50, 30);
resetButton.addActionListener(Component.ACTION_CLICK, new 
ActionListener() {
public void actionPerformed(ActionEvent event) {
progressBar.setCurrentIndex(0);
}
});
dialog.getChildren().add(progressBar);
dialog.getChildren().add(fillButton);
dialog.getChildren().add(resetButton);
dialog.setVisible(true);
}
Nesse exemplo, nós temos uma ProgressBar e dois botões, um que vai enchendo a barra e outro que 
faz com que o seu contador volte a zero. No construtor da barra nós passamos o seu tamanho e o índice 
inicial dela (é o valor no qual ela vai se iniciar), para alterar o valor do seu tamanho, basta alterar a 
propriedade “currentIndex” da barra.
Imagem 10 – Exemplo de ProgressBar
GUJ – http://www.guj.com.br – Página 21
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Componente Slider
O componente Slider é utilizado para facilitar a seleção de números dentro de um intervalo, como 
escolher os números entre zero e cem. Vejamos um exemplo de uso do Slider:
Listagem 15 – Exemplo de Slider
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Slider");
Dialog dialog = new Dialog();
dialog.setTitle("Janela Slider");
dialog.setBounds(100, 100, 400, 400);
final Slider slider = new Slider( 200, 0 );
slider.setSize(100, 30);
final TextField textField = new TextField();
textField.setBounds(0, 40, 50, 30);
slider.addPropertyChangeListener( 
RangeComponent.PROPERTY_CURRENT_INDEX , new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
textField.setText( new 
Integer(slider.getCurrentIndex()).toString() );
}
});
dialog.getChildren().add(slider);
dialog.getChildren().add(textField);
dialog.setVisible(true);
GUJ – http://www.guj.com.br – Página 22
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
}
O Slider funciona com a definição de um intervalo, da mesma forma que o ProgressBar, a diferença é 
que o Slider é um componente que o próprio usuário seleciona e diz qual é o valor.
Imagem 11 – Exemplo de Slider
Componente WebBrowser
O componente WebBrowser cria um navegador na tela do usuário, permitindo de que da sua aplicação, 
ele possa abrir outras páginas e até mesmo outras aplicações. Vejamos um exemplo de seu uso:
Listagem 16 – Exemplo do componente WebBrowser
public static void main(String[] args) {
Application.current().getFrame().setTitle("Exemplo de Navegador");
Dialog dialog = new Dialog("Exemplo de Navegador");
dialog.setBounds(0, 0, 800, 600);
WebBrowser webBrowser = new WebBrowser();
webBrowser.setBounds(20, 20, 750, 550);
webBrowser.setLocation("http://www.guj.com.br/");
dialog.getChildren().add(webBrowser);dialog.setVisible(true);
}
Como você pode ver, basta criar o componente e dizer qual página você deseja que ele carregue, todo 
o resto do trabalho é feito pelo próprio componente.
Imagem 12 – Exemplo do componente WebBrowser
GUJ – http://www.guj.com.br – Página 23
http://www.guj.com.br/
http://maujr.org/
Maurício Linhares de Aragão Junior – http://maujr.org/ 
Referências
Site oficial do projeto – http://www.thinwire.com/ 
Conclusão
Como você pôde perceber, utilizar o Thinwire para o desenvolvimento de aplicações web é 
extremamente simples e ainda lhe dá como resultado aplicações com interfaces ricas e responsivas para 
o seus clientes usando técnicas AJAX para envio e atualização d conteúdo. Entretanto, o Thinwire não é a 
opção correta se você está buscando desenvolver páginas na web, ele é uma boa escolha se a sua 
necessidade é desenvolver aplicações com interfaces complexas, se o seu problema pode ser resolvido 
simplesmente com algumas páginas e formulários, usar outras tecnologias, como Servlets, JSF ou JSP, 
podem ser uma escolha mais acertada.
Tenha em vista também que todo o estado da sua aplicação é mantida pelo servidor, então não espere 
que uma aplicação desenvolvida no Thinwire possa ser instalada num servidor “simples” e servir a 
aplicação simultaneamente para milhares de pessoas. Os desenvolvedores do projeto tem clientes que já 
chegam a até oitocentos usuários simultâneos, mas isso é extremamente relativo a o tamanho da 
aplicação e a máquina servidora que está a servindo, então não pense em fazer uma aplicação dessas 
rodando em um único servidor se você espera ter cinqüenta mil pessoas penduradas naquele seu único 
servidor. Faça testes de carga e integração cedo para descobrir se esta realmente é a abordagem 
correta, pra que você não tenha que esquentar a cabeça com problemas de lentidão depois que a 
aplicação tiver sido implantada e começado a ser utilizada pelo seu cliente.
Maurício Linhares de Aragão Junior (mauricio.linhares@gmail.com) é graduando em Desenvolvimento de 
Sistemas para a Internet e Comunicação Social, com Habilitação em Jornalismo, desenvolvedor da Phoebus 
Tecnologia ( http://www.phoebus.com.br/ ), consultor e instrutor independente, instrutor parceiro da Synapse Tech 
Cursos ( http://stcursos.com/ ), membro da equipe administrativa do PBJUG ( http://pbjug.org/ ) e colaborador dos 
fóruns do GUJ ( http://guj.com.br/ ).
GUJ – http://www.guj.com.br – Página 24
http://www.guj.com.br/
http://guj.com.br/
http://pbjug.org/
http://stcursos.com/
http://www.phoebus.com.br/
mailto:mauricio.linhares@gmail.com
http://maujr.org/
http://www.thinwire.com/

Continue navegando