Construção de Interfaces Gráficas - Introdução Programação Orientada a Objetos Java Prof. Geraldo Braz Junior
Objetivos Apresentar Os fundamentos da construção GUI em Java Modelo de Eventos AWT Biblioteca de Componentes Swing 2
Introdução Interface gráfica é composta de: Componentes Recipientes (Containers) Layout Eventos 4
Recipientes e Componentes Componentes, controles ou widgets são os aspectos visíveis de uma GUI, como botões, menus, caixas de textos São colocados dentro de recipientes (containers). Os recipientes podem conter: Um ou mais componentes, assim como outros recipientes Importante para construção de layouts de complexidade realista 5
AWT versus Swing 6 A Abstract Window Toolkit (AWT) é o antigo conjunto de ferramentas para interfaces gráficas do Java Oferece uma infra-estrutura mínima de interface gráfica Componentes têm aparência dependente de plataforma Limitado em recursos devido a depender de suporte de cada plataforma para os componentes oferecidos Bugs e incompatibilidades entre plataformas
AWT versus Swing O swing não é um substituto completo do AWT, mas fornece um conjunto muito mais rico e conveniente de componentes para interface com usuário O Swing é menos sujeito a erros específicos de cada plataforma 7
Evolução das AWT Java 1.0 Modelo de eventos arcaico baseado em interfaces Java 1.1 Melhora do modelo de eventos: por delegação usando design pattern Observer Java 1.2 Swing substitui totalmente componentes AWT Mantém e estende a interface de eventos e layout da versão 1.1 8
Tipos de Aplicativos Graficos Há dois tipos de aplicações gráficas em Java Applets executam dentro de um navegador Web Aplicações standalone iniciadas via sistema operacional Ambas capturam eventos do sistema e desenham-se sobre um contexto gráfico fornecido pelo sistema Applets são aplicações especiais que executam a partir de um browser Browser é quem controla seu ciclo de vida (início, fim, etc.) Geralmente ocupam parte da janela do browser, mas podem abrir janelas extras Possuem restrições de segurança 9
Principais classes de GUI java.lang.object java.awt.component java.awt.container javax.swing.jcomponent 10
Classe java.awt.component Raiz da hierarquia de componentes gráficos 11 Existe um Component por trás de tudo que pode ser pintado na tela Principais métodos (chamados pelo sistema) void paint(java.awt.graphics g) void repaint() void update(java.awt.graphics g) Dimension getsize() retorna o tamanho de um componente. O tipo de retorno é um objeto da classe Dimension, que possui dois atributos públicos height e width void setsize(int, int) Altera o tamanho de um componente
Class java.awt.component getlocation() e setlocation(int x, int y) estes métodos alteram a localização dos componentes (em pixels) relativa ao canto superior esquerdo do componente O tipo de retorno de getlocation() é Dimension setforeground() e setbackground() altera as cores dos componentes Os argumentos são uma instância de java.awt.color 12
Class java.awt.component setfont() define a fonte que será usada para renderizar o texto que será apresentado no componente Este método recebe três argumentos: fonte, estilo e o tamanho setenable(boolean) habilita ou desabilita um componente Este método é útil para criar interfaces que reflitam o estado atual da aplicação do usuário 13
java.awt.container Subclasse de java.awt.component São recipientes. Podem conter outros componentes Descendentes da classe Container: Frame, Panel, Applet e JComponent (raiz da hierarquia dos componentes Swing) Para adicionar um componente em um Container (Panel, Frame, Applet) utiliza-se o método add(component c) 14
javax.swing.jcomponent Fornece recursos de alto nível a todos os componentes swing Tamanho preferencial setpreferredsize() Suporte a acessibilidade e internacionalização Suporte a dicas quando o mouse permanece sobre um componente Definição de bordas 15
Principais Componentes JComponent JComboBox JLabel JList JMenuBar JPanel JPopupMenu JScrollBar JScrollPane JTable JprogressBar JSplitPane JViewPoint JTree JRootPane JTabbedPane JInternalFrame JSeparator JToolbar JFileChooser JColorChooser JTextComponent JOptionPane JSlider JToolTip Componentes de Texto JDesktopPane JLayeredPane JEditorPane JTextField JTextPane JPasswordField AbstractButton Botões JButton JToggleButton JCheckBox JRadioButton JMenu JMenuItem
Frames (Molduras) É uma janela independente que pode ser movimentada na tela independente de quaisquer outras janelas de GUI Java fornece duas classes para este fim: java.awt.frame, subclasse da classe java.awt.window e javax.swing.jframe, subclasse de java.awt.frame 17
Hierarquia de Herança da Classe JFrame java.lang.object java.awt.component java.awt.container javax.swing.jcomponent java.awt.window... javax.swing.jpanel java.awt.frame javax.swing.jframe 18
Frames (JFrame) O seguinte código exibe um JFrame vazio: import javax.swing.jframe; public class Moldura { } public static void main(string[] args) { JFrame f = new JFrame("Primeira moldura"); } f.setsize(300, 250); f.setvisible(true); Aparece no título da moldura É necessário, pois um frame recém construído não está visível na tela 19
Adicionando componentes ao JFrame Até o JDK 1.5 era necessário obter um Container para adicionar os componentes JFrame frame = new JFrame( Teste"); Container cont = frame.getcontentpane(); JPanel pan = new JPanel(); pan.add(new JButton("Button")); cont.add(pan); A SUN corrigiu este inconveniente possibilitando a verificação especial deste recurso em tempo de execução Era necessário para manter a independência de plataforma 20 JFrame frame = new JFrame( Teste"); JPanel pan = new JPanel(); pan.add(new JButton("Button")); frame.add(pan);
Panel e JPanel É um recipiente de uso geral. Ele não pode ser usado isoladamente, como frames e caixas de diálogo Painéis podem administrar eventos 21
Tratamento de Eventos
Tratamento de Eventos Esta seção apresenta como lidar com eventos ou ações que ocorrem dentro de ambientes GUI Interfaces gráficas são guiadas por eventos Exemplo: movimento do mouse, pressionar um botão, entrada de dados em um textfield, etc. Em java eventos são objetos que descrevem o que aconteceu Eventos em Java são uma instância de uma subclasse de java.util.eventobject 23 Fornece o método getsource() que retorna a fonte do evento
Tratamento de Eventos 24 O modelo de eventos se torna fácil de usar, pois é baseado em uma nomenclatura simples: Para cada tipo de evento XXXEvent existe uma interface XXXListener (interface ouvinte ): Os métodos desta interfaces são todos public void e recebem um único argumento do tipo XXXEvent (um objeto) ActionEvent: ActionListener ItemEvent : ItemListener TextEvent : TextListener WindowEvent: WindowListener KeyEvent : KeyListener... XXXEvento : XXXListener
Tratamento de Eventos Nomenclatura de eventos: Se um componente emite eventos de tipo XXXEvent, então ele tem um método público chamado addxxxlistener(xxxlistener) Quando um componente é ativado de uma maneira que o leve a emitir eventos XXX, todos os receptores registrados recebem uma chamada para um dos métodos da interface receptora Qualquer objeto que implementa esta interface pode ser registrado como um receptor de eventos XXX 25
Tratamento de Eventos Nomenclatura de eventos: Além do método addxxxlistener (XXXListener), um componente que emite eventos, também tem um método público chamado removexxxlistener(xxxlistener) Possibilita que os receptores que não estejam mais interessados em eventos XXX desfaçam o registro 26
Modelo de Tratamento de Eventos Pode ser dividido em três partes 1. Origem do evento (fonte) É o resultado de alguma ação do usuário em um componente GUI Exemplo: o clique de mouse em um componente irá gerar (source) um ActionEvent 27
Modelo de Tratamento de Eventos 28
Modelo de Tratamento de Eventos 2. Objeto que contem informações sobre evento (ActionEvent) Encapsula informações sobre o evento que ocorreu Exemplo: um objeto da Classe ActionEvent Todo evento tem um objeto que é sua fonte Object fonte = evento.getsource(); 29
Modelo de Tratamento de Eventos 3. Listener (Ouvinte) Recebe eventos como argumento public class NomeClasse implements ActionListener { public void actionperformed(actionevent evt) { Object fonte = evt.getsource(); System.out.println(evt + em + fonte); } } 30
Modelo de Tratamento de Eventos Programador deve realizar duas tarefas 1. Registrar um ouvinte para cada evento que se deseja tratar 2. Implementar o(s) método(s) que manipulam o evento 31
Como ligar a fonte ao Ouvinte Na ocorrência de um evento, em uma fonte, todos os ouvintes registrados serão notificados. fonte.add<listener> (referência_para_listener); O mesmo objeto que é fonte às vezes também é listener, se implementar as interfaces: Ainda assim, é necessário registrar a fonte ao listener this.addwindowlistener(this); Fonte Ouvinte 32
Descrição dos Eventos 33 Descendentes de java.awt.event.awtevent Divididos em categorias (java.awt.event) ActionEvent (fonte: componentes de ação (JButton, JTextField,...)) MouseEvent (fonte: componentes afetados pelo mouse) ItemEvent (fonte: componentes de seleção (JCheckBox, JRadioButton, JComboBox,...)) AdjustmentEvent (fonte: scrollbars) TextEvent (fonte: componentes de texto) WindowEvent (fonte: janelas) FocusEvent (fonte: componentes em geral) KeyEvent (fonte: componentes afetados pelo teclado)
Alguns componentes (subclasse de JComponent)
JLabel São strings de texto usadas para identificar outros elementos. Normalmente são inseridas à esquerda ou acima do elemento que está sendo rotulado Podem apresentar: Somente Texto Imagens Texto e imagens 35
JTextField e JPasswordField É um dispositivo de linha única de texto Em virtude de ser possível apenas uma linha, um ActionListener pode ser informado através de actionperformed() quando a tecla enter for pressionada Este componente não exibe barra de rolagem, mas é possível rolar sobre o texto longo da esquerda para a direita, se for necessário 36 A classe JPasswordField herda de JTextField e adiciona vários métodos que são específicos ao processamento de senhas
JTextField e JPasswordField 37 Confira: TextFieldTest.java
Botões São elementos de forma retangular que o usuário utiliza para iniciar ações O pacote swing define vários tipos de botões botões de comando Check boxes (caixa de seleção) Radio buttons Todos estes botões são subclasse de 38 javax.swing.abstractbutton
JButton javax.swing.jcomponent javax.swing.abstractbutton (Classe Abstrata) javax.swing.jbutton javax.swing.togglebutton javax.swing.jcheckbox javax.swing.jradiobutton 39
JButton São criados com a classe JButton Quando o usuário clica no botão é gerado um ActionEvent O método actionperformed(actionevent evt) de qualquer ouvinte registrado é chamado quando o botão for pressionado 40
JCheckBox (Caixa de Seleção) Fornece um dispositivo simples de entrada liga/desliga com um rótulo de texto ao lado A seleção ou o cancelamento de um checkbox é notificado pela interface ItemListener que define o método: public void itemstatechanged(itemevent e) Um objeto da classe ItemEvent possui um método getstatechange(), que retorna uma das duas constantes: ItemEvent.SELECTED ItemEvent.DESELECTED 41
JRadioButton e ButtonGroup Os botões de opção normalmente aparecem como um grupo em que apenas um botão de opção pode ser selecionado O relacionamento lógico entre botões de um grupo é mantido por um objeto ButtonGroup O objeto ButtonGroup em si não é um componente GUI, pois não é exibido em uma interface com o usuário O mesmo pode ser utilizado como parâmetro no construtor de um JRadioButton 42
JRadioButton (Botões de Opção) 43
JToolTip (Dica) É uma string de texto que fornece uma dica. Aparece automaticamente quando o mouse permanece sobre o componente Pode ser configurado para qualquer JComponent É necessário apenas chamar o método settooltiptext() no componente Ex: comp.settooltiptext( dica ); 44
JComboBox (Escolhas) Fornece uma lista de itens entre os quais o usuário pode escolher JComboBox gera ItemEvent, assim como, JCheckBox e JRadioButton Uso de classe interna anônima para o tratamento de eventos 45
JList Exibe uma série de itens em que o usuário pode selecionar um ou mais itens Este componente suporta Listas de uma única seleção: Lista de seleção múltipla: 46
Tratamento de Eventos do Mouse Interfaces ouvintes de eventos do mouse MouseListener e MouseMotionListener Os eventos do mouse podem ser capturados por qualquer componente GUI que herda de javax.swing.jcomponent Todos os métodos ouvintes aceitam um objeto MouseEvent como seu argumento 47
Tratamento de Eventos do Mouse (MouseEvent) Métodos (Ouvintes) da interface MouseListener mouseclicked(mouseevent e) mousepressed(mouseevent e) mousereleased(mouseevent e) mouseentered(mouseevent e) mouseexited(mouseevent e) Quando o botão do mouse for pressionado e liberado Quando o botão do mouse for pressionado Quando o botão do mouse for liberado (precedido por um evento mousepressed) Quando o cursor do mouse entra nos limites de um componente Quando o cursor do mouse deixa os limites de um componente 48
Tratamento de Eventos do Mouse (MouseEvent) Métodos (Ouvintes) da interface MouseMotionListener mousedragged(mouseevent) Quando o botão do mouse for pressionado e movido (precedido por uma chamada mousepressed) mousemoved(mouseevent) Quando o cursor do mouse for movido nos limites de um componente 49
Classes Adaptadoras Padrão de Projeto chamado Adapter Algumas interfaces possuem uma classe adaptadora que implementa todos os seus métodos, com um corpo vazio: Só existem para interfaces que possuem mais de um método Pode-se herdar de uma classe adaptadora e fornecer uma implementação (sobrescrever) somente o método necessário para o tratamento do evento 50
Classes Adaptadoras O nome da classe adaptadora é semelhante ao do Listener : MouseListener: MouseAdapter MouseMotionListener: MouseMotionAdapter KeyListener: KeyAdapter WindowListener: WindowAdapter... 51
Tratamento de Eventos do Teclado Uma classe que implementa KeyListener deve fornecer as definições para os métodos: KeyPressed KeyReleased KeyTyped Cada uma das classes recebe um KeyEvent como argumento A classe trata seus próprios eventos de teclado usando o método addkeylistener 52
Gerenciadores de Layout
Objetivos Apresentar os gerenciadores de layout: FlowLayout BorderLayout GridLayout BoxLayout GridBagLayout 54
Gerenciadores de Layouts São fornecidos para organizar componentes GUI em um container para propósitos de apresentação processam a maioria dos detalhes, fornecendo uma maneira automática de posicionar os componentes gráficos nos containers Todos os gerenciadores de Layout implementam a interface LayoutManager ou a subinterface LayoutManager2 55 Cada container como um Painel ou Frame (molduras) possui um gerenciador de layout padrão associado
Gerenciadores de Layouts É possível desativar o Gerenciador de Layout caso o programador queira definir o tamanho ou posição dos componentes Para desligar layouts: recipiente.setlayout(null); Porém torna-se necessário definir posição e tamanho de cada componente: componente.setbounds(x, y, larg, alt); 56
1. public class NullLayout extends JFrame { 2. private JButton b1, b2, b3; 3. NullLayout(String nome) { 4. super(nome); 5. Container ct = this.getcontentpane(); 6. ct.setlayout(null); 7. b1 = new JButton("Maça"); 8. b2 = new JButton("Pera"); 9. b3 = new JButton("Uva"); 10. // parametros: x, y, largura e altura 11. b1.setbounds(10,10,150,40); 12. b2.setbounds(10,60,150,40); 13. b3.setbounds(10,110,150,40); 14. ct.add(b1); ct.add(b2); ct.add(b3); 15. this.setsize(180, 200); 16. this.setvisible(true); 17. } } Exemplo Desativa o gerenciador de Layout
Tamanho e Posição dos Componentes Um container mantém uma referência a uma instância particular do Gerenciador de Layout Sempre quando for necessário posicionar o componente será invocado o Gerenciador de Layout Ou seja, se o usuário tentar definir o tamanho ou posição dos componentes (setsize() ou setlocation()) o Gerenciador de Layout irá anular a decisão 58
Tamanho e Posição dos Componentes public class TamanhoComp extends JFrame { public static void main(string[] args) { JFrame frame = new JFrame(); JPanel panel = new JPanel(); for (int i=0; i<2; i++) { JButton btn = new JButton("Não adianta chamar setsize"); btn.setsize(300, 300); } panel.add(btn); } frame.getcontentpane().add(panel); frame.setsize(450, 70); frame.setvisible(true); } Esta linha, não tem efeito, pois o botão é adicionado ao painel, que chama o seu gerenciador de layout para decidir a sua posição e quão grande o componente deve ficar 59
Política de Layout Cada componente Java tem um tamanho preferencial: Normalmente é o menor tamanho necessário para apresentar o componente de maneira visualmente significativa Exemplo de um botão é o tamanho de sua etiqueta de texto O Gerenciador de Layout equilibra duas considerações: a política de layout e o tamanho preferencial de cada componente. A prioridade é para a política de layout 60
Etapas para se construir uma interface Cada Painel é montado em quatro etapas: 1. Construir (instanciar) o painel 2. Dar ao painel o gerenciador de layout Quando um container é instanciado (etapa 1) ele recebe um gerenciador de layout padrão. Esta etapa pode ser pulada se o gerenciador a ser utilizado for o padrão 3. Preencher o painel Envolve montar componentes e acrescentá-los ao painel 4. Acrescentar o painel ao seu próprio container OBS: Se algum dos componentes for ele próprio um painel, as etapas 1 4 precisam ser executadas sucessivamente 61
Gerenciadores de Layouts Existem vários gerenciadores de layouts disponível com a linguagem Java FlowLayout, BorderLayout, GridLayout BoxLayout, GridBagLayout Principais métodos da classe java.awt.container setlayout(layoutmanager m) void add(component c) adiciona um componente ao container sob o controle do gerenciador de layout utilizado 62
FlowLayout É o gerenciador de layout mais simples Dispõe os objetos seqüencialmente da esquerda para a direita na ordem em que foram adicionados container.setlayout(new FlowLayout()); Permite aos componentes serem alinhados à esquerda, centralizados (padrão) ou à direita objetolayout.setalignment(flowlayout.right); 63
FlowLayout Todos os componentes possuem um método chamado getpreferredsize(), usado pelos gerenciadores de layout para perguntar o tamanho de cada componente É o padrão para java.awt.applet, java.awt.panel e javax.swing.jpanel 64
FlowLayout - Principais construtores FlowLayout() Centraliza os componentes deixando uma distância entre eles (gap) de 5 pixels. FlowLayout(int align) Constrói um layout com alinhamento estabelecido (FlowLayout.CENTER, FlowLayout.LEFT, FlowLayout. RIGHT) FlowLayout(int align, int hgap, int vgap) Define o alinhamento e a distância horizontal e vertical, respectivamente 65
BorderLayout É o gerenciador padrão para JFrames, JApplets e Caixas de Diálogo A classe BorderLayout herda diretamente da classe Object e implementa a interface LayoutManager2 (uma subinterface de LayoutManager) Organiza os componentes em cinco áreas Norte, Sul, Leste, Oeste e Centro 66
BorderLayout Os componentes devem ser adicionadas a regiões nomeadas no gerenciador de layout, caso contrário não ficarão visíveis: NORTH, SOUTH, EAST, WEST, CENTER Norte e Sul têm prioridade sobre Leste e Oeste, que têm prioridade sobre Centro Se for adicionado um componente ao Centro, este se expande até ocupar todo o espaço restante na janela O componente colocado em uma região pode ser um container ao qual serão anexados outros componentes (p.ex., JPanel) 67
GridLayout Fornece flexibilidade para colocação de componentes Divide o container em uma grade de modo que os componentes podem ser colocados em linhas e colunas A classe GridLayout herda diretamente da classe Object e implementa a interface LayoutManager 68
GridLayout Com o gerenciador GridLayout, a posição relativa dos componentes não é alterada quando a área é redimensionada Os componentes são adicionados iniciando na célula na parte superior esquerda da grade e prosseguindo da esquerda para a direita até a linha estar cheia. Então, o processo continua na próxima linha 69
Gerenciando layouts complexos com Painéis Interfaces complexas exigem que cada compo-nente seja colocado numa localização exata Para tanto, geralmente usam-se múltiplos painéis, cada um com seu layout específico Container -> JComponent -> JPanel 70
Classe container Box Permite colocar uma única linha ou coluna de componentes com mais flexibilidade do que o GridLayout Existe um Container - a classe Box cujo gerenciador de layout padrão é BoxLayout: Fornece métodos estáticos para criar um BoxLayout horizontal ou vertical: Box b = Box.createHorizontalBox( ) São organizados da esquerda para direita Box b = Box.createVerticalBox( ) 71 São organizados de cima para baixo
Gerenciador BoxLayout e a classe container Box Depois, adicionam-se os componentes da maneira usual: b.add(btnok); b.add(btnsair); 72
Referências Deitel & Deitel. Java como Programar, 6ª ed. Caps. 11 e 22; Materiais do site da SUN (http://java.sun.com) 73