Forum Main Page > Java Básico

Criando uma simples Janela Swing

Goto page 1

New Topic    Reply Message


  1. Copernico
    Offline
    Posts: 530

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Este tutorial é bem básico, feito para quem não tem prática na criação de interfaces gráficas em java.

    Certo, queremos criar uma simples interface com o usuário que seja uma janela padrão (com funções de minimizar, maximizar e fechar) contendo um caixa de texto dentro (digamos que seja um início para o nosso notepad em java :00ps: ).

    Sigamos o raciocínio: primeiro fazemos a janela. Como em java trabalhamos com objetos em tudo então precisamos de um objeto que seja uma janela. Então nossa classe de janela vai herdar da classe de janela do Swing (prefira-o ao awt, na maioria dos casos):



    Bem, jé temos uma classe que cria objetos que são janelas. Agora precisamos construir a infra-estrutura da janela, modificando-a e adicionando coisas. Isso faz parte do processo de construção da janela e nenhum lugar melhor para isso que no construtor da classe!

    Antes uma pequena pausa para explicar um detalhe. As API gráficas do java provêm dois tipos de componentes visuais: componentes propriamente ditos e containers.

      Um componente é uma peça (widget) que tem alguma função na interface.

      Um container é um componente que tem a capacidade de abrigar outros componentes (conteiners possuem um método add(), que recebe qualquer componente como parâmetro e o adiciona a sua lista de componentes "abrigados").


    Sem entrar em muitos méritos (esse é um tutorial curto), o swing tem uma característica interessante adicional: todos os componentes swing, todos mesmo são também containers (possuem um método add())! :shock:



    Retomando a nossa trilha agora: nosso próximo objetivo é abrigar uma caixa de texto na janela. Para isso, simplesmente criaríamos um objeto JTextArea (é o componente visual para grandes áreas de texto não formatado (como no notepad do windows) no swing) e o passaríamos para o método add().

    Mas há um pulo do gato aí! Até o Java 1.4, não era possível adicionar componentes gráficos diretamente em um JFrame. Isso pq ele é um container especial que só permite um número limitado de componentes (containers) abrigados nele. Em um JFrame existem alguns containers "invisíveis" sobrepostos. O container mais superficial é chamado de "[color=red:ec9b2e8e19]contentPane[/color:ec9b2e8e19]" (painel de conteúdo) e é a superfície na qual os componentes devem ser dispostos.

    Usar o método add() do JFrame faria com que nosso componente ficasse embaixo do [color=red:ec9b2e8e19]contentPane[/color:ec9b2e8e19], sem efeito visual. Por isso, no J2SE1.4 para trás, o compilador reclama com vc. se isso for feito.

    Mas então como raios eu adiciono o componente? Simples, obtenha uma referência ao contentPane e use o método add() desse container:



    No Java 1.5 (J2SE5.0 - Tiger), se vc. usa o método add() do JFrame (this.add(texto)), o compilador já supõe que vc. quer adicionar um componente no contentPane e gera um bytecode equivalente a this.getContentPane().add(texto). Boa notícia, não? Mas lembre-se: só funciona da versão 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 executável para usar a nossa janela, inicializando a aplicação criando e exibindo. Mas para sermos simplistas, vamos usar essa classe mesmo, tornando-a uma classe funcional (executável).



    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 usuário. Acrescente então no método main() a linha:



    Ao rodar isso vc. obtém sua janela... Mas ops! ela fica pequenininha lá no canto esquerdo. Vc. tem que definir um tamanho para sua janela!

    Acrescente a linha:



    Dica: Faça isso antes de exibir sua janela. Assim a JVM não 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 invés do setSize(), vc. também pode utilizar o método pack() (sem parâmetros dessa vez) para que ele configure a janela com o melhor parâmetro que abrigue todos os componentes, de acordo com seus tamanhos. Em nosso exemplo não vai adiantar nada, pq não definimos um tamanho (preferencial ou específico) para o JTextArea.

    Enfim, eis o código que funciona perfeitamente:



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

      1- Como fazer a minha aplicação interagir com o usuário (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 aplicação (novo, abrir, salvar, e outros mais complexos) portáveis para outras aplicações que eu fizer?

      5- A minha GUI está um pouco feia ou inadequada para usuários acostumados a um determinado Sistema Operacional... Há como mudar a aparência e/ou o comportamento dela (Look And Feel - Aparência e Comportamento)?

      6- Como evitar que a janela "congele" quando a aplicação executar uma ação "pesada" (execução multitarefa)?

      7- Como eu integro minha aplicação ao "icon tray" do Windows?


    Esses e outros tópicos podem ser explorados nos próximos tutoriais. Qual o próximo assunto que vc. gostaria de ver explorado? Opine!

    E, da próxima vez, considere fazer sua nova aplicação como uma aplicação desktop, oferecendo mais recursos visuais e integração ao seu usuário. Afinal além de cada vez mais rápido a cada nova versão, java é portável, aproveite isso! :!:
    _________________
    JavaFree.org




  1. Ronaldo
    Offline
    Posts: 216

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    O assunto que eu gostaria de ver explorado é de MDI e também de telas de modelo para telas de cadastro (com botões incluir, salvar, excluir, atualizar...) e também para telas de pesquisa.

    Se possível, gostaria de ver alguma técnica para facilitar a obtenação de dados por consulta.

    Ex: suponha que eu tenha que informar um cliente em determinado cadastro. Então eu tenho que ter um botão localizar cliente. Esse botão irá abrir a tela de pesquisa de cliente (abrir em showmodal) e quando o usuário selecionar o cliente, é retornado para a janela anterior o cliente selecionado.

    Eu gostaria de saber o que fazer para não ter que repetir sempre o código de instanciar a janela de pequisa, obter o objeto selecionado. Teria alguma coisa?
    _________________
    Vamos pescar de caiaque?
    Sou representante dos caiaques lontra. São bons para pesca e mergulho.
    http://www.caiaquelontras.com.br/




  1. Copernico
    Offline
    Posts: 530

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Olá pessoal! Oi Ronaldo.

    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 construção de comandos reutilizáveis, para botões de barra de ferramentas e menu. No próximo artigo vamos expandir nossa aplicação para usar MDI.

    Como criar comandos reutilizáveis?

    Uma grande evolução na forma como tratamos os comandos de usuário é encapsular os procedimentos a serem executados em objetos que possuem uma interface comum. Assim poderemos tratar todos os comandos do usuário da mesma forma. Um usuário aperta um botão de salvar e um arquivo é salvo, um usuário aperta um botão e um arquivo é aberto... A forma de acionar a ação é comum (apertar um botão), mas o procedimento executado é diferente. Um padrão de projeto que resolve este tipo de problema é o chamado padrão Command (pesquise por Command - Design Patterns - GoF). O Swing implementa esse padrão através da interface [color=red:9a7cf41c63]Action[/color:9a7cf41c63] e da classe [color=orange:9a7cf41c63]AbstractAction[/color:9a7cf41c63].

    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 básico de novo, abrir e salvar textos. Primeiramente, vamos construir o novo esqueleto da janela:



    A principal coisa a notarmos nesse código é referente aos menus e a barra de ferramentas. Passamos a eles objetos das classes NovoAction, SalvarAction e AbrirAction. Notamos também 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 necessário para gerar um botão ou item de menu. O objeto sabe informar (a quem perguntar) o nome da ação que executa, a imagem de seu botão, a descrição 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 exercício pra você, ok? Bem, uma forma bem mais fácil de escrever uma action é criando uma subclasse de java.swing.AbstractAction:





    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 ação facilmente, pois elas já são razoavelmente auto-suficientes e são pouco dependentes do MeuNote em si (um desafio para você: como aumentar ainda mais o potencial de reutilização dessas actions, de forma que elas não dependam mais da referência a uma JTextArea, mas possam apagar, salvar e abrir arquivos em qualquer lugar?).

    Quando construir seu projeto, verá que as ações se tornam menus e botões "automagicamente". Quando um menu é clicado, ou um botão da barra de ferramentas é criado, o método actionPerformed da ação correspondente á invocado.

    Por hora terminamos esse tutorial. Por questão de brevidade, não respondi todas as duvidas possíveis, embora saiba que muitas serão levantadas. Fico no aguardo de vocês para fazerem as perguntas.

    Esse tutorial vai facilitar o entendimento do próximo artigo, onde vou mostrar a construção de interfaces MDI. Até lá! :!:
    _________________
    JavaFree.org




  1. daltoncamargo
    Offline
    Posts: 8768

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Parabéns pelos tutoriais, estou adorando (eu que não conhecia muito de swing :) )
    Apenas duas correções:


    É obrigatório o tratamento para a IOException, e o
    File arquivo = jfbc.getSelectedFile(); não existe, é jfc, mas é apenas um detalhe! :o

    Ahh, na MeuNote.java, no método:



    A classe JScrollBar está acusando um erro:

    Quote:
    The constructor JScrollBar(JTextArea) is undefined



    :arrow:

    Editado novamente:



    Na invocação do método montaGUI, você deverá passar o interno como parâmetro também :!:
    _________________
    Dalton Camargo

    Sugestão de Livro do JavaFree para os iniciantes em Java

    0




  1. Copernico
    Offline
    Posts: 530

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Obrigado pelas correções... Já corrigi o que eu vi . É que eu não tive muito tempo pra escrever a segunda parte e tive que escrever o código de cabeça... sorry! ops:
    _________________
    JavaFree.org




  1. junior.esnaola
    Offline
    Posts: 472

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    muito legal o tutorial Copérnico

    só a JScrollBar esta desalinhada, fiz uns testes e consegui arruma-la:

    interno.add(new JScrollBar(), BorderLayout.EAST);

    me puxei pois nunca tinha feito nada com swing

    mas nao consegui fazer a classe abre


    se alguem fez e quizer posta-la ae pra mim dar uma olhada basica agradeço
    _________________
    SCJP 1.4
    SCJP 1.5
    JavaFree.org




  1. Copernico
    Offline
    Posts: 530

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Eu errei, era JScrollPane, e não JScrollBar...

    Já que muita gente se interessou, eu vou ver se consigo um tempo pra escrever direito, compilar tudo e por no download...
    _________________
    JavaFree.org




  1. Copernico
    Offline
    Posts: 530

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Visitante.

    Sua dúvida diz respeito à exibição e atualização de dados em um formulário, certo? Neste tutorial, ainda não chegamos lá ainda, estaremos tratando de outro escopo.

    Sendo assim, resolvi mover a sua dúvida para outro tópico, onde poderemos escrever especificamente sobre este assunto, ok?

    Nos encontramos em: http://www.javafree.com.br/forum/viewtopic.php?t=13989
    _________________
    JavaFree.org




  1. Lich King
    Offline
    Posts: 46

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    há alguma diferenca d performance entre usar JInternalFrame ou JFrame???
    qual dos dois eh + aconselhável usar???
    _________________
    programmer.setFucked(user.isStupid() );




  1. Copernico
    Offline
    Posts: 530

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    São usados para propósitos diferentes...

    JFrame, assim como JWindow e JDialog (e suas contrapartes AWT) é um container "top-level", ou seja, pode ser desenhado diretamente no contexto gráfico do sistema operacional.

    JInternalFrame é uma janela que só pode ser adicionada dentro de um JDesktopPane. Ela não pode ser desenhada sem ele e é feita especialmente para isso (vc. não pode pôr um JFrame dentro de um JDesktopPane). Para criar uma interface MDI vc. usa um JFrame, um JDesktopPane dentro dele e 1..n JInternalFrames, que aparecerão dentro do JDesktopPane.

    Como vc. pode ver JFrame e JInternalFrame tem usos inteiramente diferentes, um não pode substituir o outro...
    _________________
    JavaFree.org




  1. Lich King
    Offline
    Posts: 46

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    esses action funcionam com textfields????
    _________________
    programmer.setFucked(user.isStupid() );




  1. bugaavila
    Offline
    Posts: 0

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Salve salve Javaneses.

    Preliminarmete registro meus agradecimentos pelo tutorial.

    Apenas alguns ajustes que tive que fazer em meu projeto.

    Ao clicar nas opções de menu para fazer chamada aos objetos actions, o compilador retornava erro de "NullPointerException". Isso ocorre pq a referencia ao objeto na classe action sempre referenciava a instancia texto desta propria classe (this.texto....), assim a superclasse não conseguia "enxergar" tal objeto.
    Solução:
    Passei como parâmetro para meu construtor das classes actions o meu JTextArea (texto) da superclasse, e em seguida a subclasse.texto recebeu meu objeto superclasse.texto. Veja no código:






    Existem outras maneiras de resolver este problema, como por exemplo austar a referência ao objeto texto da seguinte maneira. NomeDaSuperClasse.this.objeto. Talvez eta não seja a forma mais elegante de resolver o problema, pois você poderá ter problemas de reutilização de código.


    Por fim, estou submetendo minha classe AbrirAction:






    Até a próxima!


    Adriano Ávila
    _________________
    JavaFree.org




  1. Lich King
    Offline
    Posts: 46

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    como q usa a herança d formulários no java????
    _________________
    programmer.setFucked(user.isStupid() );




  1. Ronaldo
    Offline
    Posts: 216

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Da mesma forma que usa herança de qualquer outro objeto. Basta extender a classe usando o comando extends.

    public class FormularioFilho extends FormularioPai {...}
    _________________
    Vamos pescar de caiaque?
    Sou representante dos caiaques lontra. São bons para pesca e mergulho.
    http://www.caiaquelontras.com.br/




  1. Lich King
    Offline
    Posts: 46

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    mas como q eu faco isso usando netbeans???
    _________________
    programmer.setFucked(user.isStupid() );




  1. Ronaldo
    Offline
    Posts: 216

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    ai já nao sei.
    mas normalmente é só mandar criar uma classe qualquer e digitar o código fonte da classe.
    _________________
    Vamos pescar de caiaque?
    Sou representante dos caiaques lontra. São bons para pesca e mergulho.
    http://www.caiaquelontras.com.br/




  1. leod
    Offline
    Posts: 7

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    Como eu colocaria, digamos o Nome do arquivo aberto no Titulo (setTitle(String) ), e como quando eu fosse Slavar o arquivo ja aberto, existente, ja salvava direto ser ter de escolher o nome, e o local?


    Pq extendendo a classe não consegui setar o Titulo depois, mas criando um Objeto JFrame, e fazendo torcando o this pelo objeto criado eu consegui.Teria algum outro jeito?

    Muito Obrigado
    _________________
    JavaFree.org




  1. Hero_of_sand
    Offline
    Posts: 0

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    eu to com um problema.... espero que vcs possam me responder o mais rapido possivel....

    eu ta querendo salvar arquivos apenas .txt, para isso to tentando forçar a extensao .txt (se o arquivo nao for .txt ou .TXT). Para isso to tentando renomear o arquivo que o usuario vai salvar mas nunca da certo pq o metodo renameTo sempre ta retornando false... num sei pq..


    to fazendo assim..




    sendo que file é o arquivo que é o File que recebe o getSelectedFile() do JFileChooser....




  1. simu
    Offline
    Posts: 5424

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    A documentacao diz que o metodo pode falhar:
    1) por nao conseguir mover o arquivo de um disco (filesystem) para outro
    2) se ja existir um arquivo com esse nome/caminho

    e talvez tambem pode dar problema se o arquivo estiver 'aberto' em outra aplicacao ou pelo proprio programa

    Meu conselho: faz um system.out.println do arquivo velho e do novo, e tambem verifique a (nao)existencia do novo arquivo, para ter certeza do que esta acontecendo



    []]]
    _________________
    Carlos Heuberger
    GC do Javafree.org
    ____________________________________________________________________________

    This posting is provided AS IS with
    no warranties and confers no rights.




  1. PALopes
    Offline
    Posts: 4

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    podia fazer um breve tuto sobre icon tray.




  1. simone07
    Offline
    Posts: 1

    Comment Arrow

    Publicado em: 10/04/2009 00:18:44

    this.montaGUI(); ocorre o seguinte erro nesta linha

    cannot be applied to()

    nao estou conseguindo resolver




  1. Relacionados





New Topic    Reply Message     Forum Main Page -> Java Básico


Goto page 1