Vous êtes sur la page 1sur 9

Criando uma Janela Swing

Publicado por Tutoriais Admin em 05/07/2010 - 181.738 visualizaes

comentrios: 6 Este tutorial bem bsico, feito para quem no tem prtica na criao de interfaces grficas em java. Certo, queremos criar uma simples interface com o usurio que seja uma janela padro (com funes de minimizar, maximizar e fechar) contendo um caixa de texto dentro (digamos que seja um incio para o nosso notepad em java: 00ps:). Sigamos o raciocnio: primeiro fazemos a janela. Como em java trabalhamos com objetos em tudo ento precisamos de um objeto que seja uma janela. Ento nossa classe de janela vai herdar da classe de janela do Swing (prefira-o ao awt, na maioria dos casos): 1. 2. 3. 4. 5. import javax.swing.JFrame; public class MeuNote extends JFrame { ... }

Bem, j temos uma classe que cria objetos que so janelas. Agora precisamos construir a infra-estrutura da janela, modificando-a e adicionando coisas. Isso faz parte do processo de construo da janela e nenhum lugar melhor para isso que no construtor da classe! Antes uma pequena pausa para explicar um detalhe. As API grficas do java provm dois tipos de componentes visuais: componentes propriamente ditos e containers. Um componente uma pea (widget) que tem alguma funo na interface. Um container um componente que tem a capacidade de abrigar outros componentes (conteiners possuem um mtodo add (), que recebe qualquer componente como parmetro e o adiciona a sua lista de componentes " abrigados "). Sem entrar em muitos mritos (esse um tutorial curto), o swing tem uma caracterstica interessante adicional: todos os componentes swing, todos mesmo so tambm containers (possuem um mtodo add ())!: shock: Retomando a nossa trilha agora: nosso prximo objetivo abrigar uma caixa de texto na janela. Para isso, simplesmente criaramos um objeto JTextArea ( o componente visual para grandes reas de texto no formatado (como no notepad do windows) no swing) e

passaramos

para

mtodo

add

().

Mas h um pulo do gato a! At o Java 1.4, no era possvel adicionar componentes grficos diretamente em um JFrame. Isso pq ele um container especial que s permite um nmero limitado de componentes (containers) abrigados nele. Em um JFrame existem alguns containers " invisveis " sobrepostos. O container mais superficial chamado de " contentPane " (painel de contedo) e a superfcie na qual os componentes devem ser dispostos. Usar o mtodo add () do JFrame faria com que nosso componente ficasse embaixo do contentPane , sem efeito visual. Por isso, no J2SE1.4 para trs, o compilador reclama com vc. se isso for feito. Mas ento como raios eu adiciono o componente? Simples, obtenha uma referncia ao contentPane e use o mtodo add () desse container: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. import javax.swing.JFrame; import javax.swing.JTextArea; public class MeuNote extends JFrame { / * Componentes devem estar no contexto da instncia, * para que possam ser acessados em todos os mtodos * no-estticos da classe */ private JTextArea texto = new JTextArea (); public MeuNote () { // Define o ttulo da janela super ("Meu Notepad"); this.montaJanela (); } private void montaJanela () { this.getContentPane (). add (texto); } ... }

No Java 1.5 (J2SE5.0 - Tiger), se vc. usa o mtodo add() do JFrame (this.add(texto)), o compilador j supe que vc. quer adicionar um componente no contentPane e gera um bytecode equivalente a this.getContentPane().add(texto). Boa notcia, no? Mas lembrese: s funciona da verso 5.0 do Java em diante.

Nosso objetivo est quase pronto, j temos nossa janela. Agora s precisamos exibir a mesma. Uma arquitetura melhor seria criar outra classe executvel para usar a nossa janela, inicializando a aplicao criando e exibindo. Mas para sermos simplistas, vamos usar essa classe mesmo, tornando-a uma classe funcional (executvel).

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.

import javax.swing.JFrame; import javax.swing.JTextArea; public class MeuNote extends JFrame { / * Componentes devem estar no contexto da instncia, para que possam ser acessados em todos os mtodos no-estticos da classe */ private JTextArea texto = new JTextArea (); public MeuNote () { / / Define o ttulo da janela super ("Meu Notepad"); this.montaJanela (); } private void montaJanela () { this.getContentPane (). add (texto); } public static void main (String [] args) { / / Cria objeto: MeuNote janela = new MeuNote (); } }

Ponha isso pra rodar e vc. vai ter... nada ! Vc. criou o objeto da janela, mas em momento algum disse para torn-lo visivel ao usurio. Acrescente ento no mtodo main () a linha: 1. janela.setVisible (true);

Ao rodar isso vc. obtm sua janela... Mas ops! ela fica pequenininha l no canto esquerdo. Vc. tem que definir um tamanho para sua janela! Acrescente a linha: 1. /* A medida de tamanho em pixels por polegada, igual a da resoluo da sua t ela */ 2. janela.setSize (640, 480);

Dica: Faa isso antes de exibir sua janela. Assim a JVM no precisa enviar mensagens

ao Sistema Operacional para redimensionar a janela. Defina o tamanho antes (deixando que os componentes dentro da janela se organizem para o tamanho da mesma) e mostre depois! Obs.: Ao invs do setSize(), vc. tambm pode utilizar o mtodo pack() (sem parmetros dessa vez) para que ele configure a janela com o melhor parmetro que abrigue todos os componentes, de acordo com seus tamanhos. Em nosso exemplo no vai adiantar nada, pq no definimos um tamanho (preferencial ou especfico) para o JTextArea. Enfim, eis o cdigo que funciona perfeitamente: 1. import javax.swing.JFrame; 2. import javax.swing.JTextArea; 3. 4. public class MeuNote extends JFrame { 5. /* Componentes devem estar no contexto da instncia, 6. para que possam ser acessados em todos os mtodos 7. no-estticos da classe */ 8. 9. private JTextArea texto = new JTextArea (); 10. 11. public MeuNote () { 12. //Define o ttulo da janela 13. super ("Meu Notepad"); 14. this.montaJanela (); 15. } 16. 17. private void montaJanela () { 18. this.getContentPane (). add (texto); 19. } 20. 21. public static void main (String [] args) { 22. // Cria objeto: 23. MeuNote janela = new MeuNote (); 24. janela.setSize (640, 480); 25. janela.setVisible (true); 26. } 27. }

E o fim de nosso pequeno tutorial. Esse um ponto de partida para evoluir nossas habilidades com alguns temas mais avanados como:

1. Como fazer a minha aplicao interagir com o usurio (tratamento de eventos)? 2. Como colocar uma janela dentro da outra (MDI - Multiple Document Interface)?

3. Como construir um menu e barras de ferramentas? 4. Como tornar meus comandos de aplicao (novo, abrir, salvar, e outros mais complexos) portveis para outras aplicaes que eu fizer? 5. A minha GUI est um pouco feia ou inadequada para usurios acostumados a um determinado Sistema Operacional... H como mudar a aparncia e/ou o comportamento dela (Look And Feel - Aparncia e Comportamento)? 6. Como evitar que a janela "congele" quando a aplicao executar uma ao "pesada" (execuo multitarefa)? 7. Como eu integro minha aplicao ao "icon tray" do Windows?

Para tentar afiar mais suas habilidades em swing e ajudar a atender demanda do Ronaldo, neste tutorial vamos estender as capacidades do nosso MeuNote com duas novidades: a construo de comandos reutilizveis, para botes de barra de ferramentas e menu. No prximo artigo vamos expandir nossa aplicao para usar MDI. Como criar comandos reutilizveis?

Uma grande evoluo na forma como tratamos os comandos de usurio encapsular os procedimentos a serem executados em objetos que possuem uma interface comum. Assim poderemos tratar todos os comandos do usurio da mesma forma. Um usurio aperta um boto de salvar e um arquivo salvo, um usurio aperta um boto e um arquivo aberto... A forma de acionar a ao comum (apertar um boto), mas o procedimento executado diferente. Um padro de projeto que resolve este tipo de problema o chamado padro Command (pesquise por Command - Design Patterns GoF). O Swing implementa esse padro atravs da interface Action e da classe AbstractAction. Para mostrar em termos simples como a coisa funciona, vamos dotar nosso notepad com uma barra de ferramentas, uma barra de menus e alguns comandos bsico de novo, abrir e salvar textos. Primeiramente, vamos construir o novo esqueleto da janela: 1. 2. 3. 4. 5. 6. 7. import java.wat. *; import java.awt.event. *; import javax.swing. *; import javax.swing.event. *;

// Procure no javadoc cada umas das classes que vc. n o conhece neste exemplo . Assim vc. saber em que pacotes elas est o e as conhecer melhor!; -) 8. public class MeuNote extends JFrame { 9. // Componentes 10. private JToolBar toolbar = new JToolBar (" Ferramentas "); 11. private JMenuBar menubar = new JMenuBar (); 12. private JMenu arquivo = new JMenu (" Arquivo "); 13. private JTextArea texto = new JTextArea (); 14. 15. // A es:

16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.

private Action novo = new NovoAction (this.texto); private Action salvar = new SalvarAction (this.texto); private Action abrir = new AbrirAction (); public MeuNote () { super (" Meu Notepad "); // Desliga automaticamente a aplica o quando o usu rio fecha a janela. this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); Container interno = this.getContentPane (); this.montaMenu (); this.montaToolBar (); this.montaGUI (); }

private void montaMenu () { // JMenuItem pode ser constru do a partir de um objeto que implementa a int erface Action 32. JMenuItem itemNovo = new JMenuItem (this.novo); 33. JMenuItem itemSalvar = new JMenuItem (this.salvar); 34. JMenuItem itemAbrir = new JMenuItem (this.abrir); 35. this.arquivo.add (itemNovo); 36. this.arquivo.add (itemSalvar); 37. this.arquivo.add (itemAbrir); 38. this.menubar.add (this.arquivo); 39. this.setJMenuBar (this.menubar); 40. } 41. 42. private void montaToolBar () { 43. // Barras de ferramenta swing tamb m aceitam objetos que implementam Ac tion como par metro de construtor 44. this.toolbar.add (this.novo); 45. this.toolbar.add (this.salvar); 46. this.toolbar.add (this.abrir); 47. } 48. 49. private void montaGUI (Container interno) { 50. interno.setLayout (new BorderLayout ()); 51. interno.add (this.toolbar, BorderLayout.NORTH); 52. interno.add (new JScrollPane (this.texto)); 53. } 54. 55. public static void main (String args []) { 56. // Vc. sabe o que fazer... 57. } 58. }

A principal coisa a notarmos nesse cdigo referente aos menus e a barra de ferramentas. Passamos a eles objetos das classes NovoAction, SalvarAction e

AbrirAction. Notamos tambm que essas classes possuem a interface Action (javax.swing.Action) em comum. Que tipo de objeto esse? Em swing, um objeto Action encapsula todo o necessrio para gerar um boto ou item de menu. O objeto sabe informar (a quem perguntar) o nome da ao que executa, a imagem de seu boto, a descrio curta ou extensa sobre o trabalho que realiza e, por fim, ele sabe realizar a tarefa para o qual foi desenhado. Tudo isso em um s objeto (ou seja, ele mais do que um simples ouvinte de evento)! Como criar este tipo de objeto? Vou mostrar aqui como escrever as classes NovoAction e SalvarAction, deixando a ltima, AbrirAction, como exerccio pra voc, ok? Bem, uma forma bem mais fcil de escrever uma action criando uma subclasse de java.swing.AbstractAction: 1. public class NovoAction extends AbstractAction { 2. private JTextArea texto; 3. public NovoAction (JTextArea texto) { 4. // Define o nome da a o 5. super (" Novo "); 6. 7. // Define mais algumas caracter sticas 8. this.putValue (Action.SMALL_ICON, new ImageIcon (" new.gif ")); 9. this.putValue (Action.SHORT_DESCRIPTION, " Limpa a rea de texto "); 10. // Consultem a documenta o de javax.swing.Action para outras propriedad es 11. } 12. 13. // Definimos aqui o procedimento que ser executado quando NovoAction for acionado 14. public void actionPerformed (ActionEvent ev) { 15. this.texto.setText (" "); 16. } 17. }

1. public class SalvarAction extends AbstractAction { 2. private JTextArea texto; 3. public SalvarAction (JTextArea texto) { 4. // Define o nome da a o 5. super (" Salvar "); 6. // Define mais algumas caracter sticas 7. this.putValue (Action.SMALL_ICON, new ImageIcon (" save.gif ")); 8. this.putValue (Action.SHORT_DESCRIPTION, " Salva arquivo texto "); 9. // Consultem a documenta o de javax.swing.Action para outras propriedad es 10. } 11. 12. // Definimos aqui o procedimento que ser executado quando NovoAction for a cionado

13. public void actionPerformed (ActionEvent ev) { 14. JFileChooser jfc = new JFileChooser (); 15. int resp = jfc.showSaveDialog (this.texto); 16. if (resp! = JFileChooser.APPROVE_OPTION) return; 17. 18. File arquivo = jfc.getSelectedFile (); 19. this.saveFile (arquivo); 20. } 21. 22. // Aqui trabalhamos com classes do java.io 23. private void saveFile (File f) { 24. try { 25. FileWriter out = new FileWriter (f); 26. out.write (this.texto.getText ()); 27. out.close (); 28. } catch (IOException e) { 29. JOptionPane.showMessageDialog (null, e.getMessage ()); 30. } 31. } 32. }

A parte interessante disso tudo que, se tivermos outro projeto em que seja preciso apagar, salvar ou abrir arquivos de texto em uma JTextArea, poderemos reaproveitar as classes de ao facilmente, pois elas j so razoavelmente auto-suficientes e so pouco dependentes do MeuNote em si (um desafio para voc: como aumentar ainda mais o potencial de reutilizao dessas actions, de forma que elas no dependam mais da referncia a uma JTextArea, mas possam apagar, salvar e abrir arquivos em qualquer lugar?). Quando construir seu projeto, ver que as aes se tornam menus e botes " automagicamente ". Quando um menu clicado, ou um boto da barra de ferramentas criado, o mtodo actionPerformed da ao correspondente invocado. Por hora terminamos esse tutorial. Por questo de brevidade, no respondi todas as duvidas possveis, embora saiba que muitas sero levantadas. Fico no aguardo de vocs para fazerem as perguntas. Esse tutorial vai facilitar o entendimento do prximo artigo, onde vou mostrar a construo de interfaces MDI. At l!

Leia Criando Mergulhando NetBeans 6.5, Tudo

uma jtree sobre no treeModel o

tambm: Janela Swing SwingX e defaultMutableTreeNode GridBagLayout.