INTERFACE GRÁFICA EM
JAVA
MOTIVAÇÃO
• Como fazer programas com interface gráfica em Java?
• Algumas possibilidades:
• AWT – Abstract Window Toolkit (java.awt.*): API básica para o desenvolvimento de GUIs e applets em Java
• Swing (javax.swing.*): Extensão da API básica com inclusão de componentes visuais de mais alto nível (por ex., tree
view, list box e tabbed panes)
• SWT - Standard Widget Toolkit (org.eclipse.swt.*): Biblioteca desenvolvida pela IBM como parte da plataforma Eclipse; entretanto, seu uso não está amarrado ao uso da IDE
• Java 2D (java.awt e java.awt.image): Adição de classes ao pacote básico para desenho avançado de imagens em 2D
SWING
•
Algumas características importantes:
• Look and Feel plugável: configuração da aparência
de uma aplicação
• Transferência de Dados: copy-paste, drag and drop • Internacionalização e localização: permite a
configuração separada de aspectos dependentes de uma região: língua, moeda, ..
• Acessibilidade: permite projetar GUIs capazes de
serem utilizadas por portadores de deficiências
• Integração com o desktop: possibilita a integração
da aplicação com o desktop hospedeiro,
permitindo a execução de aplicações default com preenchimento prévio de dados, etc.
SWING
• À seguir, apresentamos figuras com os
componentes mais comuns desta biblioteca
• Estas figuras foram tiradas do tutorial da Sun (
http://java.sun.com/docs/books/tutorial/ui/featur es/components.html
CONTROLES INTERATIVOS COM
INFORMAÇÃO MAIS FORMATADA
CONTROLES INTERATIVOS COM
INFORMAÇÃO MAIS FORMATADA
CONTROLES COM INFORMAÇÃO
NÃO-EDITÁVEL
CONTÊINERES COM PROPÓSITO
ESPECIAL
ROTEIRO DE CRIAÇÃO DE INTERFACES
GRÁFICAS
1) instanciar os componentes de interface
• janelas, botões, campos de textos, etc
2) adicionar os componentes em containers
• como os componentes podem ser agrupados
ROTEIRO DE CRIAÇÃO DE INTERFACES
GRÁFICAS
3) estabelecer o tratamento de eventos de interface
• o que deve ocorrer quando o usuário clicar um botão?
• como alterar o conteúdo de um componente quando
public class JanelaSimples {
public JanelaSimples() {
final JButton botaoLimpa = new JButton("Limpa"); //botão
final JTextField campoTexto = new JTextField(10); //texto
campoTexto.setText("Java");
final JFrame janela = new JFrame ("Janela Simples"); //janela
janela.setSize(300,100);
JPanel painel = new JPanel(); // adiciona componentes
painel.add (botaoLimpa); painel.add (campoTexto);
janela.getContentPane().add(painel);
//Quando o usuário clicar no botao, limpa o campo de texto
botaoLimpa.addActionListener (new ActionListener() {
public void actionPerformed (ActionEvent e) { campoTexto.setText("");
}
});
janela.setVisible(true); }
public static void main(String[] args) {
new JanelaSimples(); }
}
EXEMPLO
Container content pane JPanel painel contém JButton botaoLimpa JTextField campoTexto contém contém JFrame janela contémHIERARQUIA DE COMPOSIÇÃO
• Componente
• qualquer elemento de interface • Container • é um Componente • agrega Componentes Componente Container é um contém
ELEMENTOS DE INTERFACE SWING
• janela:
• é um top-level container
• é onde os outros componentes são desenhados • painel:
• é um container intermediário
• serve para facilitar o agrupamento de outros componentes
ELEMENTOS DE INTERFACE SWING
• componentes atômicos
• elementos de interface que não agrupam outros componentes
• botões
• campos de texto
• …
• API do Swing
• À seguir serão apresentados exemplos de uso de
JAVAX.SWING.JLABEL
• Modela um texto e/ou imagem não editável, isto é,
EXEMPLO DE JLABEL
/* Cria um label com texto */JLabel label1 = new JLabel("Label1: Apenas Texto");
/* Cria um label com texto e imagem */
JLabel label2 = new JLabel("Label2: Imagem e texto", new ImageIcon("javalogo.gif"), JLabel.CENTER);
label2.setVerticalTextPosition(JLabel.BOTTOM); label2.setHorizontalTextPosition(JLabel.CENTER);
JAVAX.SWING.JBUTTON
EXEMPLO DE JBUTTON
/* Cria um botao com texto */JButton botao1 = new JButton ("Botão Desabilitado"); botao1.setEnabled(false);
botao1.setToolTipText("Exemplo de um botão de texto"); botao1.setMnemonic(KeyEvent.VK_D); // Alt-D
/* Cria um botao com texto e imagem */
JButton botao2 = new JButton("Botão Habilitado", new
ImageIcon("javalogo.gif"));
botao2.setToolTipText("Botão de texto e imagem"); botao2.setMnemonic(KeyEvent.VK_H); // Alt-H
ALGUNS CONTAINERS
• Janela • Diálogo • Applet • Painel
• Scroll Pane
}
Containers Intermediários
JAVAX.SWING.JFRAME
•
representa uma janela do sistema nativo
•
possui título e borda
EXEMPLO DE JFRAME
JFrame j = new JFrame("Exemplo de Janela");j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel msg = new JLabel("Olá Mundo!"); j.getContentPane().add(msg);
j.setLocationRelativeTo(null); // centraliza j.setIconImage(new
ImageIcon("javalogo2.gif").getImage());
JMenuBar menuBar = new JMenuBar(); menuBar.add(new JMenu("Menu"));
j.setJMenuBar(menuBar); j.pack();
JAVAX.SWING.JPANEL
• modela um container sem decoração • representa um grupo de elementos
• normalmente usado para estruturar a interface • associado a um diagramador
DIAGRAMADORES
• arrumam um grupo de elementos • estão associados aos containers • diferentes estilos de arrumação
• como fluxo de texto • orientada pelas bordas • em forma de grade
• e outros ...
• http://java.sun.com/docs/books/tutorial/uiswing/layout/vis
JAVA.AWT.FLOWLAYOUT
• coloca os componentes lado a lado, uma linha
após a outra
• alinhamento: centralizado (default), à esquerda
ou à direita
EXEMPLO DE FLOWLAYOUT
Container contentPane = janela.getContentPane(); contentPane.setLayout(new FlowLayout());
contentPane.add(new JButton("Button 1")); contentPane.add(new JButton("2"));
contentPane.add(new JButton("Button 3"));
contentPane.add(new JButton("Long-Named Button 4")); contentPane.add(new JButton("Button 5"));
JAVA.AWT.BORDERLAYOUT
• Divide o container em 5 áreas: norte, sul, leste,
oeste e centro
EXEMPLO DE BORDERLAYOUT
Container contentPane = janela.getContentPane(); contentPane.add(new JButton("Button 1 (NORTH)"),BorderLayout.NORTH);
contentPane.add(new JButton("2 (CENTER)"),
BorderLayout.CENTER);
contentPane.add(new JButton("Button 3 (WEST)"),
BorderLayout.WEST);
contentPane.add(new JButton("Long-Named Button 4 (SOUTH)"), BorderLayout.SOUTH);
contentPane.add(new JButton("Button 5 (EAST)"),
JAVA.AWT.GRIDLAYOUT
• Células do mesmo tamanho especificadas pelo
EXEMPLO DE GRIDLAYOUT
Container contentPane = janela.getContentPane(); contentPane.setLayout(new GridLayout(3,2));
contentPane.add(new JButton("Button 1"));
contentPane.add(new JButton("2"));
contentPane.add(new JButton("Button 3"));
contentPane.add(new JButton("Long-Named Button 4"));
EXERCÍCIO: ENUNCIADO
Usando apenas as classes JFrame, JPanel, JButton,
JLabel, BorderLayout,
GridLayout e FlowLayout, escreva um programa que, ao ser executado, exiba a tela ao lado.
Não se preocupe com a funcionalidade do
programa. Ou seja, o programa não deve
responder aos cliques do usuário.
EVENTOS
• o que deve ocorrer quando o usuário clicar um
botão?
• como alterar o conteúdo de um componente
quando um outro sofre alguma alteração?
• solução: estabelecer o tratamento de eventos de
ANALOGIA
• Antes de irmos aos detalhes, imaginem o
funcionamento de uma lista de discussão:
• O indivíduo deseja receber postagens de uma lista
• Este indivíduo entra no site da lista e cadastra seu e-mail • À partir daí, toda a postagem na lista será encaminhada
ANALOGIA
•
Na situação citada, a lista de discussão
funciona como um recurso gráfico, como um
botão
•
O endereço de e-mail indica quem são os
assinantes, quem está “escutando” (listener)
uma dada lista
•
O evento de envio de uma mensagem de um
usuário representa acionar o recurso gráfico,
como pressionar o botão
•
O sistema responsável por manter a lista
ORIENTAÇÃO POR EVENTOS
• modelo de programação que tornou-se bastante
difundido com o uso de interfaces gráficas
• o programa deixa de ter o controle do fluxo de
execução, passando a um sistema encarregado de gerenciar a interface
• o programa passa a ser chamado pelo sistema
MECANISMOS DE CALLBACK
• para que o programa possa ser chamado pelo
sistema, ele deve registrar uma função para cada evento de interface que ele desejar tratar
• essas funções são chamadas de callbacks por
CALLBACKS EM OO
• modelo é ortogonal ao modelo de orientação por
objetos
• é possível projetar um sistema OO que use o
modelo de orientação por eventos para tratar eventos de interface, comunicações, etc
• problema: não possui o conceito de função. Como
CALLBACKS EM OO
• solução: usar um objeto que faça o papel de
callback
• ou seja, onde registraríamos uma função,
passamos a registrar um objeto
• quando o sistema precisar executar a callback,
ele deverá executar um determinado método do objeto
LISTENERS E EVENTOS
•
os listeners (Java) fazem o papel das
callbacks
•
listeners são definidos por interfaces e
podem estar aptos a tratar mais de um tipo
de evento
•
quando um listener tem um de seus métodos
chamados, ele recebe um parâmetro (objeto)
que descreve o evento ocorrido
•
existem classes para modelar diferentes
EXERCÍCIO
• Para o navegador apresentado anteriormente,
modifique-o de forma que, ao passarmos o mouse sobre o label url, apareça uma caixa de diálogo solicitando um novo endereço www.
LISTENERS
• definem interfaces que representam um grupo de
callbacks
• são registrados junto aos componentes • java.awt.event.MouseListener
public abstract void mouseClicked(MouseEvent e) public abstract void mousePressed(MouseEvent e) public abstract void mouseReleased(MouseEvent e) public abstract void mouseEntered(MouseEvent e) public abstract void mouseExited(MouseEvent e)
REGISTRO DE LISTENERS
• mecanismo de callbacks • implementação da interface • uso de classes aninhadas
button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Botão pressionado");
} });
EVENTOS
• trazem informações sobre o evento ocorrido • são passados aos listeners (callbacks)
• java.awt.event.MouseEvent
public int getX() public int getY()
WINDOWEVENT
• modela os eventos que podem ocorrer em uma
janela
• essa classe declara constantes que identificam os
diversos eventos
public static final int WINDOW_OPENED public static final int WINDOW_CLOSING public static final int WINDOW_CLOSED
public static final int WINDOW_ICONIFIED public static final int WINDOW_DEICONIFIED public static final int WINDOW_ACTIVATED public static final int WINDOW_DEACTIVATED public Window getWindow()
WINDOWLISTENER
• modela a callback de um evento do tipo
WindowEvent
• essa interface declara um método para cada
evento do grupo
public abstract void windowOpened(WindowEvent e) public abstract void windowClosing(WindowEvent e) public abstract void windowClosed(WindowEvent e)
public abstract void windowIconified(WindowEvent e) public abstract void windowDeiconified(WindowEvent
e)
public abstract void windowActivated(WindowEvent e) public abstract void windowDeactivated(WindowEvent
IMPLEMENTANDO UM LISTENER
• para criarmos um listener para um evento de
janela, por exemplo, devemos criar uma classe que implemente a interface WindowListener
• nessa classe, codificaremos o método
IMPLEMENTANDO UM LISTENER
• problema: não podemos implementar uma
interface e deixar de codificar algum método
• solução: precisaremos implementar todos os sete
ADAPTADORES
• neste caso, seis implementações são vazias pois
só desejamos responder a um único evento
• esta é uma situação comum
• o pacote java.awt.event define adaptadores
para todas as interfaces de listeners que têm mais de um método
ADAPTADORES
• são classes que implementam o listener e
fornecem implementações vazias para todos os métodos
EXEMPLO
import java.awt.event.*; import javax.swing.*; public class Janela {
JButton botaoLimpa; JTextField campoTexto; JFrame janela; public Janela() {
botaoLimpa = new JButton("Limpa"); campoTexto = new JTextField(10);
janela = new JFrame ("Exemplo de Listener"); janela.setSize(300,100);
JPanel painel = new JPanel();
janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); painel.add (botaoLimpa);
painel.add (campoTexto);
janela.getContentPane().add(painel);
botaoLimpa.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent e) {
campoTexto.setText(""); } }); janela.setVisible(true); }
public static void main(String[] args) { new Janela();
} }
EXERCÍCIO: ENUNCIADO
Usando apenas as classesJFrame, JPanel, JButton, JLabel, BorderLayout,
GridLayout e FlowLayout, escreva um programa que, ao ser executado, exiba a tela ao lado.
Faça com que o número que aparece no visor seja o
número digitado no teclado numérico da aplicação.
O botão send deve imprimir no console o conteúdo do visor e o botão end deve apagar o visor.
Permita que a aplicação seja termina fechando-se a
EXERCÍCIO CALCULADORA: SOLUÇÃO 1
import javax.swing.*; public class Celular {
public static void main(String[] args) {
JFrame janela = new JFrame("Celular"); // janela JLabel visor = new JLabel("5122299"); // visor visor.setAlignment(JLabel.RIGHT);
JPanel num = new JPanel(new GridLayout(4,3)); // teclado String[] n =
{"1","2","3","4","5","6","7","8","9","*","0","#"};
for (int i=0; i<n.length; i++) num.add(new Button(n[i])); JPanel botoes = new JPanel(); // send & end
((FlowLayout)botoes.getLayout()).setVgap(0); botoes.add(new Button("send"));
botoes.add(new Button("end"));
janela.add(visor, BorderLayout.NORTH); // monta tudo janela.add(num, BorderLayout.CENTER); janela.add(botoes, BorderLayout.SOUTH); janela.pack(); // mostra janela.show(); } }
EXERCÍCIO: SOLUÇÃO 2
import javax.swing.*; import java.awt.*;
import java.awt.event.*;
public class JCelular {
public static void main(String[] args) {
JFrame janela = new JFrame("Celular"); // janela
final JLabel visor = new JLabel("5122299"); // visor visor.setHorizontalAlignment(JLabel.RIGHT);
JPanel numeros = new JPanel(new GridLayout(4,3));//Tecla String[] nomes =
{"1","2","3","4","5","6","7","8","9","*","0","#"}; // Cria o listener para as teclas do celular
ActionListener trataTecla = new ActionListener() { public void actionPerformed(ActionEvent e) {
JButton botaoClicado = (JButton)e.getSource();
visor.setText(visor.getText()+botaoClicado.getText()); }};
EXERCÍCIO: SOLUÇÃO
for(int i=0; i<nomes.length; i++) ((JButton)numeros.add(new
JButton(nomes[i]))).addActionListener(trataTecla); JPanel botoes = new JPanel(); // Botoes send e end
((JButton)botoes.add(newJButton("send"))).addActionListen er (new ActionListener() {
public void actionPerformed(ActionEvent e) { System.out.println(visor.getText()); }});
((JButton)botoes.add(new
JButton("end"))).addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
visor.setText(" "); }});