Neste módulo veremos:
swing
;As GUI, do inglês, Graphical User Interfaces, são construídas a partir de componentes (também chamados de widgets) que interagem com o usuário via mouse, teclado ou outro dispositivo de entrada,
Na imagem abaixo podemos ver alguns dos principais componentes de uma janel gráfica, que são:
Java originalmente gerava as janelas gráficas através de
um pacote chamado AWT
, acrônimo de Another Window Toolkit.
O pacote java.awt
associa as capacidades gráficas aos recursos
da plataforma local. Esta é uma característica
interessante para algumas aplicações mas é limitante em
outras pois impede uma padronização da interface a medida que gera componentes
diferentes para cada plataforma.
Diferentemente do pacote java.awt
os componentes do pacote javax.swing
são escritos, manipulados e
exibidos usando somente a tecnologia Java (não são sobrecarregados
pelos recursos gráficos da plataforma) e por isso são também conhecidos
como componentes puros
, ou componenentes peso-leve
.
Através dos componenentes da classe java.swing
existe um
controle total do comportamento e da aparência dos componentes gráficos.
Algumas das características do pacote Swing
são:
Abaixo vemos a hierarquia de classes que definem os atributos e os comportamentos das classes de componentes gráficos. Cada classe é exibibida pelo nome de seu pacote e elas estão apresentadas hierarquicamente da classe raíz para as classes descendentes.
java.lang.Object java.awt.Component java.awt.Container java.swing.JComponent
Logo, JComponent
herda da classe Container
que,
por sua vez, herda da classe Component
que herda da classe
Object
. Assim, todo JComponent
é um
Container
que, por sua vez é um Component
e assim por
diante.
Um Component
é um objeto que tem uma representação gráfica
que pode ser mostrada na tela e oferece interação com o usuário. Exemplos
deste componente são os botões, os checkboxes e as barras de rolagem
(scrollbars
).
Já o Container
é uma coleção de componentes
relacionados, ou mehor, é um componente que pode conter outros
componentes. Fazem parte deste componente os painéis, os painéis com scroll
e as windows.
As vedetes desta aula são os componentes derivados da subclasse JComponent
.
Uma GUI é formada por componentes.
Em Java temos os seguintes componentes mais comuns:
JLabel
: para textos e ícones não editáveis;JTextField
: área para inserção de dados;JButton
: aciona um evento ao click do mouse;JCheckBox
: dois estados: selecionado e não-selecionado;JComboBox
: caixa de rolagempara seleção de um elemento;
JList
: a seleção pode disparar um evento;JPanel
: container em que são colocados os componentes.Veja todos os componentes Swing
neste
link.
Vejamos agora um exemplo e criação de um componente GUI aproveitado das páginas da Sun.
/** hello.java * @author java.sun.com */ import javax.swing.*; public class Hello { private static void criaMostraGUI() { //ajusta a decoracao da janela JFrame.setDefaultLookAndFeelDecorated(true); //cria uma noja janela JFrame frame = new JFrame("HelloWorld usando Swing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //adiciona label "Hello World" label. JLabel label = new JLabel("Hello World"); frame.getContentPane().add(label); //Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { //cria e mostra a plicacao usando thread javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { criaMostraGUI(); } }); } }
Grande parte das aplicações envolvendo componentes GUI usam os eventos, as respostas as interações do usuário portato, é imperativo aprender sobre eventos para usar as componentes GUI.
Os compoentes da GUI são baseados em eventos. Os eventos ocorrem
quando há interação do usuário com a máquina, por exemplo, ao
usar o teclado ou o mouse. Vários eventos podem ser disparados
nestas situações. Veremos agora como programar os respostas
da GUI aos eventos.
Existem vários tipos de eventos. Cada componente suporta vários tipos de eventos, como eventos de mouse, teclado, entre outros. São eventos comuns:
ContainerEvent
FocusEvent
KeyEvent
WindowEvent
MouseEvent
Cabe lembrar que os eventos aqui não estão organizados hierarquicamente em classes, como na realidade estão. Para uma descrição mais detalhada destas classes consulte as páginas de referência da API que está usando.
O mecanismo de evento tem três partes significativas e diferentes:
listener, ouvinte é o objeto que é notificado pelo evento, recebe um objeto evento quando notificado sobre ele.
O processamento do evento é delegado ao ouvinte de eventos no aplicativo, ou melhor, quando ocorre um evento existe um mecanismo de aviso (dispatch) para os ouvintes daquele evento. Este dispatch é na realidade uma delegação para que o ouvinte cuide do tratamento de evento.
Para cada tipo de evento, ou melhor, objeto evento, existe uma interface ouvinte do evento correspondente. Esta interface é a encarregada deste tratamento.
Cada interface ouvinte especifica um ou mais métodos de tratamento do evento. Estes métodos devem ser declarados na classe que implementa a interface.
Lembre-se que uma interface é usada quando classes muito diferentes, ou melhor, pouco relacionadas, precisam compartilhar métodos e constantes comuns. Objetos que implementam a mesma interface podem responder às mesmas chamadas de métodos. Uma interface pode descrever genericamente funcionalidades e o programador pode depois implemetá-las para cada classe específica.
Cada tipo de evento tem uma ou mais interfaces ouvintes de eventos. São interfaces comuns:
ActionListener
ComponentListener
FocusListener
KeyListener
MouseListener
TexteListener
WindowListener
Três situações devem ser observadas para o tratamentode eventos:
listener
) que responderá a um
evento;Todo ouvinte tem uma lista de eventos aos quais deverá reagir. O programador deve registar o evento na lista dos eventos que o ouvinte deve reagir. O programador também deverá influir nos métodos de tratamento de eventos especificados pelas interfaces dos ouvintes.
Quando um evento ocorre, o componente GUI recebe da JVM um identificador
(um número) que especifica o tipo de evento. Este ID é usado para
decidir como será o dispatch
, qual o método chamar para
cada tipo de ouvinte. Por exemplo, para um ActionEvent
o evento é
despachado para o método actionPerformed
.
JTextField
Vejamos como isso ocorre no exemplo abaixo:
/** CampoTexto.java * @author EESR based on Deitel e Deitel */ import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CampoTexto extends JFrame { private JTextField texto1, texto2, texto3; // configura a GUI public CampoTexto() { super("Teste de JField"); Container container = getContentPane(); container.setLayout( new FlowLayout()); texto1 = new JTextField(10); // dimensao do campo container.add(texto1); // texto default texto2 = new JTextField("Texto aqui"); container.add(texto2); texto3 = new JTextField("Não permite edição", 30); texto3.setEditable(false); container.add(texto3); // registra tratadores de evento TratadorTexto tratat; tratat = new TratadorTexto(); texto1.addActionListener(tratat); texto2.addActionListener(tratat); texto3.addActionListener(tratat); setSize(350,100); setVisible(true); } // executor do aplicativo public static void main (String args[]) { CampoTexto aplicacao = new CampoTexto(); aplicacao.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); } // classe interna para tratar eventos private class TratadorTexto implements ActionListener { public void actionPerformed (ActionEvent evento){ String cadeia = ""; // enter no texto1 if (evento.getSource() == texto1) cadeia = "texto1. evento: " + evento.getActionCommand(); // enter no texto2 else if (evento.getSource() == texto2) cadeia = "texto2. evento: " + evento.getActionCommand(); // enter no texto3 else if (evento.getSource() == texto3) cadeia = "texto3. evento: " + evento.getActionCommand(); JOptionPane.showMessageDialog(null, cadeia); } } }
Detalhes:
ActionListener
através de implements
,
de rescrita, especificando o que fazer dado o evento;Como dissemos, existem várias interfaces que respondem à varios eventos. Não veremos todas aqui mas algumas. Cabe ao programador sempre consultar a documentação para maiores detalhes.
JButton
Veja abaixo um exemplo simples de uso de botões em Java
/** BotoesTexto.java * @author EESR */ import java.awt.Container; import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.JOptionPane; public class BotoesTexto extends JFrame { private JButton bot1; private JButton bot2; public BotoesTexto() { super ("Teste de botões com texto"); Container cont = getContentPane(); cont.setLayout (new FlowLayout()); bot1 = new JButton("B1"); cont.add(bot1); bot2 = new JButton("B2"); cont.add(bot2); TrataBotoes handler = new TrataBotoes(); bot1.addActionListener (handler); bot2.addActionListener (handler); } public static void main (String args[]) { BotoesTexto bt = new BotoesTexto(); bt.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); bt.setSize(200,100); bt.setVisible(true); } private class TrataBotoes implements ActionListener { public void actionPerformed (ActionEvent evento) { if (evento.getSource()==bot1) JOptionPane.showMessageDialog (BotoesTexto.this, "Botão 1"); else JOptionPane.showMessageDialog (BotoesTexto.this, "Botão 2"); } }// private }
Note que, como para JTextField
os JButton
geram
ActionEvent
que podem ser processados por
qualquer objeto ActionListener
(que é na verdade uma interface).
É o método da interface ActionPerformed()
que recebe um
ActionEvent
.
Veja agora a segunda versão deste mesmo programa que trata botões e um campo de texto. É uma boa dica para a sua calculadora.
/** BotoesTexto.java * @author EESR * @version 0.2 */ import java.awt.Container; import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.JTextField; import javax.swing.JOptionPane; public class BotoesTexto extends JFrame { private JButton bot1; private JButton bot2; private JTextField texto; public BotoesTexto() { super ("Teste de botões com texto"); Container cont = getContentPane(); cont.setLayout (new FlowLayout()); texto = new JTextField(20); cont.add(texto); bot1 = new JButton("B1"); cont.add(bot1); bot2 = new JButton("B2"); cont.add(bot2); TrataBotoes handler = new TrataBotoes(); bot1.addActionListener (handler); bot2.addActionListener (handler); } public static void main (String args[]) { BotoesTexto bt = new BotoesTexto(); bt.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); bt.setSize(250,100); bt.setVisible(true); } private class TrataBotoes implements ActionListener { public void actionPerformed (ActionEvent evento) { if (evento.getSource()==bot2) { int num = Integer.parseInt (texto.getText()); num++; JOptionPane.showMessageDialog(null, "Um a mais é: " + num); } else texto.setText("1234"); } }// private }
Procura na API correspondente, para cada componente GUI, no pacote
java.awt
principalmente, a quais tipos de objetos
o dado componente reage, quais são os eventos gerados e
os métodos a serem programados.
(evandro at usp ponto br)