Fundamentos de GUIs João Carlos Pinheiro jcpinheiro@cefet-ma.br Última Atualização Junho / 2004 Versão: 3.0 1
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 Layout Eventos 4
Recipientes e Componentes Componentes 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 pode conter: Um ou mais componentes, assim como outros recipientes Importante para construção de layouts de complexidade realística 5
AWT versus Swing 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 6
AWT versus Swing O swing não é um substituo 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 executa 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
Class java.awt.component Raiz da hierarquia de componentes gráficos 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 11
Class java.awt.component getlocation() e setlocation(int x, int y) estes métodos alteram a localização dos componentes (em pixel) 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, stilo 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(componet 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 qualquer 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 É necessário devido a independência de plataforma JFrame frame = new JFrame( Teste"); JPanel pan = new JPanel(); pan.add(new JButton("Button")); frame.add(pan); 20
Panel e JPanel É um recipiente de uso geral. Ele não pode ser usado isoladamente, como frames e caixas de diálogos Painéis pode administrar eventos 21
Painel - Exemplo public class PanelDemo { public static void main(string[] args) { JFrame f = new JFrame("Content Pane Demo"); f.setsize(350, 250); Container cont = f.getcontentpane(); cont.setlayout(new GridLayout(2,1)); for (int i=0; i<2; i++) { JPanel pan = new JPanel(); pan.setbackground(i==0? Color.ORANGE:Color.CYAN); } } for (int j=0; j<3; j++) pan.add(new JButton("Button")); cont.add(pan); } f.setvisible(true); 22
Vantagens/Desvantagens dos Applets Desvantagens Restrições de segurança Tempo de download Incompatibilidade com browsers Vantagens Facilidade para realizar comunicação em rede Possibilidade de abrir janelas externas Capacidade de estender o browser em recursos de segurança, protocolos de rede, capacidade gráfica 23
Vantagens/Desvantagens dos Applets Aplicação sempre atualizada Capacidade de interagir com a página via JavaScript Alternativa (1.4) Java Web Start: aplicações normais instaladas via rede 24
Manipulação de Eventos 25
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 é uma instância de uma subclasse de java.util.eventobject Fornece o método getsource() que retorna a fonte do evento 26
Tratamento de Eventos O modelo de eventos se torna fácil de usar, pois é baseada em algumas simples nomenclatura que diz o seguinte: Para cada tipo de evento XXXEvent existe uma interface XXXListener Os métodos desta interfaces são todos public void e recebem um único argumento do tipo XXXEvent ActionEvent: ActionListener ItemEvent : ItemListener TextEvent : TextListener WindowEvent: WindowListener KeyEvent : KeyListener... XXXEvento : XXXListener 27
Tratamento de Eventos Continuação (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 28
Tratamento de Eventos Continuação (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 29
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 (fonte) um ActionEvent 30
Modelo de Tratamento de Eventos 31
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(); 32
Modelo de Tratamento de Eventos 3. Listener (Ouvinte) Recebem eventos como argumento public class NomeClasse implements ActionListener { public void actionperformed(actionevent evt) { Object fonte = evt.getsource(); System.out.println(evt + em + fonte); } } 33
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 que manipula o evento 34
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 35
1. import java.awt.*; 2. import java.awt.event.*; 3. import javax.swing.*; 4. public class ButtonTest extends JFrame { 5. private JButton plainbutton, fancybutton; 6. public ButtonTest() { 7. super( "Testing Buttons" ); 8. Container c = getcontentpane(); 9. c.setlayout( new FlowLayout() ); 10. // cria o botão 11. plainbutton = new JButton( "Plain Button" ); 12. c.add( plainbutton ); 13. Icon bug1 = new ImageIcon( "bug1.gif" ); 14. Icon bug2 = new ImageIcon( "bug2.gif" ); 15. fancybutton = new JButton( "Fancy Button", bug1); 16. fancybutton.setrollovericon( bug2 ); 17. c.add( fancybutton );
17. //cria uma instância da classe interna 18. //para utilizar no tratamento de eventos 19. ButtonHandler handler = new ButtonHandler(); 20. //Liga a fonte ao listener (Ouvinte) 21. fancybutton.addactionlistener( handler ); 22. plainbutton.addactionlistener( handler ); 23. setsize( 275, 100 ); 24. setvisible(true); 25. } 26. public static void main( String args[] ) { 27. ButtonTest app = new ButtonTest(); 28. } 29. //Classe interna para tratamento de eventos 30. private class ButtonHandler implements ActionListener { 31. public void actionperformed( ActionEvent e) { 32. JOptionPane.showMessageDialog(null, 33. Sua senha: " + e.getactioncommand()); 34. } 35. } 36. } // fim da classe Registrar um ouvinte para cada componente
Descrição dos Eventos 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) 38
Alguns componentes que são subclasse de JComponent 39
JLabel São strings de texto usadas para identificar outros elementos. Normalmente são inseridas a esquerda ou acima do elemento que estar sendo rotulado Pode apresentar: Somente Texto Imagens Texto e imagens 40
1. import java.awt.*; 2. import javax.swing.*; 3. import java.awt.event.*; 4. public class JLabelTeste extends JFrame { 5. public JLabelTeste() { 6. this.setsize(264, 110); 7. this.settitle("exemplo do JLabel"); 8. JPanel painel = new JPanel(); 9. JLabel labnormal = new JLabel("JLabel Normal"); 10. painel.add(labnormal); 11. JLabel labgrande = new JLabel("Letras Grandes"); 12. //Adiciona um hint ao label 13. labgrande.settooltiptext("esta é uma dicas"); 14. // Associa a fonte ao JLabel 15. labgrande.setfont(new Font("Serif", Font.BOLD Font.ITALIC, 32));
19. Icon carro = new ImageIcon("carro.gif"); 20. // Adiciona o Ícone ao JLabel 21. labgrande.seticon(carro); 22. labgrande.sethorizontalalignment(jlabel.right); 23. painel.add(labgrande); 24. // Adiciona o painel ao Formulário 25. getcontentpane().add(painel); 26. } 27. public static void main(string args[]) { 28. JLabelTeste nova = new JLabelTeste(); 29. nova.show(); 30. } 31.}
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 A classe JPasswordField herda de JTextField e adiciona vários métodos que são específicos ao processamento de senhas Confira: TextFieldTest.java 43
JTextField e JPasswordField TextFieldTest.java 44
// Demonstrando as classes JTextField e JPasswordField import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TextFieldTest extends JFrame { private JTextField text1, text2, text3; private JPasswordField password; public TextFieldTest() { super( "Testing JTextField and JPasswordField" ); Container c = getcontentpane(); c.setlayout( new FlowLayout() ); text1 = new JTextField( 10 ); c.add( text1 ); text2 = new JTextField( "Enter text here" ); c.add( text2 );
text3 = new JTextField( Text Field desabilitado", 20 ); text3.seteditable( false ); // desabilita o JTextField c.add( text3 ); password = new JPasswordField( secreto" ); c.add( password ); //Instancia um objeto da classe interna TextFieldHandler //que implenta a interface ActionListener TextFieldHandler ouvinte = new TextFieldHandler(); text1.addactionlistener( ouvinte ); text2.addactionlistener( ouvinte ); text3.addactionlistener( ouvinte ); password.addactionlistener( ouvinte ); setsize( 325, 100 ); show(); } // fim do construtor
// classe interna para tratamento de eventos private class TextFieldHandler implements ActionListener { public void actionperformed( ActionEvent e ) { String s = ""; if ( e.getsource() == text1 ) s = "texto1: " + e.getactioncommand(); else if ( e.getsource() == text2 ) s = "texto2: " + e.getactioncommand(); else if ( e.getsource() == text3 ) s = "texto3: " + e.getactioncommand(); else if ( e.getsource() == password ) { JPasswordField pwd = (JPasswordField) e.getsource(); s = "senha: " + new String( pwd.getpassword() ); } JOptionPane.showMessageDialog( null, s ); } } // fim da classe interna } //fim da classe TextFieldTest
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 javax.swing.abstractbutton 48
JButton javax.swing.jcomponent javax.swing.abstractbutton (Classe Abstrata) javax.swing.jbutton javax.swing.togglebutton javax.swing.jcheckbox javax.swing.jradiobutton 49
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 Confira os exemplos: JButtonTeste1.java 50
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 itemstatechange(itemevent e) O objeto da classe ItemEvent possui um método getstatechange() que retorna uma das duas constantes: ItemEvent.SELECTED ItemEvent.DESELECTED Confira os exemplo: CheckBoxTest.java 51
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 Vale destacar que o mesmo pode ser utilizado como parâmetro no construtor de um JRadioButton 52
JRadioButton (Botões de Opção) Confira os exemplo: RadioButtonTeste1.java 53
JToolTip É 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 ); Como aparece na tela? 54
JOptionPane Uma classe utilitária que fornece Caixas de Dialogos 55
JTextArea Fornece uma área de manipulação de múltiplas linhas de texto Um JTextArea não tem eventos de ação como o JTextField O JTextArea podem ter barras de rolagem (por meio de um componente JScrollPane) ta = new JTextArea( s, 10, 15 ); container.add(new JScrollPane(ta)); Confira os exemplo: TextAreaDemo.java 56
JComboBox (Escolhas) Fornece uma lista de itens entre os quais o usuário pode escolher JComboBox gera ItemEvent, assim como, JCheckBox e JRadioButton Confira os exemplo: ComboBoxTest.java 57
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 Confira os exemplo: ListTest.java Lista de seleção múltipla Confira os exemplo: MultipleSelection.java 58
Tratamento de Eventos do Mouse Interfaces ouvintes de eventos do mouse MouseListenter 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 59
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 curso do mouse entra nos limites de um componente Quando o curso do mouse deixa os limites de um componente 60
Tratamento de Eventos do Mouse (MouseEvent) Métodos (Ouvintes) da interface MouseMotionListener mousedragged(mouseevent) mousemoved(mouseevent) Quando o botão do mouse for pressionado e movido (precedido por uma chamada mousepressed) Quando o curso do mouse for movido nos limites de um componente Confira os exemplo: MouseTracker.java Confira os exemplo: MouseDetails.java 61
Classes Adaptadoras Padrão de Projeto chamado Adapter Algumas interfaces possuem uma classe adaptadora que implementa todos os métodos, sem instruções Só existe para interfaces que possui mais de um método 62
Classes Adaptadoras O programador pode estender a classe adaptadora para herdar a implementaçãopadrão de cada método e então redefinir (anular) o(s) métodos(s) necessário(s) para tratamento de eventos O nome da classe adaptadora é semelhante ao do Listener MouseListener: MouseAdapter, WindowListener: WindowAdapter,... Confira os exemplo: Painter.java 63
Tratamento de Eventos do Teclado Uma classe que implementa KeyListener deve fornecer as definições para os métodos KeyPressed KeyReleased KeyType Cada uma das classes recebe um KeyEvent como argumento Confira os exemplo: KeyDemo.java 64
Bibliografia Consultada Guia Completo de estudos para Certificação Java 2. Autores: Philip Heller e Simon Roberts Core Java Volume I Fundamentos Core Java Volume II Recursos Avançados Java Como Programar 3ª Edição. Autor: H. M. Deitel e P. J. Deitel 65