Java - Interface Gráfica do Usuário

De Aulas

Afluentes: Programação em Java

GUI - Graphical User Interface

A interface gráfica com o usuário tenta fornecer ao usuário uma forma mais intuitiva de utilização de um programa, reduzindo o tempo de aprendizado na utilização do mesmo.

As GUIs são construídas a partir de componentes, ou objetos, com o qual o usuário interage, tais como:

  • Mouse;
  • Teclado;
  • Campos de entrada;
  • Menus e outros.

Elementos de uma GUI

  • componentes: Elementos desenhados na tela.
    • Exemplos: botão, textbox, label, etc.
  • containers: elementos que servem como agrupadores lógicos para componentes.
    • Exemplo: Panel.
  • Containers de alto nível: cidadãos de primeira classe, que efetivamente ocupam um espaço no desktop.
    • Exemplos: Frame, DialogBox.

GUI em Java: AWT e Swing

A ideia inicial da Sun foi o AWT: Abstract Windowing Toolkit.

  • Criar um conjunto de classes e métodos que possam ser usados para escrever uma GUI multi-plataforma;
  • Não era poderosa o suficiente, sendo extremamente limitada.

O Swing foi uma nova interface, a partir do JDK 1.2:

  • Nova biblioteca, construída do zero que permite gráficos e GUIs muito mais poderosos e flexíveis.

Porque swing e não awt?

  • awt é a versão mais velha e mais primitiva.
  • Swing é mais poderosa
  • Swing pode ser enviado com as aplicações, sendo não dependente de máquina


Tplnote Bulbgraph.png

Por compatibilidade retroativa, ambos existem no Java e, às vezes, nós usamos os dois.

Look and Feel

  • Cada figuta abaixo mostra o mesmo programa com um look and feel diferente.
  • Conforme mudamos de SO ou de ambiente, o look and feel se adapta para aquele que é padrão na máquina onde rodamos.
  • Isto é uma obrigação da JVM, não do programador.
Swing looknfeel.png

Componentes Swing

  • O Swing fornece vários componentes padrão de GUI que podem ser combinados de forma a criar sua interface.
  • Alguns exemplos:
    • Botões, Listas, Menus, Áreas de texto, etc.
  • Swing também fornece containers tais como janelas e barras de ferramentas.
  • Pode ser de vários níveis:
    • Nível mais alto: frames, diálogos
    • Nível Intermediário: panel, scroll pane, tabbed pane, etc.

Hierarquia de Componentes Swing

java.lang.Object
	+--java.awt.Component
		+--java.awt.Container
			+--javax.swing.JComponent
			|	+--javax.swing.JButton
			|	+--javax.swing.JLabel
			|	+--javax.swing.JMenuBar
			|	+--javax.swing.JOptionPane
			|	+--javax.swing.JPanel
			|	+--javax.swing.JTextField
			|
			+--java.awt.Window
				+--java.awt.Frame
					+--javax.swing.JFrame

Métodos comuns em todos os componentes Swing

  • get/setPreferredSize
  • get/setSize
  • get/setLocation
  • getLength/Width
  • repaint
  • setBackground(Color)
  • setFont(Font)
  • isEnabled / setEnabled(boolean)
  • isVisible / setVisible(boolean)

Atividade 1

Faça uma pesquisa sobre a biblioteca AWT e tente montar uma janela com alguns componentes usando a biblioteca.

Containers

Janelas

A interface com o usuário é orientada a janelas

  • Os elementos de interface com o usuário são classificados como janelas, containers e componentes;
  • As janelas são a base da interface com o usuário, contendo os demais elementos;
  • Os containers são grupos de componentes, apresentados em uma região de tela definida;
  • Os componentes são os principais elementos de interface, sendo utilizados diretamente pelo usuário.
  • Descendentes da classe java.awt.Container.
  • Componentes que podem conter outros componentes.
  • Usamos um layout manager para posicionar e definir o tamanho dos componentes contidos neles.
  • Componentes são adicionados a um container usando as várias formas do método add


Swing componentes e containers.png
  • A janela (JFrame) é o container de mais alto nível
    • A janela existe para prover espaço para apresentação dos componentes Swing
  • O painel (JPanel) é um container intermediário
    • Os painéis existem para controlar o posicionamento dos componentes
  • Componentes atômicos, como botões (JBuZon) e linhas de edição (JTextField), realizam a interação com o usuário propriamente dita

Containers Top-Level

  • Todo programa que usa uma GUI Swing tem pelo menos um container de alto nível (top-level).
  • Um container top-level provê o suporte que os componenetes siwng necessitam para realizar o desenho da tela e o tratamento de eventos.
  • O Swing fornece três containers top-level:
    • JFrame (Janela principal)
    • JDialog (Janela secundária)
    • JApplet (Um applet mostra uma área desenhada dentro de um navegador internet)
  • Para aparecer na tela, todo componente GUI deve ser parte de uma hierarquia de contenção, cuja raiz é um container top-level.
  • Todo container top-level tem um content pane que contém todos os componentes visíveis dentro da interface daquele container top-level.
Swing toplevel container.png

Content Pane

  • Todo container top-level contém indiretamente um container intermediário denominado content pane
  • Este content pane contém todos os componentes visíveis n GUI da janela.
  • Os containers são adicionados ao content pane usando um dos vários tipos de métodos add
  • Exemplo:
    • frame = new JFrame(...);
    • label = new JLabel(...);
    • frame.getContentPane().add(label, BorderLayout.CENTER);

JFrame

  • A classe JFrame representa uma janela Swing – Seu construtor pode receber uma string com o Título da janela
  • Toda janela possui um painel invisível (ContentPane)
  • Os componentes da janela são inseridos neste painel
  • A janela pode conter uma barra de menu
JFrame frame = new JFrame(Alo, Mundo);
frame.getContentPane().add (new JButton (Teste));
  • Um frame, implementado como uma instância da classe JFrame, é uma janela que tem acessórios tais como borda, título e botões para fechar e minimizá-la.
  • Estes acessórios são totalmente dependentes de plataforma.
  • As aplicações com uma GUI tipicamente usam ao menos um frame.
  • Métodos principais:
    • public void setTitle(String title): Coloca um título na barra de título da janela.
    • public void show(): Faz o frame aparecer na tela.
    • public void setVisible(boolean v): Faz com que o frame se torne visível (v=true) ou não (v=false).
    • public void setDefaultCloseOperation(int op): Faz a janela realizar uma determinada operação quando fecha. Mais comum: JFrame.EXIT_ON_CLOSE
Swing jframe.png
  • A programação gráfica está muito ligada à ocorrência de eventos, que devem ser tratados;
  • Ao contrário de outras linguagens de programação, os containers Java não vêm 100% para lidar com os eventos básicos que ocorrem em uma janela;
  • Um exemplo é o evento de fechamento;
  • Qualquer aplicativo Delphi ou VB sabe fechar sua janela sem problema, mas Java não;
  • Mais à frente nós vamos aprender mais sobre eventos, então vamos nos contentar com o setDefaultCloseOperation por enquanto;
 1import javax.swing.*;                                           // Importa a biblioteca swing
 2
 3class HelloWorldSwing {
 4    public static void main(String [] args) {
 5        JFrame frame = new JFrame("HelloWorldSwing!");        // Cria uma janela
 6        final JLabel label = new JLabel("Hello world!");        // Cria um rotulo
 7        frame.getContentPane().add(label);                      // Adiciona o rotulo ao painel da janela
 8        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   // Operacao ao fechar a janela
 9        frame.pack();                                           // Empacota tudo
10        frame.setVisible(true);                                 // Mostra a janela
11    }
12}
Swing helloworld.png


Tplnote Bulbgraph.png

O código a seguir faz a mesma coisa, só que criando uma classe nova que herda JFrame, definida por nós.

 1import javax.swing.*;
 2
 3public class HelloWorldSwing extends JFrame {
 4    public HelloWorldSwing() {
 5        super("HelloWorldSwing");
 6        final JLabel label = new JLabel("Hello World");
 7        getContentPane().add(label);
 8        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 9        pack();
10        setVisible(true);
11    }
12
13    public static void main(String[] args) {
14        HelloWorldSwing frame = new HelloWorldSwing();
15    }
16}

JPanel

A classe JPanel representa um painel simples

  • JPanel é o container intermediário mais simples
  • O painel pode ser inserido em uma janela ou outro painel
  • O método add() insere o painel na janela
JFrame frame;
JPanel painel;

frame = new JFrame(Alo, Mundo);
painel = new JPanel();
frame.getContentPane().add(painel);

O Swing possui outros painéis intermediários:

Swing paineis intermediarios.png

Atividade 2

Usando os exemplos dessa seção, tente criar uma janela, modificando características como tamanho da janela na inicialização, texto, cor, desabilite redimensionamento, etc.

Componentes

Rótulos

  • Rótulos permitem a apresentação de textos e imagens
  • Os métodos getText() e setText() permitem consultar e alterar o texto de um rótulo
  • Os métodos getIcon() e setIcon() permitem consultar e alterar a imagem apresentada no rótulo
ImageIcon icon = new ImageIcon (boom.gif");

JLabel label1 = new JLabel ("Image and Text", icon, JLabel.CENTER);
// Alinhamento do texto
label1.setVerticalTextPosition (JLabel.BOTTOM);
label1.setHorizontalTextPosition (JLabel.CENTER);
painel.add (label1);

label2 = new JLabel ("Text-Only Label");
painel.add (label2);

label3 = new JLabel (icon);
painel.add (label3);
Swing rotulos.png

Botões

  • Um botão é uma região clicável com a qual o usuário interage de forma a realizar um comando.
  • CaracterísNcas dos botões Swing
    • Apresentam texto e imagens
    • Podem possuir um mnemônico utilizado como hotkey
    • Controlam o posicionamento do Título do botão
  • Quando criamos um botão ele não faz nada, mesmo clicando.
  • Precisamos associar o botão a um tratador de eventos (veremos isso melhor mais a diante)

• Principais métodos:

  • public JButton(String text): Cria um novo botão com o texto dado como parâmetro definido como texto de face.
  • public String getText(): Retorna o texto mostrado no botão.
  • public void setText(String text): Muda o texto de face do botão.
ImageIcon icone = new ImageIcon("images/right.gif");
JButton b1 = new JButton (Teste, icone);
b1.setVerticalTextPosition (AbstractButton.CENTER);
b1.setHorizontalTextPosition (AbstractButton.LEFT);
b1.setMnemonic(KeyEvent.VK_D);
Adicionando evento ao botão
  • Para acontecer algo quando clicamos no botão, precisamos colocar ele em um tratador de eventos;
  • No exemplo a seguir, colocamos ele no ActionListener e criamos uma classe anonima pra isso;
  • Colocamos o que queremos que ele faça dentro do método actionPerformed;
JButton botao = new JButton("Teste");
botao.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent arg0) {
        JOptionPane.showMessageDialog(null, "Testando botão", "Teste", 0);
    }
});


Tplnote Bulbgraph.png

Vamos tratar melhor sobre eventos mais tarde.

Entrada de Texto

  • Permitem a edição de textos
    • O construtor da linha de edição indica seu tamanho desejado
    • O construtor não limita o tamanho do texto editado
    • O método setText() altera o texto em edição na linha
    • O método getText() retorna o texto editado pelo usuário
// entrada de texto simples, uma linha
JTextField linha = new JTextField(20);
linha.setText(Alo, Mundo !);
linha.selectAll();

// entrada de texto com múltiplas linhas
JTextArea area = new JTextArea(5, 20);
area.setText(Testando 1, 2, 3);

// Áreas de texto são inseridas em painéis
JScrollPane scroll = new JScrollPane(area);
painel.add(scroll);
Swing entrada de texto.png
Métodos de suporte
    • O método setEditable() indica se a linha de texto é editável ou read-only, de acordo com seu parâmetro booleano
  • O método isEditable() determina se a linha de texto é editável ou read-only, retornando um booleano
  • O método setHorizontalAlignment() indica como o texto é alinhado na linha de edição
    • JTextField.LEFT
    • JTextField.CENTER
    • JTextField.RIGHT

Exemplo

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

public class HelloFrame extends JFrame {
    private static final long serialVersionUID = 1L;

    public HelloFrame() {
        super("Hello Frame");
        setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));

        final JLabel label = new JLabel("Entre com uma informação");
        getContentPane().add(label);

        final JTextField entrada = new JTextField(20);
        getContentPane().add(entrada);

        final JButton botao = new JButton("clique-me");
        botao.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                botao.setText("clicou");
                JOptionPane.showMessageDialog(null, "Dados de entrada: " +
                entrada.getText(), "informação", 0);
                entrada.setText(""); 
            }        
        });
        getContentPane().add(botao);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new HelloFrame();
    }
}

Atividade 3

Faça uma janela em Java Swing para entrar com os dados de um estudante ao se matricular na faculdade. Crie um botão cadastrar e outro cancelar. Quando clicar no botão cadastrar, monta um texto com todos os dados entrados e mostra em um rótulo. Quando clicar no botão cancelar, apaga todos os campos.

Resolução

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

public class Estudante extends JFrame {
    private static final long serialVersionUID = 1L;

    public Estudante() {
        super("Cadastro de Estudantes");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));

        ImageIcon icon = new ImageIcon("unisul.png");
        JLabel labelImage = new JLabel(icon);
        getContentPane().add(labelImage);

        getContentPane().add(new JLabel("CPF:"));
        final JTextField cpf = new JTextField(20);
        getContentPane().add(cpf);

        getContentPane().add(new JLabel("Nome:"));
        final JTextField nome = new JTextField(20);
        getContentPane().add(nome);

        getContentPane().add(new JLabel("Idade:"));
        final JTextField idade = new JTextField(20);
        getContentPane().add(idade);

        getContentPane().add(new JLabel("Curso:"));
        final JTextField curso = new JTextField(20);
        getContentPane().add(curso);

        JTextArea info = new JTextArea(5, 20);
        info.setEditable(false);
        info.setLineWrap(true);
        info.setWrapStyleWord(true);

        JPanel panel = new JPanel(new FlowLayout());

        final JButton btCadastrar = new JButton("Cadastrar");
        btCadastrar.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                info.setText(
                    nome.getText() +
                    ", com CPF numero " +
                    cpf.getText() +
                    ", com " +
                    idade.getText() +
                    " anos, se encontra devidamente matriculado no curso " +
                    curso.getText()
                );
            }            
        });
        panel.add(btCadastrar);

        final JButton btCancelar = new JButton("Cancelar");
        btCancelar.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                cpf.setText("");
                nome.setText("");
                idade.setText("");
                curso.setText("");
                info.setText("");
            }
        });
        panel.add(btCancelar);

        getContentPane().add(panel);
       
        getContentPane().add(new JScrollPane(info));
        
        pack();
        setVisible(true);
    }

    public static void main(String [] args) {
        new Estudante();
    }
}