AMBIENTE GRÁFICO - Swing

 

As aplicações gráficas são elaboradas com intuito de facilitar a comunicação software-usuário, pois é mais agradável e intuitivo trabalhar com este tipo de ambiente na interação com o usuário.

 

O pacote AWT é que trabalha com essas aplicações em Java, sendo no Java 2 disponibilizada suas evoluções no Swing. Os recursos já disponíveis na AWT e evoluídos no Swing tiveram seus identificadores de classe na Swing acrescidos de um J (jota) na frente do nome original na AWT, por exemplo: Button passou a ser JButton.

 

A figura a seguir representa as principais classes disponíveis nestes recursos gráficos em Java (AWT em amarelo e Swing em azul).

 
 

Cada um destes recursos pode ser estudado mais especificamente como um componente a ser empregado possivelmente em uma aplicação gráfica em Java. Porém, neste material, propõe-se a uma abordagem mais genérica e essencial a elaboração de aplicações gráficas em Java, sendo facilmente usados estes componentes a partir do entendimento deste conteúdo.

   
Janelas de Diálogo
 

Geralmente, a interação entre usuário e sistema é realizada por meio de janelas ou caixas de diálogos, provenientes da classe JOptionPane. Esta classe fornece fácil manipulação de janelas gráficas capazes de interagir com o usuário diretamente, durante a execução de uma aplicação gráfica em Java.

 

Basicamente, são quatro as circunstâncias prevista para o uso deste tipo de interação através de janelas de diálogo manipuladas por seus respectivos métodos estáticos específicos: MessageDialog, ConfirmDialog, InputDialog, OptionDialog.

 

Estas janelas são formadas por:

 
  • Título na janela de dialogo;
  • Mensagem orientadora destinada ao contato com usuário;
  • Ícone representativo do tipo de mensagem:
    • Informação;
    • Pergunta;
    • Alerta (ou advertência);
    • Erro;
    • Um outro qualquer que seja definido pelo usuário;
  • Um ou mais botões de interação com usuário.
 

MessageDialog: Mostra somente uma informação, geralmente notificadora, ao usuário, sendo sua sintaxe mais comum:

 
JOptionPane.showMessageDialog(Componente, Mensagem, 
		                      Título da Janela, Tipo de Mensagem);
             
 
  • Componente: referente ao objeto do tipo contêiner que permite definir a posição na tela em que a janela de dialogo aparecerá. Normalmente seu valor é null para que a janela se apresente no centro da tela;
  • Mensagem: mensagem que a janela mostrará ao usuário;
  • Título da Janela: título que será mostrado na janela;
  • Tipo de Mensagem: define o ícone padrão que será apresentado na janela de dialogo, ou outro ícone qualquer definido no sistema, ou ainda sem ícone algum.
 
 
/**
*Síntese
*   Objetivo: realizar uma saudação
*   Entrada: sem entrada
*   Saída: a saudação
*/

import javax.swing.JOptionPane;

public class MessageDialog {
    public static void main(String [] args) {
        JOptionPane.showMessageDialog(null,"Seja bem-vindo ao ambiente gráfico!",
               "Informação",JOptionPane.INFORMATION_MESSAGE);
    }
}

 

Os possíveis ícones que são padrões das janelas de diálogos em Java são usados por meio de suas definições constantes relacionadas a seguir:

 
 

O uso dos demais métodos (ConfirmDialog, InputDialog, OptionDialog), assim como seus parâmetros adequados, podem ser observados, inclusive com vários exemplos nos arquivos compactado e disponível na instalação de seus JDK. Aqueles que estiverem usando o Java na versão 5 ou superior poderão descompactar e executar o arquivo SwingSet2.jar (localizado em \Java\jdk1.5.0_09\demo\jfc - executar a instrução java -jar SwingSet2.jar indicando a localização exata deste arquivo em seu computador) para ter acesso a um material prático e esclarecedor sobre as janelas de diálogos (JOptionPane) e outros componentes gráficos.

 

Java fornece ao desenvolvedor basicamente 5 APIs que simplificam o desenvolvimento de aplicações gráficas visualmente interessantes e intuitivas, melhorando a interação com o usuário e que ainda podem ser usadas em aplicações Java e Applets, sendo elas:

 
  • AWT;
  • Swing;
  • Java2D;
  • Accessibility;
  • Drag and Drop.
 

A API Swing trabalha num nível mais abstrato, de forma que tenta desenhar as telas independente do Sistema Operacional, com isso seu desempenho é menor e o uso de memória RAM é mais elevado. Graças a isso, as telas Swing possuem uma aparência independente do SO.

 
CONTÊINERES
 
 

No desenvolvimento de aplicações gráficas, alguns recursos são utilizados com função de contêineres, ou seja, componentes onde outros recursos gráficos são alocados. Em Java, as principais classes contêineres são:

 
  • Component: Classe abstrata base de todas as classes AWT que podem ser mostradas ao usuário;
  • Container: subclasse abstrata de Component e base para as classes que comportam outros componentes;
  • Panel: herda a classe Container e corresponde a uma área que pode ser inserida em um Frame;
  • Frame: Representa uma janela completa, com título, bordas, menu e cantos que podem redimensioná-la.
 
Component
 

Um componente, baseado na classe Component, é um objeto que faz interação com usuário por meio do mouse e/ou teclado. Esses componentes são agrupados em contêineres (Container) e apresentados, geralmente, em painéis (Panel) que compõem quadros (Frame) adequados para a interação almejada com seus usuários. Cada um desses componentes possui propriedades próprias (tamanho, cor, fonte etc.) que podem ser alteradas em tempo de desenvolvimento ou execução, conforme as expectativas de interação.

 
JFrame
 

O desenvolvimento de aplicações GUI utilizará a extensão da classe AWT na maioria dos recursos otimizados na Swing. A criação das janelas gráficas visualizadas pelo usuário será realizada pela JFrame (extensão da Frame na AWT). Esse componente cria uma janela que possui os itens indicados anteriormente (título, barra de menu etc.), mas pode ainda conter outros componentes, como botões, área de texto etc., gerando uma aplicação gráfica com a qual o usuário possa interagir facilmente.

 

Principais Características da JFrame

 
  • Exige importação da javax.Swing;
  • As janelas criadas pela JFrame são configuradas para não serem visíveis no seu valor padrão de criação;
  • O tamanho padrão (altura e largura) são 0 (zero), sendo necessária a definição do tamanho real;
  • São compostas por painéis de conteúdos que permitem uma interação mais organizada com o usuário;
  • Existem diversos componentes que podem compor o interior de um JFrame. Abaixo serão apresentados os mais utilizados.
 

Alguns Métodos Disponíveis na API da JFrame

 
  • JFrame: Método construtor. Cria uma janela vazia;
  • getTitle: obtém o título da janela;
  • setTitle(String): define o título da janela;
  • SisResizable: verifica se a janela é ou não dimensionável;
  • setResizable(boolean): define se a janela é dimensionável ou não;
  • setIconeImage(Image): define ícone quando minimizado;
  • setSize(int, int): define o tamanho da janela;
  • setLocation(int, int): posiciona a janela no monitor;
  • setVisible(boolean): define se a janela é visível ou não;
  • setBounds(int, int, int, int): posiciona e dimensiona a janela;
  • show: método da classe Window que é herdado pela JFrame para apresentação da janela na aplicação (método deprecated).
 
JPanel
 

A programação gráfica adequada trabalha com painéis, os quais serão organizados e apresentados aos usuários da aplicação pelo JFrame, que os contém de forma visual bem organizada, como os componentes (botões, áreas de texto, etc.) coerentes em uma janela de interação.

 
 

Com o uso de painéis é possível um posicionamento mais preciso dos componentes em uma janela gráfica, podendo ainda, vários painéis serem colocados em uma mesma janela (JFrame). Os painéis possuem características recipientes (container), ou seja, eles recebem outros componentes, inclusive outros painéis (aninhar).

 
// cria um painel vazio
   JPanel painel = new JPanel( [] );

// acrescenta um componente no painel
   painel.add();
 
A classe Font
 

A exibição de textos nas aplicações pode ser customizada com o uso da classe Font e de métodos da classe Graphics, por exemplo:

 
Font fonte = new Font( "Arial" , Font.PLAIN , 12);

 

No método construtor da classe Font estão sendo passados três parâmetros:

 
  • Família da Fonte: String com o nome da família da fonte (font family);
  • Característica da Fonte: Inteiro que define a característica da fonte. A classe Font define algumas constantes que podem ser combinadas:
    • normal = Font.PLAIN
    • negrito = Font.BOLD
    • itálico = Font.ITALIC
    • negrito e itálico = Font.BOLD + Font.ITALIC
  • Tamanho da Fonte: Inteiro com o tamanho da fonte.
 
A classe Color
 

Uma outra configuração do ambiente gráfico é possível pela classe Color, além de alguns métodos da classe Graphics, que permitem a modificação das cores de fundo (segundo plano) e do objeto (primeiro plano).

 

Existem diversas formas de se alterar as cores de uma aplicação gráfica em Java. A classe Color define 13 constantes de cores, mas também é possível aos objetos da classe Color trabalhar a intensidade das cores vermelho, verde e azul (RGB), variando entre 0 e 255 (1 byte), para compor muitas outras cores que possam ser mais interessantes na aplicação gráfica.

 
 
Alguns métodos da classe Graphics
 

Para visualização e alteração de fontes e cores, alguns métodos da classe Graphics devem ser utilizados, melhorando a interface de interação entre o usuário e a aplicação gráfica desenvolvida, por exemplo:

 
  • setFont(Font): define a família da fonte para um objeto gráfico;
  • drawString(String, int, int): desenha o texto passado como parâmetro na posição enviada como parâmetro (x e y), com a família e cor definidas como padrão;
  • setColor(Color): altera a cor do contexto gráfico;
  • setBackground(Color): define a cor do segundo plano;
  • setForeground(Color): define a cor do primeiro plano.
 

Exemplo:

 
/**
*Síntese
*   Objetivo: saudar usuário
*   Entrada: sem entrada
*   Saída: saudação de bom dia
*/

import java.awt.*; 
import javax.swing.*; 
public class Principal extends JFrame {
    
    Principal( ) {
          setTitle("Aplicação Gráfica");
          setSize(300,200);
          setBackground(Color.yellow);
          Container container = getContentPane();
          container.add( new  PainelTexto() );
    
          // Inseri uma imagem na barra de título
          Toolkit kit = Toolkit.getDefaultToolkit();
          Image imagem = kit.getImage("figura.jpg");
          setIconImage(imagem);
    }

    public static void main(String [] args) {
        JFrame janela = new Principal();
        janela.setVisible(true);
    }
	
    // Nova classe que não é pública presente no mesmo arquivo
    class PainelTexto extends JPanel {
    
        public void paintComponent(Graphics grafico) {
            setForeground(Color.blue);
            Font fonte = new Font("SansSerif",Font.BOLD,14);
            grafico.setFont(fonte);
            grafico.drawString("Bom dia!", 20, 50);
        }
    
    }
}

 

A representação da execução do programa anterior resultaria na janela a seguir:

 
 

Observações importantes sobre o programa anterior

 
  • O getContentPane() é um método que obtém as características de um painel e o add acrescenta um componente no objeto;
  • A classe Toolkit permite uma interação com o sistema Operacional (Windows, Linux, etc.), enquanto o método getDefaultToolkit() obtém seu estado atual e o getImage() retorna uma imagem que será lida de um arquivo;
  • A classe Image permite a manipulação de imagens por sua aplicação gráfica;
  • O método setIconImage() pertence a JFrame e permite a inserção de uma imagem (ícone) na barra de título da janela;
  • O método paintComponent() permite o desenho (elaboração gráfica) na janela em sua aplicação.
 
Finalizar uma Aplicação Gráfica em Java
 

Observe na execução do exemplo anterior que a aplicação não é encerrada depois que o botão de fechar a aplicação gráfica, no canto superior direito, é acionado. Isso ocorre porque, na verdade, ao clicar no botão de fechar, a visibilidade da janela se torna falsa (false), mas a execução da aplicação continua em seu computador.

 

Em uma aplicação gráfica é necessário acompanhar a interação com o usuário, sendo isso possível pelo uso de eventos que são assistidos ou ouvidos pelos recursos implementados na aplicação. No exemplo a seguir será usado um evento que acompanhará o acionamento do botão fechar de uma janela e encerrará a aplicação quando isso acontecer.

 
/**
*Síntese
*   Objetivo: saudar usuário e encerrar a execução ao fechar a janela
*   Entrada: sem entrada
*   Saída: saudação de bom dia
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Janela extends JFrame {

	  Janela (String titulo ) {     // construtor de Janela
          super (titulo);              // título na superclasse
          setSize(300,200);
          setBackground(Color.yellow);

          // cria objeto de uma classe interna anônima    
          this.addWindowListener( new WindowListener() {
               // método anterior inclui acompanhamento na janela e
               // obriga a implementação de todos métodos desta interface
   
               public void windowActivated(WindowEvent evJanela) {
    
               }
    
               public void windowClosed(WindowEvent evJanela) {
    
               }
    
               public void windowClosing(WindowEvent evJanela) {
                     fechaJanela();
               }
    
               public void windowDeactivated(WindowEvent evJanela){
    
               }
    
               public void windowDeiconified(WindowEvent evJanela){
    
               }
    
               public void windowIconified(WindowEvent evJanela) {
    
               }
    
               public void windowOpened(WindowEvent evJanela) {
    
               }
    
          });   // termina classe anônima

          Container container = getContentPane();    
          container.add(new PainelTexto());
    
          // Inseri imagem na barra de título
          Toolkit kit = Toolkit.getDefaultToolkit();
          Image imagem = kit.getImage("figura.jpg");  // localizar figura correta 
          setIconImage(imagem);

	  }

      public void fechaJanela() {
          System.exit(0);    // método que encerra o programa
      }
        
      public static void main(String [] args) {
         JFrame janela = new Janela("Aplicação Gráfica");
         janela.setVisible(true);       
      }
    
// Nova classe que não é pública e está no mesmo arquivo

	class PainelTexto extends JPanel {

        public void paintComponent(Graphics grafico) {
            setForeground(Color.blue);
            Font fonte = new Font("SansSerif",Font.BOLD,14);
            grafico.setFont(fonte);
            grafico.drawString("Bom dia!", 20, 50);
    
        }

	}
}// termina a classe pública

 

Nessa reformulação, um Listener (acompanhador) é adicionado ao JFrame e são definidos vários métodos para cada evento que esse Listener reconhece. Como pode ser percebido, apesar de serem implementados todos os métodos abstratos da interface WindowListener, apenas um é usado (windowClosed).

 

Como muitas vezes é preciso usar apenas um ou outro método de uma interface, a linguagem Java disponibiliza classes que implementam, de forma neutra e padrão, os métodos das interfaces que não serão redefinidos por sua aplicação, restando ao desenvolvedor o trabalho de implementar apenas os métodos que serão usados. Essas classes que implementam os métodos das interfaces são denominadas como Adapters (classes adaptadoras).

 

O exemplo do programa anterior irá implementar a classe adaptadora para manipular janelas (WindowAdapter) e possibilitar a implementação somente do método desejado (windowClosing) ao correto funcionamento desta aplicação em sua nova versão listada a seguir:.

 
/**
*Síntese
*   Objetivo: saudar usuário e encerrar a execução ao fechar a janela
*   Entrada: sem entrada
*   Saída: saudação de boa tarde
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Janela2 extends JFrame {
    
    	Janela2(String titulo ) {             // construtor de Janela2        
              super (titulo);              // título na superclasse
              setSize(300,200);
              setBackground(Color.blue);

              // cria objeto de uma classe interna anônima com adaptadora        
              this.addWindowListener( new WindowAdapter() {
                   // método anterior inclui acompanhamento na janela
     
                   public void windowClosing(WindowEvent evJanela) {   
                           fechaJanela();
                   }
        
              } );  // termina classe anônima
        
              Container container = getContentPane();
              container.add(new PainelTexto());
        
              // Inseri imagem na barra de título
              Toolkit kit = Toolkit.getDefaultToolkit();
              Image imagem = kit.getImage("figura.jpg");  // localizar figura correta
              setIconImage(imagem);
        }
        
        public void fechaJanela() {
               System.exit(0);    // método que encerra o programa
        }
        
        public static void main(String [] args) {      
            JFrame janela = new Janela2("Aplicação Gráfica");
            janela.setVisible(true);
        }
        
        // Nova classe que não é pública
        
        class PainelTexto extends JPanel {
        
            public void paintComponent(Graphics grafico) {                
                setForeground(Color.yellow);
                Font fonte = new Font("SansSerif",Font.BOLD,14);
                grafico.setFont(fonte);
                grafico.drawString("Bom tarde!", 20, 50);
            }
        
        }

}   // termina a classe pública

 

Repare que nesta última versão do programa de saudação o único método implementado da interface WindowListener foi o windowClosing, pois somente ele será usado por esta aplicação.

 

Nos últimos exemplos deste programa foi usado um método para adicionar um acompanhador (listener) na janela. Esse método recebe um nome seguindo o padrão indicado a seguir:

 
add <tipo do objeto> Listener

 

Observe no programa anterior que foi incluído um acompanhador (listener) de janelas, sendo o nome de sua inclusão addWindowListener. Esse Listener que é adicionado ao objeto acompanha os eventos do referido objeto. Quando um evento tem relação com um de seus métodos, esse então é disparado e entra em execução. Nos últimos exemplos anteriores, quando acontece o evento do usuário fechar a janela será disparado o método windowClosing, que por sua vez aciona o método criado pelo programador desta aplicação denominado fechaJanela().

 

Na criação de aplicações gráficas é importante saber usar os componentes básicos que geralmente são utilizados em sua elaboração, inclusive quando estas aplicações forem para web. Por isso, serão apresentados a seguir somente estes componentes mais comuns e importantes, pois a partir de seu conhecimento se tornará mais fácil aprender como usar a infinidade dos recursos deste tipo que estão disponíveis para área de Programação em ambientes gráficos. Assim, são apresentadas a seguir estes componentes de maneira resumida.

 
JLabel
 

O componente gráfico denominado Label corresponde a uma etiqueta ou rótulo que possui um texto e características de fonte a ser apresentada na janela gráfica de uma aplicação. A classe JLabel permite inclusão de rótulos com envolvimento de texto, imagens e alinhamento que orientem o usuário da aplicação, por exemplo:

 
JLabel identificador = new JLabel(texto, JLabel.alinhar);

 
  • texto: String que será mostrada como rótulo na aplicação em execução;
  • alinhar: forma de alinhamento do rótulo, sendo definida nesta classe pelos valores constantes: LEFT, RIGHT, CENTER.
 

Existem ainda mais dois construtores da classe JLabel que permitem iniciar um rótulo com uma imagem ou apenas texto, sem alinhamento:

 
texto2 = new JLabel("Endereço:",JLabel.RIGHT);  // rótulo alinhado
texto3 = new JLabel("Diagrama:",imagem, JLabel.CENTER); // com imagem

 

Na terceira criação, texto3, imagem é um objeto da classe ImageIcon:

 
ImageIcon imagem = new ImageIcon("C:/temp/foto.gif");

 

Uma imagem pode ser apresentada com o rótulo para facilitar a compreensão do usuário da aplicação, ou mesmo, sem o rótulo, quando a imagem for bem expressiva em seu significado.

Exemplo:

 
/**
*Síntese
*   Objetivo: Mostrar rótulos (etiquetas) em uma janela gráfica da aplicação
*   Entrada: sem entrada
*   Saída: texto e imagem como rótulo da janela gráfica
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Rotulos extends JFrame {

       JLabel rotulo1, rotulo2, rotulo3;

       Container contem = getContentPane();

       Rotulos() {          // método construtor     
            setTitle("Aplicação Gráfica");
            setLocation(150,150);
            setSize(200,200);
            
            // objeto para uso da imagem que deve estar no caminho indicado
            ImageIcon figura = new ImageIcon("C:/temp/diagrama.gif");
            contem.setBackground(Color.gray);
            rotulo1 = new JLabel("Etiqueta 1:");
            rotulo2 = new JLabel("Rótulo 2:",JLabel.RIGHT);
            rotulo2.setForeground(Color.red);
            rotulo3 = new JLabel("Etiqueta 3:", figura, JLabel.CENTER);
            
            // indica o gerenciador de layout que será aplicado
            contem.setLayout(new GridLayout(4,1));
            contem.add(rotulo1);
            contem.add(rotulo2);
            contem.add(rotulo3);

       }

       public static void main(String [] args) {            
            JFrame janela = new Rotulos();
            janela.setVisible(true);
            
            // Outro método que encerra a execução de uma aplicação gráfica
            janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       }
}

 
 

No exemplo anterior foram criadas 3 instâncias JLabel e cada uma com seu alinhamento. Repare que na criação do rotulo1 não foi especificado o alinhamento, mas o padrão é à esquerda. Neste mesmo exemplo foram usados os métodos:

 
  • setLayout: define o layout de apresentação do respectivo container;
  • setDefaultCloseOperation: define uma ação padrão para o fechamento da aplicação, sendo:
    • DO_NOTHING_ON_CLOSE: não realiza nada;
    • HIDE_ON_CLOSE: apenas esconde a janela;
    • DISPOSE_ON_CLOSE: esconde e libera a janela;
    • EXIT_ON_CLOSE: encerra a aplicação.
 
JTextField
 

Esse é um componente gráfico muito usado para na interação com o usuário, coletando dados descritivos como nome ou denominações de objetos ou coisas que fazem parte do problema computacional a ser tratado por um programa.

 

Um JTextField, ou caixa de texto, é um meio de entrada de dados que pode receber um conjunto de caracteres (string) em linha de texto (vetor). Isso quer dizer que uma caixa de texto não consegue identificar ou representar uma quebra de linha, mas qualquer outro caractere pode ser inserido neste componente pelo usuário da aplicação gráfica elaborada.

 

Como atributos opcionais, um JTextField pode ser definido como somente de leitura, ter um valor inicial, restringir o número total de caracteres permitidos, sem contar que apesar de somente receber caracteres, seu conteúdo pode, a medida do possível ser convertido para outros tipos de dados (int, double, float etc.), conforme a necessidade do processamento da aplicação.

 

Vários métodos estão disponíveis nesta classe, podendo ser acessados através de sua API, sendo alguns deles indicados a seguir:

 
  • JTextField(): método construtor que cria uma caixa de texto vazia;
  • JTextField(String): cria caixa de texto com string orientadora dentro;
  • JTextField(String, int): cria caixa de texto com string orientadora e tamanho definido (quantidade de colunas);
  • JTextField(int): cria caixa de texto com tamanho específico definido;
  • getText(): obtém o texto do objeto;
  • getSelectedText(): obtém o texto selecionado do objeto;
  • isEditable(): verifica se o componente é editável (seu conteúdo pode ser alterado ou não);
  • setEditable(boolean): define se caixa é editável ou não;
  • setText(String): especifica o texto a ser contido no componente.
 

Geralmente, o valor numérico inserido em caixas de texto precisam de uma formatação. Para isso são utilizadas algumas classes específicas que cuidam dessa formatação (máscara) de maneira adequada, tais como NumberFormat e DecimalFormat. Observe o exemplo de código a seguir que efetua esta formatação.

 
import java.text.NumberFormat;

public class Pagamento {

    double salario;     // atributo numérico da classe    
    NumberFormat valor1;     // define um objeto formatado
    valor1 = NumberFormat.getNumberInstance();
    valor1.setMinimumFractionDigits(3);  // quantidade de casas decimais
    
    // Atribuição de um valor formatado dentro da caixa de texto
    caixaTexto.setText("" + valor1.format(salario));
}

 
JPasswordField
 

Um JPaswordField, ou caixa de senha, possui as mesmas características de um JTextField, diferenciando que ela oculta seu verdadeiro valor na apresentação no próprio campo. Isso é realizado para proteger o dado que será informado pelo usuário da aplicação, onde pessoas que possam estar ao seu lado consigam ver o valor informado.

 

Para ocultar o valor digitado um mesmo caracter é apresentado no campo, independente de qual esteja sendo o valor digitado pelo usuário. Como padrão deste componente, o caractere que oculta o conteúdo da caixa de senha é o * (asterisco), podendo este ser alterado pelo método setEchoChar disponível na API deste componente gráfico.

 

Além da maioria dos métodos disponíveis no JTextField, existem alguns outros, como os relacionados a seguir:

 
  • JPasswordField: construtor que cria uma caixa de senha vazia;
  • setEchoChar(char): define um caracter que ocultará os valores realmente digitados.
 
JTextArea
 

Este novo componente também se assemelha ao JTextField, com a diferença que uma área de texto reconhece a quebra de linha, ou seja, é possível escrever várias linhas em seu interior.

 

Alguns de seus métodos interessantes são relacionados a seguir, porém é importante lembrar que este componente também possui vários outros a serem estudados por você em sua API.

 
  • JTextArea(String, int, int): cria uma área de texto com string inicial dentro, número de linhas e quantidade de caracteres máxima por linha;
  • getSelectedText(): obtém o texto selecionado na área de texto;
  • insert(String, int): insere a string na posição inteira indicada;
  • replaceRange(String, int, int): métodos JTextField que funcionam em JTextArea;
  • append(String): insere um texto no final da área de texto;
  • getColumns(): obtém comprimento da área de texto;
  • getRows(): obtém largura da área de texto;
  • setColumns(int): define colunas da área de texto;
  • setRows(int): define linhas na área de texto;
  • setLineWrap(boolean): define quebra de linha automática.
 

Verifique no exemplo de código a seguir a elaboração de uma aplicação gráfica com alguns dos componentes estudados anteriormente.

 
/**
*Síntese
*   Objetivo: analisa a veracidade da senha
*   Entrada: senha
*   Saída: situação do acesso e senha
*/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

   public class AveriguaSenha extends JFrame implements ActionListener {

       JLabel etiq1, etiq2, etiq3;

       JTextArea area;

       JPasswordField senha;

       JTextField texto;

       // Obtém aspectos do painel padrão

       Container conteiner = getContentPane();

       AveriguaSenha (){    // método construtor
        
            setBounds(100,100,250,250);
        
            setTitle("Analisa Senha");
        
            conteiner.setBackground(new Color(150,150,150));
        
            conteiner.setLayout(new GridLayout(3,2));
        
            // Cria primeira etiqueta 
        
            etiq1 = new JLabel("Digite a senha: ");
        
            etiq1.setForeground(Color.black);
        
            etiq1.setFont(new Font("SansSerif",Font.BOLD,14));
        
            // Cria segunda etiqueta 
        
            etiq2 = new JLabel("Situação: ");
        
            etiq2.setForeground(Color.black);
        
            etiq2.setFont(new Font("",Font.BOLD,14));
        
            // Cria terceira etiqueta 
        
            etiq3 = new JLabel(" => Senha");
        
            etiq3.setForeground(Color.CYAN);
        
            etiq3.setFont(new Font("",Font.ITALIC,14));
        
            // Cria campos de texto 
        
            area = new JTextArea();
        
            texto = new JTextField();
        
            texto.setEnabled(false);
        
            texto.setFont(new Font("Arial",Font.ITALIC,18));
        
            senha = new JPasswordField();
        
            senha.setEchoChar('?');
        
            senha.addActionListener(this);
        
            // Inclui no painel padrão do conteiner 
        
            conteiner.add(etiq1);
        
            conteiner.add(senha);
        
            conteiner.add(etiq2);
        
            conteiner.add(area);
        
            conteiner.add(texto);
        
            conteiner.add(etiq3);

       }

  	   public static void main(String[] args) {

          JFrame janela = new AveriguaSenha();
    
          janela.setVisible(true);
    
          janela.addWindowListener(new WindowAdapter() { 
    
              public void windowClosing(WindowEvent evJanela) {
    
                  System.exit(0);    // método que encerra o programa
    
              }
    
          });    // termina a classe interna anônima

	  }

  	  public void actionPerformed(ActionEvent evento){
    
          if(senha.getText().equals("Java")) {   // senha
    
             area.setForeground(Color.blue);
    
             area.setText("Senha válida\n");
    
             texto.setText(senha.getText());
    
          }
    
          else {
    
             area.setForeground(Color.red);
    
             area.append("Senha inválida\n");
    
             senha.setText("");    // limpa entrada da senha
    
          }

  	}

}  // encerra a classe 

 
 
Gerenciador de Layouts
 

Em alguns dos exemplos anteriores foi usado o método setLayout, que define um layout para um container. O layout funciona como uma forma de organizar os componentes que serão inseridos no container ao qual são atribuídos. Um layout pode definir o número de componentes por linha e coluna ou até definir uma organização por pixels (pontos). O uso de layouts adequado permite que um cointaner receba mais de um componente em uma organização visual mais coerente com a apresentação gráfica desejada por seu programador.

 

Diversas são as classes de layout, onde algumas são mostradas a seguir:

 
FlowLayout
 

Os componentes são inseridos sequencialmente, da esquerda para a direita, pelo método add. Quando não há mais espaço na linha, o salto para a próxima linha é automático. Seu método de criação (sobrecarga) possui variações para definir alinhamento, espaçamento horizontal e espaçamento vertical entre os componentes:

 
	
	
    <Container>.setLayout(new FlowLayout(1,20,40));

 
  • alinhamento Centralizado;
  • espaçamento horizontal de 20 unidades;
  • espaçamento vertical de 40 unidades.
 
GridLayout
 

Divide o layout em células (linhas e colunas), como em uma planilha eletrônica. Diferentemente do FlowLayout a inserção dos componentes pode ser específica para uma célula. Em seu método construtor são passados o número de colunas, o número de linhas e opcionalmente o espaçamento horizontal e vertical das células.

 
	
	
    <Container>.setLayout(new GridLayout(3,2,20,40));

 
  • linhas são três;
  • colunas são duas;
  • espaçamento horizontal de 20 unidades;
  • espaçamento vertical de 40 unidades.
 
BorderLayout
 

Define o layout em cindo regiões, sistematicamente, divididas: North, South, West, East e Center. Cada uma recebe um componente, por meio do método add que passa o componente a ser inserido e a região em que será colocado no layout. Em seu método construtor são indicadas as distâncias horizontal e vertical dos componentes.

 
	
	
    <Container>.setLayout(new BorderLayout(20,40));

 
  • espaçamento horizontal de 20 unidades;
  • espaçamento vertical de 40 unidades.
 
CardLayout
 

Neste layout é possível agrupar vários contêineres na forma de cartões, mostrando um de cada vez conforme seja selecionado pelo usuário na aplicação. Cada contêiner possuirá seu layout definido especificamente, permitindo ainda que diversos layouts sejam usados em um mesmo espaço da janela gráfica, similar as abas superiores que indicam pastas diferentes.

 

Geralmente, este layout apresenta vários tipos de painéis em uma mesma janela e navega entre eles através dos métodos da CardLayout, sendo a ordem de seus painéis dependente da ordem em que forem inseridos na aplicação. A CardLayout usa o método add para adicionar painéis em seus cartões.

 
	
	
    <Container>.setLayout(new CardLayout(20,40));
	<Panel>.add(painel, "nome de identificação");

 

Alguns métodos interessantes desta classe de layout são relacionados a seguir:

 
  • CardLayout(): cria layout sem espaçamento entre os painéis;
  • first(container): mostra o primeiro painel inserido ao CardLayout;
  • last(container): mostra o último painel inserido ao CardLayout;
  • previous(container): mostra componente anterior inserido ao CardLayout;
  • next(container): exibe o próximo componente;
  • show(container,String): exibe o componente especificado pela string fornecida.
 

A escolha do layout a ser usado na aplicação tem ligação direta com a função da aplicação, sendo que muitas vezes a construção de uma aplicação gráfica utiliza vários layouts e painéis numa mesma janela para causar a interação mais adequada ao seu usuário.

 
JButton
 

Outro componente importante para a interação do usuário com a aplicação gráfica é o botão. Por meio dele são acionadas ações ou eventos durante a interação do usuário com a aplicação.

 
JButton botao1 = new JButton("Cancelar");   // cria um botão
JButton botao2 = new JButton("Confirmar", imagem); // cria outro botão

 

O objeto botao1 é construído de maneira mais convencional, onde uma string define o texto que será mostrado ao usuário para orientá-lo sobre o que o acionamento deste botão realizaria na aplicação.

 

No botao2 este texto orientador também é apresentado, mas uma imagem, definida anteriormente como objeto Image, será mostrada junto a este texto.

 
Com intuito de apoiar o aprendizado sobre Orientação a Objeto, sugere-se assistir a videoaula para o aperfeiçoamento no conhecimento deste conteúdo.
 
Controladores de Eventos
 

Este tipo de aplicação computacional (gráfica) se baseia na realização de eventos disparados através do processamento adequado de um cálculo por exemplo ou diretamente pela vontade de seu usuário (pressionar um botão). São os eventos que desencadeiam as ações que geram a verdadeira interação com usuário, onde qualquer componente é capaz de desencadear algum evento.

 

Por essa razão, são necessários objetos específicos que sejam chamados quando um evento é disparado para que realizem a ação ou processamento coerente com o objetivo da aplicação. Estes objetos são acionados quando um evento é disparado e por meio deles é possível controlar ou acompanhar os eventos

 

Existe uma grande variação entre os eventos, em relação aos seus componentes, por exemplo: um botão pode ser pressionado; uma área de texto pode ser editada e uma janela pode ser fechada. Para cada evento desses existe um tipo de acompanhador ou "ouvidor" (Listener) que fica escutando a aplicação para realizar um evento quando ele for acionado.

 

Exemplo:

 
/**Síntese 
*    Objetivo: averiguar a realização de eventos (uso do Listener) 
*    Entrada: texto e definição da cor deste texto 
*    Saída: texto com cor definida pelo usuário 
*/ 

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class Eventos { 

   public static void main(String[] args) { 

       JFrame janela = getJFrame(); 

       janela.add(getJPanel()); 

       janela.setVisible(true); 

   } 

   public static JFrame getJFrame(){ 

       JFrame jframe = new JFrame("Eventos (Listener)"); 

       jframe.setBounds(150,150,450,100); 

       jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       return jframe; 

   } 

   public static JPanel getJPanel(){ 
        
       JPanel jpanel = new JPanel(); 
        
       JLabel label = new JLabel(); 
        
       JTextField field = new JTextField(); 
        
       field.setColumns(20); 
        
       field.addKeyListener(new CloneListener(label)); 
        
       jpanel.add(field); 
        
       JButton redButton = new JButton("Vermelho"); 
        
       redButton.setForeground(Color.red); 
        
       redButton.addMouseListener(new PaintListener(Color.red, label)); 
        
       jpanel.add(redButton); 
        
       JButton blueButton = new JButton("Azul"); 
        
       blueButton.setForeground(Color.blue); 
        
       blueButton.addMouseListener(new PaintListener(Color.blue, label)); 
        
       jpanel.add(blueButton); 
        
       jpanel.add(label); 
        
       return jpanel; 

   } 

   // classe interna 
    
    static class PaintListener implements MouseListener { 
    
        private Color cor; 
        
        private JLabel label; 
        
        private PaintListener(Color cor, JLabel label) { 
        
          this.cor = cor; 
        
          this.label = label; 
        
        } 
        
        public void mouseClicked(MouseEvent e) { 
        
                    label.setForeground(cor); 

        } 
        
        public void mouseEntered(MouseEvent e) { } 
        
        public void mouseExited(MouseEvent e) { } 
        
        public void mousePressed(MouseEvent e) { } 
        
        public void mouseReleased(MouseEvent e) { } 

	} 

    // classe interna 
    
    static class CloneListener implements KeyListener { 
    
        private JLabel label; 
        
        private CloneListener(JLabel label) { 
        
              this.label = label; 
        
        } 
        
        public void keyPressed(KeyEvent ev) { } 
        
        public void keyReleased(KeyEvent ev) { 
        
             label.setText(((JTextField) ev.getSource()).getText()); 
        
        } 
        
        public void keyTyped(KeyEvent ev) { } 
        
    } 

} // encerra a classe pública 

 

No exemplo anterior estão sendo usados dois acompanhadores (Listeners - KeyListener e MouseListener) que 'escutam' o teclado e o mouse respectivamente. Assim, é possível observar que as interfaces Listeners obrigam a implementação de determinados métodos que serão chamados quando um determinado evento ocorrer. Por exemplo: keyReleaset será chamado quando uma tecla do teclado for solta pelo usuário após pressioná-la.

 

Os métodos das Listeners sempre recebem um objeto do evento por parâmetro. Por esse objeto é possível identificar dados do evento, por exemplo: fonte (getSource), número de cliques do mouse, tecla do teclado pressionada, etc.

 
Com intuito de apoiar o aprendizado sobre Orientação a Objeto, sugere-se assistir a videoaula para o aperfeiçoamento no conhecimento deste conteúdo.
 

Atividade de Fixação

 

No intuito de fixar a aprendizagem iniciada por meio deste módulo e verificar como seu entendimento sobre este conteúdo está, estão sendo sugeridos alguns exercícios de fixação para serem resolvidos. Clique no link de exercícios ao lado, pois será por meio dele iniciada a lista de exercícios sobre os conteúdos estudados até este momento nesta disciplina.