Slide 1 - IC/UFF

Propaganda
Introdução à Interface Gráfica
Carlos Bazilio
Isabel Rosseti
Depto de Ciência e Tecnologia
Pólo Universitário de Rio das Ostras
Universidade Federal Fluminense
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/f
eatures/components.html)
Controles Básicos
Controles Interativos com
Informação mais Formatada
Controles Interativos com
Informação mais Formatada
Controles com Informação
não-Editável
Contêineres de mais AltoNível
Contêineres de Propósito
Geral
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
– qual é o layout de diagramação
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 um outro sofre alguma alteração?
Exemplo
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
JFrame
janela
contém
Container
content pane
contém
JPanel
painel
contém
JButton
botaoLimpa
contém
JTextField
campoTexto
Hierarquia de
composição
• Componente
– qualquer elemento de interface
• Container
– é um Componente
– agrega Componentes
Componente
é um
Container
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 alguns destes recursos
javax.swing.JLabel
• Modela um texto e/ou imagem não editável,
isto é, sem interação com o usuário
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
• Modela um push-button
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
botao2.setPressedIcon(new ImageIcon("javalogo2.gif"));
Alguns containers
• Janela
• Diálogo
• Applet
• Painel
• Scroll Pane
}
}
Top Level Containers
Containers Intermediários
javax.swing.JFrame
• representa uma janela do sistema nativo
• possui título e borda
• pode possuir menu
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();
j.setVisible(true); // show(); DEPRECATED!
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/uiswin
g/layout/visual.html
java.awt.FlowLayout
• coloca os componentes lado a lado, uma
linha após a outra
• alinhamento: centralizado (default), à
esquerda ou à direita
• default para o JPanel
Exemplo de FlowLayout
Container contentPane = janela.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(new
contentPane.add(new
contentPane.add(new
contentPane.add(new
contentPane.add(new
JButton("Button 1"));
JButton("2"));
JButton("Button 3"));
JButton("Long-Named Button 4"));
JButton("Button 5"));
java.awt.BorderLayout
• Divide o container em 5 áreas: norte, sul,
leste, oeste e centro
• Default para content pane do JFrame
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)"),
BorderLayout.EAST);
java.awt.GridLayout
• Células do mesmo tamanho especificadas
pelo número de linhas e colunas
Exemplo de GridLayout
Container contentPane = janela.getContentPane();
contentPane.setLayout(new GridLayout(3,2));
contentPane.add(new
contentPane.add(new
contentPane.add(new
contentPane.add(new
contentPane.add(new
JButton("Button 1"));
JButton("2"));
JButton("Button 3"));
JButton("Long-Named Button 4"));
JButton("Button 5"));
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 interface
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 para os e-mails cadastrados
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
encaminha a mensagem a todos os assinantes
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 quando algum evento é gerado na
interface
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 serem ‘chamadas de volta’
pelo sistema
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 resolver então?
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
• esse método, então, fará o tratamento do
evento
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 grupos
de eventos
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
public
public
public
public
abstract
abstract
abstract
abstract
abstract
void
void
void
void
void
mouseClicked(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
mouseEntered(MouseEvent e)
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()
public int getClickCount()
WindowEvent
• modela os eventos que podem ocorrer em
uma janela
• essa classe declara constantes que
identificam os diversos eventos
public
public
public
public
public
public
public
static
static
static
static
static
static
static
final
final
final
final
final
final
final
int
int
int
int
int
int
int
WINDOW_OPENED
WINDOW_CLOSING
WINDOW_CLOSED
WINDOW_ICONIFIED
WINDOW_DEICONIFIED
WINDOW_ACTIVATED
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
public
public
public
public
public
public
abstract
abstract
abstract
abstract
abstract
abstract
abstract
void
void
void
void
void
void
void
windowOpened(WindowEvent e)
windowClosing(WindowEvent e)
windowClosed(WindowEvent e)
windowIconified(WindowEvent e)
windowDeiconified(WindowEvent e)
windowActivated(WindowEvent e)
windowDeactivated(WindowEvent e)
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
correspondente ao evento que desejamos
tratar
Implementando um
listener
• problema: não podemos implementar uma
interface e deixar de codificar algum
método
• solução: precisaremos implementar todos
os sete métodos definidos
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
import java.awt.event.*;
import javax.swing.*;
Exemplo
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 classes
JFrame, 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 janela.
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"))).addActionListener
(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(" ");
}});
Exercício: solução
// monta tudo
janela.getContentPane().add(visor, BorderLayout.NORTH);
janela.getContentPane().add(numeros, BorderLayout.CENTER);
janela.getContentPane().add(botoes, BorderLayout.SOUTH);
// mostra
janela.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
janela.pack();
janela.show();
}
}
Download