Buscar

Aplicações de Linguagem de Programação Orientada a Objetos

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 27 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 27 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 27 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Aplicações de Linguagem de Programação Orientada a 
Objetos 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 2 
Módulo 1 – AWT (Abstract Window Toolkit) e Swing 
Componentes 
Os componentes, também chamados de widgets (windows gadgets, ou dispositivos de janelas) 
são os elementos construtivos das interfaces gráficas de usuário ou GUIs, isto é, são botões, 
caixas de entrada de texto, caixas de seleção, menus, barras de rolagem, etc., que compõem 
qualquer aplicativo visual. Também existem componentes não visuais destinados a oferecer 
suporte aos demais componentes, como prover acesso a dados ou outras tarefas com as quais o 
usuário do aplicativo não interaja diretamente. A figura abaixo apresenta um exemplo de GUI: 
 
Java oferece uma ampla biblioteca de componentes GUI e de capacidades gráficas na forma de 
classes, pertencentes aos pacotes java.awt e javax.swing, que representam os frameworks 
(ou conjuntos de classes) responsáveis pela composição dos elementos visuais em um aplicativo. 
AWT 
A AWT constitui a primeira biblioteca de componentes visuais do Java que permitem a construção 
de aplicações GUI, capaz de ser utilizada em grande parte dos sistemas operacionais. A AWT 
funciona como uma casca entre o componente do sistema nativo e seu equivalente representado 
pela classe correspondente da biblioteca. 
Assim, uma aplicação Java AWT que contenha um botão usará o componente nativo para botões 
onde a aplicação é executada. Mesmo que a aparência do componente apresente ligeira diferença 
entre um sistema operacional e outro para o mesmo aplicativo, o comportamento e funcionamento 
durante a operação serão os mesmos. 
No entanto, isso exige um mecanismo razoavelmente complexo e pesado de troca de mensagens 
entre o sistema operacional e a JVM (máquina virtual Java), o que reduz o desempenho dos 
componentes AWT (daí serem chamados de componentes pesados ou heavy-weight 
components). Além disso, a quantidade de componentes disponíveis é relativamente pequena e a 
construção de novos componentes torna-se complexa ou dependente da plataforma. 
A classe abstrata Component é a base para a construção de todos os componentes GUI 
oferecidos pelo Java no pacote java.awt. Essa classe oferece a infra-estrutura necessária para 
a criação de objetos que possuam uma representação gráfica, as quais poderão ser exibidas num 
ambiente gráfico e com as quais o usuário poderá interagir. Sendo uma classe abstrata, 
 3 
Component não pode ser instanciada diretamente, mas sendo a classe-base comum de todos os 
componentes da biblioteca AWT, possibilita por meio do polimorfismo o tratamento generalizado 
dos componentes derivados. 
Com a API (Application Programming Interface ou Interface de Programação de Aplicativos) da 
classe Component é possível determinar tamanho, cores, fonte e cursor utilizados pelo 
componente, além do seu estado de funcionamento, posição e visibilidade. 
Em particular, a classe Component é a base para a construção de outra classe abstrata especial 
denominada Container, a qual representa um compartimento onde outros componentes podem 
ser adicionados e posicionados, cuja API oferece facilidades para inclusão e remoção de 
componentes. Classes derivadas de Container também são containers, isto é, também podem 
conter outros componentes, tais como janelas e painéis. 
Atualmente a AWT está integrada à JFC (Java Foundation Classes), um conjunto de bibliotecas 
que engloba a própria AWT, o Swing e o Java 2D. A JFC foi desenvolvida para a construção de 
aplicativos GUI e também gráficas voltadas para diferentes plataformas operacionais, cujo 
destaque é o Swing, uma outra família de componentes. 
Swing 
Como comentado, o uso do AWT é dependente da plataforma; portanto, usá-la não é fácil e essa 
biblioteca não está livre de bugs. Os componentes da biblioteca Swing são mais fáceis de utilizar 
e estão muito mais bem implementados, mas alguns de seus componentes ainda necessitam de 
classes da biblioteca AWT. A família de componentes Swing é uma parte importante da JFC que 
engloba: 
• Componentes Swing – uma nova família de componentes com funcionalidade ampliada e 
grande capacidade de configuração; 
• Suporte para múltiplos Pluggable Look and Feel – dá aos programas Java a 
capacidade de utilizarem diferentes aparências visuais, tais como peles (skins) adaptadas 
ou não ao ambiente operacional utilizado; 
• Acessibilidade – permite o uso integrado de tecnologias para auxílio de portadores de 
necessidades especiais, tais como monitores e teclados diferenciados; 
• Java 2D – um pacote de classes para desenho 2D de gráficos, texto e imagens de alta 
qualidade; 
• Suporte para Drag and Drop – oferece capacidade de arrastar e soltar entre aplicações 
Java e aplicações nativas. 
Além de oferecer um conjunto muito mais amplo e versátil, os componentes Swing são 100% Java 
e assim não utilizam código nativo tal como a família AWT, constituindo deste modo componentes 
leves (ou light-weight components). 
A classe JComponent do pacote javax.swing oferece a infra-estrutura para a maior parte dos 
componentes Swing. Por sua vez, a classe JComponent é uma subclasse da classe Container, 
 4 
do pacote java.awt, uma classe abstrata que oferece a estrutura para construção de 
componentes que podem conter outros componentes. Em virtude disso, a estratégia de 
representação (ou renderização) utilizada no Swing é diferenciada, sendo dividida em três partes: 
a representação do componente em si, a representação da borda do componente e a 
representação dos componentes nele contidos. A figura abaixo apresenta o diagrama da 
hierarquia de classes da biblioteca Swing e respectivas dependências com a biblioteca AWT. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Como uma interface gráfica trabalha 
Programas com interface gráfica de usuário (GUI) são controlados por eventos. Isto significa que o 
programa reage às ações do usuário; estas ações são chamadas de eventos. Exemplos de 
eventos podem ser: o pressionar de uma tecla do teclado, mover o mouse, pressionar um botão 
ou selecionar um item de menu. 
Um programa com uma GUI possui uma pequena fase de iniciação na qual a GUI é construída, 
mas ainda não exibida. Algumas outras ações (não relacionadas aos componentes visuais) 
também são executadas. Esta fase não é controlada por eventos e não é possível a interação com 
java.awt.Container JComponent 
JTextComponent AbstractButton 
JComboBox 
Texto 
JTextArea 
JEditorPane 
JTextPane 
JTextField 
Menus Widgets 
JLabel 
JList 
JTree 
JToolBar 
JTable 
JMenuBar 
JPopupMenu 
JCheckBoxMenuItem 
JMenuItem 
JMenu 
JRadioButtonMenuItem 
JSeparator 
JToggleButton 
JButton 
JCheckBox 
JRadioButton 
JPasswordField 
JSlider 
JToolTip 
JScrollBar 
JProgressBar 
Sub-janelas 
java.awt.Panel 
java.awt.Applet 
JApplet 
JPanel 
JViewPort 
Janelas de nível mais alto 
JScrollPane 
JRootPane 
JTabbedPane 
JOptionPane 
JInternalFrame 
JPane 
JSliptPane 
JLayeredPane 
java.awt.Applet 
JWindow 
JFrame 
JDialog 
java.awt.Frame 
java.awt.Dialog 
 5 
o usuário. Depois desta fase a GUI é apresentada na tela e o programa passa a ser controlado 
por eventos. 
Obviamente, queremos que o programa reaja somente a alguns tipos de eventos, não todos. O 
programador precisa especificar quem serão os eventos aos quais o programa deverá reagir e, é 
claro, quais as reações que deverá ter para cada evento. Em Java isto é feito acrescentando-se 
os chamados listeners, ou observadores de eventos, que são interfaces que ficam aguardando a 
ocorrência de determinados tipos de eventos. O observador, então, executa a ação desejada por 
meio deseus métodos. Os eventos são processados na seqüência em que ocorrem, sob o 
controle de um despachante de eventos que os organizam em fila. 
Existem muitos tipos de eventos em Java associados a diferentes fontes de eventos, tais como 
botões, menus ou o mouse. Os eventos contêm informações sobre o que aconteceu, isto é, quem 
disparou o evento (se um botão ou um item de menu) e onde ele ocorreu (em quais coordenadas 
do mouse, por exemplo). Estas são as informações exploradas pelo observador. O diagrama da 
figura abaixo indica como se dá este processo. 
 
 
 
 
 
 
 
 
 
 
 
Cada componente da interface é um objeto de uma classe distinta. O mesmo acontece com cada 
tipo de evento, que é um objeto de uma classe particular, da mesma forma que cada observador 
(listener) é uma interface que especifica um tipo particular de receptor de eventos. As classes e 
interfaces disponíveis no modelo de eventos da AWT estão no pacote java.awt.event. Todos 
os eventos da AWT possuem uma raiz comum que é a classe abstrata AWTEvent, existindo tipos 
diferentes de eventos responsáveis pelo encapsulamento de informações relativas às diferentes 
ações possíveis. 
Todos os componentes Swing são capazes de produzir eventos dos seguintes tipos: 
ComponentEvent, FocusEvent, KeyEvent e MouseEvent. Tais eventos, respectivamente, 
sinalizam a alteração do tamanho, posição e visibilidade do componente, as mudanças de foco, o 
acionamento de teclas via teclado e a utilização do mouse sobre o componente, necessitando de 
tratamento pelos seus respectivos observadores: ComponentListener, FocusListener, 
Programa GUI 
 
Gera eventos 
Despachante de eventos 
Enfileira os 
eventos e notifica 
Observadores de eventos 
Acionam 
Métodos de notificação 
 6 
KeyListener e MouseListener. A tabela a seguir apresenta os eventos adicionais gerados 
pelos principais componentes Swing. 
Classes 
Ac
tio
n
Ev
en
t 
Ca
re
tE
v
en
t 
Ch
an
ge
Ev
en
t 
Do
cu
m
en
tE
v
en
t 
Un
do
ab
le
Ed
itE
v
en
t 
Ite
m
Ev
en
t 
Li
st
Se
le
ct
io
n
Ev
en
t 
W
in
do
w
Ev
en
t 
Outros eventos 
JButton * * * 
JCheckBox * * * 
JColorChooser * 
JComboBox * * 
JDialog * 
JEditorPane * * * HyperlinkEvent 
JFileChooser * 
JFrame * 
JInternalFrame InternalFrameEvent 
JList * 
JMenu MenuEvent 
JMenuItem * * * MenuDragMouseEvent, MenuKeyEvent 
JOptionPane 
JPasswordField * * * * 
JPopupMenu PopupMenuEvent 
JProgress * 
JRadioButton * * * 
JSlider * 
JSpinner * 
JTabbedPane * 
JTable * 
TableModelEvent, 
TableColumnModelEvent, 
CellEditorEvent 
JTextArea * * * 
JTextField * * * * 
JTextPane * * * HyperlinkEvent 
JToggleButton * * * 
JTree 
TreeExpansionEvent, 
TreeWillExpandEvent, 
TreeModelEvent, 
TreeSelectionEvent 
JViewPort * 
 
Os eventos típicos do Swing são aqueles produzidos pelos componentes mais usados pela 
grande maioria das aplicações, cujo tratamento é usualmente requisitado: 
• ActionEvent – evento semântico que indica a ocorrência de alguma ação predefinida em 
um componente. Corresponde ao acionamento de botões (JButton) e itens de menu 
(JMenuItem), mas pode ser disparado por outros componentes tal como no acionamento 
da tecla ENTER em uma caixa de texto (JTextField). Seu tratamento é realizado por 
implementação da interface ActionListener; 
• CaretEvent – notifica as classes interessadas que a posição do cursor de edição de um 
componente de texto sofreu modificação. É produzido por componentes deste tipo, tais 
como JTextField e JTextArea. Seu tratamento é realizado por implementações da 
interface CaretListener; 
• ChangeEvent – permite avisar às classes interessadas que ocorreu alguma mudança no 
componente associado, tal como o posicionamento de um controle deslizante JSlider ou 
 7 
troca de aba em um JTabbedPane. Seu tratamento é realizado por implementações da 
interface ChangeListener; 
• DocumentEvent – constitui uma interface para notificação de modificações em 
documentos (conteúdo de componentes de texto). São produzidos de modo especializado 
por JTextField, JTextArea e outros. Seu tratamento exige a implementação da 
interface DocumentListener; 
• UndoableEditEvent – indica a ocorrência de uma operação que pode ser desfeita e cujo 
tratamento se dá por meio da interface UndoableEditListener; 
• ItemEvent – evento semântico que indica a seleção ou remoção da seleção de um 
componente. Corresponde a seleção de caixas de opção (JCheckBox), botões de opção 
(JRadioButton) ou itens de combos e listas (respectivamente JComboBox e JList). 
Seu tratamento é realizado por implementações da interface ItemListener; 
• ListSelectionEvent – caracteriza a mudança de seleção em uma caixa de lista (JList) 
ou tabela (JTable). Seu tratamento é realizado por implementação da interface 
ListSelectionListener; 
• WindowEvent – evento de baixo nível que indica a alteração do estado de uma janela. O 
tratamento deste evento se dá por meio de implementações da interface 
WindowListener. 
Os eventos semânticos são aqueles que têm significados bem definidos e cujos tratamentos são 
independentes de plataforma. Também são considerados como eventos de alto nível. Já os 
demais eventos, chamados de baixo nível, possuem tratamentos que, às vezes, precisam 
considerar detalhes específicos da plataforma, sendo portanto de implementação mais complexa. 
O tratamento de eventos no Java é relativamente simples. Para um evento qualquer, aqui 
denominado XEvent, seu tratamento sempre acontece por meio de uma interface XListener, a 
qual será incluída e removida respectivamente pelos métodos addXListener(XListener) e 
removeXListener(XListener). Na interface XListener é comum que os métodos a serem 
implementados tenham como prefixo o nome do evento (embora existam várias exceções). 
A tabela abaixo relaciona os principais eventos, suas interfaces ou classes adaptadoras e 
respectivos métodos do Swing: 
Evento Interface ou Adaptador Métodos 
ActionEvent ActionListener actionPerformed(ActionEvent) 
CaretEvent CaretListener caretUpdate(CaretEvent) 
ChangeEvent ChangeListener stateChanged(ChangeEvent) 
componentHidden(ComponentEvent) 
componentMoved(ComponentEvent) 
componentResized(ComponentEvent) ComponentEvent 
ComponentListener 
 
ComponentAdapter 
componentShow(ComponentEvent) 
changedUpdate(DocumentEvent) 
insertUpdate(DocumentEvent) DocumentEvent DocumentListener 
removeUpdate(DocumentEvent) 
focusGained(FocusEvent) FocusEvent FocusListener FocusAdapter focusLost(FocusEvent) 
ItemEvent ItemListener itemStateChanged(ItemEvent) 
keyPressed(KeyEvent) KeyEvent KeyListener 
KeyAdapter keyReleased(KeyEvent) 
 8 
keyTyped(KeyEvent) 
ListSelectionEvent ListSelectionListener valueChanged(ListSelectionEvent) 
mouseClicked(MouseEvent) 
mouseEntered(MouseEvent) 
mouseExited(MouseEvent) 
mousePressed(MouseEvent) 
MouseListener 
 
MouseAdapter 
mouseReleased(MouseEvent) 
mouseDragged(MouseEvent) 
MouseEvent 
MouseMotionListener 
MouseMotionAdapter mouseMoved(MouseEvent) 
MouseWheelEvent MouseWheelListener mouseWheelMoved(MouseWheelEvent) 
UndoableEditEvent UndoableEditListener undoableEditHappened(UndoableEditEvent) 
windowActivated(WindowEvent) 
windowClosed(WindowEvent) 
windowClosing(WindowEvent) 
windowDeactivated(WindowEvent) 
windowDeiconified(WindowEvent) 
windowIconified(WindowEvent) 
WindowEvent 
WindowListener 
 
WindowAdapter 
windowOpened(WindowEvent) 
 
Módulo 2 – Swing parte 1: Criação de objetos via código 
Construindo uma aplicação gráfica 
Quando se decide pela construçãode uma aplicação gráfica, é necessário um projeto da interface 
para a aplicação, ou seja, é preciso determinar quais tarefas devem ser realizadas pela interface, 
quais componentes serão utilizados, qual o objetivo de seu uso e qual a disposição desejada para 
tais componentes. Dessa maneira, é possível dizer que a representação de uma aplicação gráfica 
envolve seis passos simples, os quais devem ser repetidos para cada janela pretendida para a 
aplicação: 
1. Esboço da janela: desenho da janela pretendido que inclui disposição dos componentes 
(leiaute), identificação e tipo dos componentes, especificação das ações do usuário e 
reações correspondentes; 
2. Implementação de uma subclasse JFrame: construção de uma subclasse de JFrame para 
cada janela; 
3. Declaração dos componentes: declaração dos componentes ativos como campos privados 
da classe criada e, opcionalmente, dos componentes não ativos; 
4. Representação do construtor: definição de construtor capaz de organizar os componentes 
na interface e registrar os eventos necessários; 
5. Programação dos processadores de eventos (event listeners): representação dos métodos 
que processarão os eventos selecionados; 
6. Início da aplicação GUI: caso a janela seja a principal da aplicação (a primeira janela a ser 
utilizada), é adequado incluir o método main(String[] args). 
Frames 
Os elementos básicos de qualquer sistema operacional gráfico são as janelas, que são áreas 
retangulares nas quais texto, imagens ou outras informações podem ser exibidas. As janelas 
também podem conter elementos de interação com usuários, como menus, botões ou áreas para 
 9 
entrada de textos. Muitos outros componentes gráficos não podem ser exibidos isoladamente, 
sendo necessário que sejam colocados dentro de uma janela. A aparência final de uma janela 
dependerá do sistema operacional utilizado, especialmente a largura e o tipo de borda ao redor de 
uma janela. A posição e a cor dos botões podem variar. 
Em Java, o termo frame (moldura) é usado para aquilo que genericamente é denominado janela. 
No Swing, os frames são representados pela classe JFrame. Um frame é uma área retangular 
com uma barra de título no topo. A barra de título também contém botões para fechar, maximizar 
e minimizar a janela. Como comentado, o tipo e a posição desses botões dependem da 
plataforma (Windows, MacOS, Linux, Solaris, etc.). Abaixo da barra de título existe uma área na 
qual outros componentes gráficos podem ser embutidos. Esta área é dividida em duas partes: um 
espaço para uma barra de menu na parte superior e o painel de conteúdo, logo abaixo. O painel 
de conteúdo pode conter diversos componentes gráficos embutidos. Se não for incluída uma barra 
de menu, então o painel de conteúdo é expandido para o espaço vazio deixado pela ausência da 
barra de menu. As funções básicas como redimensionamento ou movimentação do frame com o 
mouse são automaticamente fornecidas e não precisam ser programadas pelo programador. 
Existe um outro componente chamado window na biblioteca Swing, mas este componente não 
possui moldura, isto é, não possui uma barra de título, uma borda nem botões de fechar, 
maximizar ou minimizar. A figura abaixo mostra a estrutura de um frame: 
 
 
 
 
 
 
 
 
 
 
 
 
O construtor padrão do frame é o JFrame(), que gera um frame sem título. Gerar aqui significa 
que a informação para desenhar-se o frame é fornecida; entretanto, o frame não é exibido na tela. 
Isto é obtido chamando-se o método setVisible. 
O método setVisible(boolean b) torna o frame visível se b for true. Se b for false, o 
frame é ocultado da tela, mas a informação utilizada para desenhá-lo não é destruída. Assim, se b 
for true novamente, o frame tornar-se-á visível na tela mais uma vez, ou seja, não será 
necessário chamar o construtor uma segunda vez. 
 
 
 
 
 
Painel de conteúdo 
Título X □ _ 
Espaço para a barra de menu 
 10 
O método setTitle(String title) ajusta o título na barra de título do frame com o valor 
passado como argumento em title. 
O método setSize(int width, int height) ajusta a largura do frame de acordo com o 
valor passado como argumento em width e a altura com o valor passado em height. 
O método setLocation(int horizontal, int vertical) posiciona o canto superior 
esquerdo do frame na tela de acordo com os valores passados em horizontal e vertical. 
O método pack() redimensiona o frame de modo que se ajuste firmemente ao redor dos 
componentes embutidos em seu painel de conteúdo. 
Finalmente, o método setDefaultCloseOperation(int operation) determina o que 
acontece se o botão de fechar do frame for pressionado. Neste caso, pode-se utilizar a opção 
JFrame.EXIT_ON_CLOSE como parâmetro passado ao argumento operation. 
Panels e layouts 
Embutiremos agora outro componente gráfico em um frame. Os componentes usados chamam-se 
panels (painéis). Panels são componentes retangulares, que servem a dois propósitos: podem ser 
usados como se fossem uma tela onde se pode desenhar ou podem ser usados como 
compartimentos (containers) para embutir mais componentes gráficos. 
No Swing a classe JPanel representa um panel. Abaixo temos seu construtor e alguns métodos: 
JPanel() é o construtor. O tamanho do panel é ajustado para valores padronizados, 10 por 10 
pixels na maioria dos sistemas. 
setBackground(Color c) ajusta a cor de fundo do panel. A classe Color vem da biblioteca 
da AWT. Assim, algumas cores são pré-definidas, isto é, vermelho será Color.red. Por padrão a 
cor de fundo é cinza (grey). 
setPreferredSize(Dimension d) ajusta o tamanho do panel. A classe Dimension vem da 
biblioteca da AWT. O construtor possui a sintaxe Dimension(int width, int height). 
Tanto width quanto height estão em pixels. É importante lembrar que estes valores são apenas 
recomendações para o tamanho de um componente. Dependendo do tamanho de outros 
componentes, o sistema – em tempo de execução – poderá escolher valores diferentes para eles! 
Os valores realmente usados são determinados por um LayoutManager (gerenciador de leiaute) 
em tempo de execução. Esta flexibilidade é importante ao Java para que seja independente de 
plataforma. 
Componentes gráficos são embutidos da seguinte maneira: chamemos o componente que 
queremos embutir de componente filho (child component). Aqueles componentes do Swing 
capazes de embutir outros possuem um método add (adicionar). Então, para embutir um 
componente filho (childComp) em um componente pai (parentComp), a sintaxe utilizada é: 
parentComp.add(childComp) 
 11 
Vamos agora especificar como os componentes são acomodados no painel de conteúdo. A fim de 
ser uma plataforma independente, os projetistas do Java deram alguma flexibilidade ao sistema 
gráfico. O programador apenas especifica a estrutura de arranjo dos componentes, não suas 
posições absolutas. Por exemplo, especifica-se que “o componente A está à direita do 
componente B” ao invés de definir que “o componente A está na posição (x, y)”. Em tempo de 
execução, as posições dos componentes é que são determinadas. Isto é feito pelo chamado 
layout manager (gerenciador de leiaute) que está associado ao componente pai. Existem 
diferentes gerenciadores de leiaute pré-definidos e o programador pode definir os seus próprios. 
Um JFrame possui por padrão um BorderLayout; mais precisamente o painel de conteúdo 
possui um gerenciador de leiaute do tipo BorderLayout. Ele permite que o usuário posicione um 
(grande) componente central e até quatro componentes nas bordas. As posições são 
determinadas pelas constantes CENTER, NORTH, SOUTH, EAST e WEST. Estas constantes estão 
definidas na classe BorderLayout. Se um componente de borda não estiver presente, então o 
componente central expande-se naquela direção. O componente central geralmente contém a 
informação principal. Os componentes de borda contêminformações extras. Para inserir um 
componente filho (childComp) dentro do painel de conteúdo na posição pos, usamos o método: 
this.getContentPane().add(childComp, pos) 
Onde pos é uma das seguintes constantes: BorderLayout.CENTER, BorderLayout.NORTH, 
BorderLayout.SOUTH, BorderLayout.EAST ou BorderLayout.WEST. A figura abaixo 
apresenta a distribuição dos componentes ao redor do frame. 
 
 
 
 
 
Vejamos agora mais dois gerenciadores de leiaute: o gerenciador de leiaute por fluxo 
(FlowLayout) e o gerenciador de leiaute por grade (GridLayout). Os leiautes não estão 
restritos a frames. Todo componente Swing no qual outros componentes possam ser embutidos 
(os chamados compartimentos ou containers) possui um leiaute. O leiaute padrão é uma borda. 
Para que se possa alterar o leiaute de um componente pai parentComp para outro leiaute 
newLayout usa-se o comando: 
parentComp.setLayout(newLayout) 
Se um componente tem um leiaute de fluxo então os componentes embutidos são dispostos em 
fila única da esquerda para a direita. Se uma linha estiver completa, a próxima é iniciada. Leiaute 
em linha (normalmente) respeita as dimensões dos componentes embutidos. A ordem de 
chamada do parentComp.add(child) determina a ordem dos componentes embutidos no 
componente pai. A altura de uma linha é determinada em tempo de execução, verificando-se 
CNorth 
CSouth 
CW
e
s
t
 C
E
a
s
t
 
 
CCenter 
 12 
todos os componentes daquela linha, conforme indicado na figura abaixo, onde os componentes 
C3 e C5 é que estão determinando a altura de cada uma das duas linhas presentes no frame. 
 
 
 
 
 
 
A seguir, alguns construtores do FlowLayout: 
FlowLayout() 
FlowLayout(int align) 
FlowLayout(int align, int hdist, int vdist) 
O primeiro construtor gera um leiaute que, por padrão, deixa cinco pixels de distância entre os 
componentes de uma linha e cinco pixels de distância entre linhas. Complementarmente, o 
segundo construtor especifica o tipo de alinhamento dos componentes, onde align é um destes: 
FlowLayout.RIGHT, FlowLayout.LEFT ou FlowLayout.CENTER 
Isto determina quais componentes em cada linha estarão “empacotados” à direita, à esquerda ou 
quais estarão centralizados. O terceiro construtor, além disso, também especifica a distância 
hdist horizontal entre os componentes de uma linha e a distância vdist vertical entre linhas. 
O terceiro gerenciador de leiaute a ser descrito é o GridLayout, que ordena os componentes em 
uma grade. O componente pai (em nosso exemplo, o painel de conteúdo) é dividido em l x c 
células retangulares, onde c é o número de células por linha e l é o número de linhas. Todas as 
células têm o mesmo tamanho. Os componentes ficam embutidos dentro das células em fila única 
da esquerda para a direita. Se houver mais células que componentes embutidos o gerenciador de 
leiaute tentará preencher todas as linhas o mais separado possível e poderá gerar menos que c 
colunas! Se houver menos células que componentes então mais colunas são adicionadas. 
Basicamente o gerenciador de leiaute por grade ignora o número de colunas. A fim de ter um 
número fixo c > 0 de colunas, o número de linhas deve ser ajustado para l = 0 e o número de 
colunas para c. Assim, sempre haverá c colunas e o número de linhas dependerá do número de 
componentes embutidos. A figura abaixo exemplifica o uso do gerenciador de leiaute por grade. 
 
 
 
 
 
 
C3 
C2 C1 
C4 C5 
C3 C2 C1 
C4 C5 Vazio 
 13 
Exercícios de Laboratório do módulo 2 
1. Crie a classe abaixo, referente à representação de um frame principal. Teste os diferentes 
métodos dessa classe no método main, alterando o tamanho do frame, posição na tela e o título. 
Crie mais um método exibeFrame de modo que seja possível também ao programador usuário 
dessa classe alterar as dimensões da janela, que está limitada no construtor a 200 por 200 pixels. 
package br.unip.cc4si4.ALPOO; 
import javax.swing.JFrame; 
 
public class JanelaPrincipal extends JFrame{ 
 public JanelaPrincipal(){ 
 this.setSize(200,200); 
 this.setLocation(200,200); 
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
 } 
 //Torna o frame visivel 
 public void exibeFrame(){ 
 this.setVisible(true); 
 } 
 //Torna o frame visivel e define o texto do titulo 
 public void exibeFrame(String titulo){ 
 this.setTitle(titulo); 
 this.setVisible(true); 
 } 
 //Torna o frame visivel e define o texto do titulo 
 //e a posicao da janela 
 public void exibeFrame(String titulo, int x, int y){ 
 this.setTitle(titulo); 
 this.setLocation(x,y); 
 this.setVisible(true); 
 } 
 //Torna o frame invisivel 
 public void ocultaFrame(){ 
 this.setVisible(false); 
 } 
 //Cria e exibe o frame 
 public static void main(String[] args){ 
 new JanelaPrincipal().exibeFrame("Janela Principal", 150, 150); 
 } 
} 
2. Crie a classe abaixo, referente à representação de um panel. 
package br.unip.cc4si4.ALPOO; 
import java.awt.*; 
import javax.swing.JPanel; 
 
public class PanelColorido extends JPanel{ 
 //Gera um JPanel com cor de fundo cor 
 public PanelColorido(Color cor){ 
 this.setBackground(cor); 
 } 
 //Gera um JPanel com cor de fundo cor, 
 //largura e altura 
 public PanelColorido(Color cor,int largura,int altura){ 
 this.setPreferredSize(new Dimension(largura,altura)); 
 this.setBackground(cor); 
 } 
} 
3. Altere o construtor da classe JanelaPrincipal conforme indicado abaixo e inclua também o 
seguinte import em seu cabeçalho: import java.awt.*; 
public JanelaPrincipal(){ 
 this.setSize(200,200); 
 this.setLocation(200,200); 
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
 PanelColorido PCWest = new PanelColorido(Color.white,50,20); 
 PanelColorido PCEast = new PanelColorido(Color.red); 
 PanelColorido PCNorth = new PanelColorido(Color.yellow); 
 PanelColorido PCSouth = new PanelColorido(Color.green); 
 PanelColorido PCCenter = new PanelColorido(Color.blue); 
 this.getContentPane().add(PCWest,BorderLayout.WEST); 
 this.getContentPane().add(PCEast,BorderLayout.EAST); 
 this.getContentPane().add(PCNorth,BorderLayout.NORTH); 
 14 
 this.getContentPane().add(PCSouth,BorderLayout.SOUTH); 
 this.getContentPane().add(PCCenter,BorderLayout.CENTER); 
} 
Se você quisesse que o programador usuário dessa classe fosse capaz de alterar a cor de fundo, 
que complementação de código seria necessária na classe JanelaPrincipal? 
 
4. Altere novamente o construtor da classe JanelaPrincipal conforme indicado abaixo: 
public JanelaPrincipal(LayoutManager layout){ 
 this.getContentPane().setLayout(layout); 
 this.setSize(200,200); 
 this.setLocation(200,200); 
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
 PanelColorido PC1 = new PanelColorido(Color.red ,30,30); 
 PanelColorido PC2 = new PanelColorido(Color.yellow ,40,20); 
 PanelColorido PC3 = new PanelColorido(Color.green); 
 PanelColorido PC4 = new PanelColorido(Color.blue); 
 PanelColorido PC5 = new PanelColorido(Color.white,80,20); 
 this.getContentPane().add(PC1); 
 this.getContentPane().add(PC2); 
 this.getContentPane().add(PC3); 
 this.getContentPane().add(PC4); 
 this.getContentPane().add(PC5); 
} 
Altere também o método main conforme indicado a seguir: 
public static void main(String[] args){ 
 FlowLayout flowLayout1 = new FlowLayout(); 
 JanelaPrincipal flow1Frame = new JanelaPrincipal(flowLayout1); 
 flow1Frame.exibeFrame("Leiaute por fluxo 1",60,60); 
 FlowLayout flowLayout2 = new FlowLayout(FlowLayout.LEFT,40,30); 
 JanelaPrincipal flow2Frame = new JanelaPrincipal(flowLayout2); 
 flow2Frame.exibeFrame("Leiaute por fluxo 2",300,60); 
 GridLayout gridLayout = new GridLayout(2,4); 
 JanelaPrincipal gridFrame = new JanelaPrincipal(gridLayout); 
 gridFrame.exibeFrame("Leiautepor grade",540,60); 
} 
O que acontece com a distribuição dos componentes embutidos no frame se alterarmos suas 
dimensões de 200 por 200 para 230 por 200 pixels? Porque o construtor recebe como argumento 
um gerenciador de leiaute? Esse construtor poderia ter um gerenciador de leiaute sem precisar 
receber um como argumento? Explique para que serve cada um dos argumentos (se houver) dos 
3 objetos gerenciadores de leiaute criados no método main. 
Módulo 3 – Swing parte 2: Utilização de objetos visualmente 
Labels 
Um label (rótulo) é um componente retangular que exibe texto que não pode ser editado pelo 
usuário (mas pode ser alterado pelo programa). A classe JLabel cria rótulos no Swing. Aqui 
apresentamos dois construtores e alguns métodos: 
public JLabel(String texto) 
public JLabel(ImageIcon imagem) 
 
public String getText() 
public void setText(String texto) 
public void setText(String texto, int alinhamento) 
 15 
public void setForeground(Color cor) 
public void setBackground(Color cor) 
public void setOpaque(boolean b) 
JLabel(String texto) constrói um rótulo que exibe o texto: texto; 
JLabel(ImageIcon imagem) constrói um rótulo que exibe a imagem: imagem; 
getText() devolve o texto atualmente exibido no rótulo como uma String; 
setText(String texto) substitui o texto atualmente exibido no rótulo pelo texto: texto. O 
novo texto é instantaneamente apresentado no rótulo; 
setText(String texto, int alinhamento) substitui o texto atualmente exibido no rótulo 
pelo texto: texto. Ele também ajusta o alinhamento do texto à esquerda, à direita ou ao centro. 
Os valores possíveis para alinhamento são encontrados na classe SwingConstants; por 
exemplo, use SwingConstants.CENTER para centralizar o texto no rótulo; 
setForeground(Color cor) ajusta a cor do texto para cor; 
setBackground(Color cor) ajusta a cor do fundo do rótulo para cor. Note que rótulos são 
transparentes por padrão e suas cores de fundo não são visíveis. De fato, observa-se que a cor 
do componente pai é a que se destaca. Para mudar a cor de fundo de um rótulo primeiro deve-se 
torná-lo opaco usando-se o método setOpaque; 
setOpaque(boolean b) torna o rótulo transparente se b for false e opaco se b for true. 
Buttons 
Buttons (botões) são áreas retangulares, geralmente com uma linha delineando-as, que – tal 
como os rótulos – podem exibir texto. Eles diferem dos rótulos porque podem disparar eventos. 
Um evento ocorre sempre que um botão é pressionado. O sistema em tempo de execução do 
Java monitora botões e reconhece quando um evento desse tipo ocorre. Note que um botão não é 
necessariamente pressionado clicando-o com o mouse, pode haver também um dedo 
pressionando-o em uma tela sensível a toque (as chamadas touch screens). A fim de detectar 
quando um botão é pressionado, alguém fica de olho nele; esse alguém é o listener (observador), 
um componente não gráfico da biblioteca AWT. O observador tem que estar associado ao botão 
para que possa monitorá-lo. Se ocorrer um evento com o botão em tempo de execução, o sistema 
informará o observador, que poderá então analisar o evento e dar início a alguma ação específica. 
A classe JButton representa botões no Swing. Apresentaremos apenas o construtor e o método 
que associa um observador ao botão: 
public JButton(String texto); 
public void addActionListener(ActionListener observador); 
JButton(String texto) constrói um botão que contém o texto: texto; 
addActionListener(ActionListener observador) adiciona um observador que detectará 
eventos ocorridos no botão. 
 16 
Menus 
Menus são normalmente muito utilizados como componentes de frames. Eles estão organizados 
hierarquicamente. O componente mais elevado dessa hierarquia é a barra de menu, uma área 
retangular localizada abaixo da barra de título de um frame e acima do painel de conteúdo. Os 
componentes intermediários são os menus. Um menu aparece como um texto na barra de menu. 
Quando alguém clica em um desses textos, o menu selecionado se descortina, apresentando 
diversos itens de menu, que estão na base da hieraquia. Os itens de menu são componentes que 
disparam eventos. Eles podem ser considerados como um tipo especial de botão. De fato, tal 
como os botões, os itens de menu fazem uso de observadores de eventos para monitorá-los. 
Às vezes é necessário desabilitar determinados itens de menu por algum período de tempo. Um 
item de menu desabilitado não dispara nenhuma ação quando é clicado. Em muitas plataformas o 
texto de um item de menu desabilitado aparece esmaecido em relação aos itens habilitados. A 
barra de menu é representada pela classe JMenuBar: 
JMenuBar() 
add(JMenu menu) 
JMenuBar() constrói uma barra de menu; 
add(JMenu menu) adiciona um menu em uma barra de menu. 
Os menus são adicionados à barra de menu da esquerda para a direita na ordem dos comandos 
add. Para adicionar uma barra de menu em um frame, usamos o seguinte método da classe 
JFrame: 
setJMenuBar(JMenuBar barraDeMenu) 
Note que existem dois métodos distintos: setJMenuBar e setMenuBar para adicionar um 
JMenuBar (usando Swing) e um MenuBar (usando AWT). 
Da classe JMenu precisamos do construtor que recebe o título do menu em uma string e métodos 
para adicionar itens de menu ou separadores, que são linhas horizontais que separam os itens de 
menu em blocos: 
JMenu(String tituloDoMenu) 
add(JMenuItem itemDeMenu) 
addSeparator() 
Em um menu, os itens de menu ou separadores são inseridos do topo para a base na ordem dos 
comandos add. 
Finalmente, da classe JMenuItem necessitamos do construtor que recebe o título do item em 
uma string e um método para associar um observador de eventos ao item de menu. Os itens de 
menu comportam-se de modo muito semelhante aos botões. Em particular, o observador de 
eventos (action listener) é automaticamente informado quando o item é clicado. O observador 
então inicia as ações desejadas. Finalmente precisamos de um método para habilitar ou 
desabilitar um item de menu: 
 17 
JMenuItem(String textoDoItem) 
addActionListener(ActionListener observador) 
setEnabled(boolean b) 
A chamada setEnabled(false) desabilita um item de menu. O item aparece com um texto 
suavizado e qualquer observador associado a ele não é mais notificado cada vez que o item for 
clicado. Assim, um item desabilitado não dispara qualquer reação na aplicação. Chamando 
setEnabled(true) habilitará o item de menu novamente. O texto torna-se bem destacado e os 
observadores associados ao item de menu passam a ser notificados dos eventos. 
Exercícios de Laboratório do módulo 3 
Neste laboratório teremos o primeiro exemplo de uma aplicação GUI real. Real aqui significa que 
teremos um programa que interage com o usuário. A interação é realizada usando botões e itens 
de menu em uma tela gráfica. Apesar de o programa ser muito simples, gostaríamos de introduzir 
o conceito de uma abordagem modelo-visão-controle (model-view-control ou MVC) neste ponto. A 
parte referente ao modelo do programa, não gráfica, lida com o armazenamento, manutenção e 
manipulação de dados. A parte referente à visão exibe os dados e fornece os componentes 
necessários à interação com o usuário, neste caso, botões e menu. A parte referente ao controle, 
também não gráfica, assegura que as ações do usuário resultarão nas respostas desejadas dadas 
pelo programa. A parte de controle é a ponte entre o modelo e a visão. 
A separação em estruturas de modelo, visão e controle geralmente é uma abordagem 
fundamental para o desenvolvimento de uma aplicação rápida e com sucesso. Ela também auxilia 
os programadores iniciantes a melhor reconhecer os conceitos essenciais e suas interconexões. 
Em Java, tal separação é facilmente obtida usando-se orientação a objetos, isto é, diferentes 
classes ou ao menos diferentes métodos para diferentes partes. Em aplicações complexas, 
pacotes separados (com seus conjuntosde classes) podem ser usados para partes diferentes da 
aplicação. 
Vamos então iniciar a especificação da interface gráfica de usuário que queremos representar. 
Queremos montar um contador. Ele está especificado como uma estrutura de dados abstrata. O 
contador possui uma variável chamada valor do tipo inteiro. Inicialmente ela vale zero. O contador 
permite três operações: 
• Incremento – incrementa o valor do contador de 1; 
• Decremento – decrementa o valor do contador de 1; 
• Restauro – reinicia o valor do contador para 0. 
Vamos agora definir a aparência da tela e como ela funcionará. A GUI que temos em mente deve 
exibir o valor atual do contador e permitir que o usuário possa incrementá-lo, decrementá-lo ou 
restaurá-lo. Para esta finalidade teremos três botões. Pressionando o primeiro (incrementar) com 
o mouse, incrementaremos o contador. Pressionando o segundo (decrementar) decrementaremos 
o contador e pressionando o terceiro (restaurar) zeraremos o contador. Estas opções deverão 
 18 
estar disponíveis também no menu. Assim, teremos um menu Opções com os seguintes itens de 
menu: Incrementar, Decrementar e Restaurar. E um segundo menu Programa com o item de 
menu Sair, para finalizar a aplicação. A figura abaixo mostra como queremos que a GUI se 
pareça. 
 
 
 
 
 
 
 
 
 
 
Vamos agora programar um contador em uma classe não gráfica que chamaremos de Contador. 
Esta classe terá apenas uma variável inteira chamada valor que será iniciada em zero no 
construtor, conforme exigido pela especificação. A variável valor é privada, de modo que outras 
classes só possam manipulá-la através dos métodos fornecidos pela classe Contador. 
Representaremos as três operações requeridas na especificação em três métodos com nomes 
óbvios: incrementa(), decrementa() e restaura()e um quarto método, getValor(), para 
ler o conteúdo da variável valor. Abaixo temos a listagem da classe: 
package br.unip.cc4si4.ALPOO; 
 
public class Contador { 
 private int valor; 
 
 //O constructor incia o contador em zero. 
 public Contador() { 
 valor = 0; 
 } 
 public void incrementa(){ 
 valor++; 
 } 
 public void decrementa(){ 
 valor--; 
 } 
 public void restaura(){ 
 valor = 0; 
 } 
 public int getValor(){ 
 return valor; 
 } 
} 
Cuidaremos agora da parte gráfica. Existem muitas maneiras de se arranjar os componentes 
(botões, rótulos e menu). Uma delas seria “colar” os botões, o rótulo e o menu diretamente no 
painel de conteúdo do frame. Utilizaremos aqui uma abordagem diferente: aplicaremos no painel 
de conteúdo do frame um panel intermediário que ficará responsável por embutir os botões, o 
rótulo e o menu. A classe responsável por essa disposição de elementos será chamada 
PainelDoContador. Assim, PainelDoContador é que será colada ao frame. A vantagem 
 
 
 
 
 
Incrementar 
☺ Aplicação 1 x □ _ 
 
 
 
 
Decrementar 
Restaurar 
 
 
Rótulo 
contendo o 
valor do 
contador 
Opções 
Incrementar 
Decrementar 
Restaurar 
Programa 
 19 
desta abordagem é que se pode reutilizar a classe PainelDoContador como um módulo pronto 
em outras aplicações. Reutilização de código, portanto. Veja na figura abaixo a disposição desses 
elementos na aplicação: 
 
 
 
 
 
 
 
 
 
Abaixo, temos a listagem da classe PainelDoContador: 
package br.unip.cc4si4.ALPOO; 
import javax.swing.JMenu; 
import javax.swing.JMenuItem; 
import javax.swing.JPanel; 
import javax.swing.JMenuBar; 
import javax.swing.JButton; 
import javax.swing.JLabel; 
import java.awt.BorderLayout; 
import javax.swing.SwingConstants; 
 
public class PainelDoContador extends JPanel { 
 private Contador contador; 
 private JLabel valorDoLabel; 
 
 public PainelDoContador() { 
 //Cria um objeto contador e define o 
 //gerenciador de leiaute como sendo BorderLayout. 
 contador = new Contador(); 
 BorderLayout bordLay = new BorderLayout(); 
 this.setLayout(bordLay); 
 //Cria uma barra de menu e a adiciona ao panel 
 JMenuBar barraDeMenu = new JMenuBar(); 
 this.add(barraDeMenu,BorderLayout.NORTH); 
 //Cria e adiciona os menus à barra de menu 
 JMenu opcoes = new JMenu("Opções"); 
 JMenu programa = new JMenu("Programa"); 
 barraDeMenu.add(opcoes); 
 barraDeMenu.add(programa); 
 //Cria os itens de menu e os adiciona aos menus 
 JMenuItem incrementar = new JMenuItem("Incrementar"); 
 JMenuItem decrementar = new JMenuItem("Decrementar"); 
 JMenuItem restaurar = new JMenuItem("Restaurar"); 
 JMenuItem sair = new JMenuItem("Sair"); 
 opcoes.add(incrementar); 
 opcoes.add(decrementar); 
 opcoes.addSeparator(); 
 opcoes.add(restaurar); 
 programa.add(sair); 
 //Cria os botões de incrementar, decrementar e restaurar 
 //e cria o rotulo que exibe o valor do contador. 
 JButton botaoIncrementa = new JButton("Incrementar"); 
 JButton botaoDecrementa = new JButton("Decrementar"); 
 JButton botaoRestaura = new JButton("Restaurar"); 
 valorDoLabel = new JLabel(""+contador.getValor(),SwingConstants.CENTER); 
 //Adiciona os botões e o rótulo no panel utilizando as regras 
 //de posicionamento de elementos do gerenciador de objetos BorderLayout. 
 this.add(botaoIncrementa,BorderLayout.WEST); 
 this.add(botaoDecrementa,BorderLayout.EAST); 
 this.add(botaoRestaura,BorderLayout.SOUTH); 
 this.add(valorDoLabel,BorderLayout.CENTER); 
 } 
 public void incrementa(){ 
☺ Aplicação 1 
□ _ x 
Opções Programa 
 
 
Incrementar 
 
 
Decrementar 
Restaurar 
 
 
Rótulo contendo o 
valor do contador 
JFrame 
JPanel 
JMenuBar 
JButton 
JLabel 
 20 
 contador.incrementa(); 
 valorDoLabel.setText(""+contador.getValor()); 
 } 
 public void decrementa(){ 
 contador.decrementar(); 
 valorDoLabel.setText(""+contador.getValor()); 
 } 
 public void restaura(){ 
 contador.restaurar(); 
 valorDoLabel.setText(""+contador.getValor()); 
 } 
} 
E em seguida, a listagem da classe JanelaDoContador, que é o frame responsável por embutir 
o panel PainelDoContador: 
package br.unip.cc4si4.ALPOO; 
import javax.swing.JFrame; 
import java.awt.BorderLayout; 
 
public class JanelaDoContador extends JFrame { 
 public JanelaDoContador(){ 
 //Define o tamanho e a posição do frame na tela 
 this.setSize(300,200); 
 this.setLocation(200,200); 
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
 //Cria e insere um panel do tipo PainelDoContador 
 PainelDoContador pdc = new PainelDoContador(); 
 this.getContentPane().add(pdc,BorderLayout.CENTER); 
 } 
 public void exibeFrame(String title){ 
 this.setTitle(title); 
 this.setVisible(true); 
 } 
 public void ocultaFrame(){ 
 this.setVisible(false); 
 } 
 public static void main(String[] args) { 
 //Cria um objeto frame e o exibe na tela 
 JanelaDoContador jdc = new JanelaDoContador(); 
 jdc.exibeFrame("Aplicação 1"); 
 } 
} 
Se você rodar o programa, observará que ao clicar nos botões ou nos itens de menu nada 
acontece. A conexão entre as ações do usuário (como pressionar um botão) e a aplicação é 
estabelecida pelos observadores (listeners). Estes são componentes não-gráficos fornecidos pela 
biblioteca AWT: java.awt.events.*. Existem diferentes observadores para diferentes tipos de 
eventos (pressionar um botão, mover o mouse, etc.). Observadores são, em geral, interfaces e 
não classes. 
Vamos começar descrevendo como o conceito de um observador normalmente funciona. Alguns 
componentes do Swing são capazes de disparar eventos. Por exemplo, um botão pode ser 
pressionado ou um item de menu pode ser selecionado. Tais eventos são automaticamente 
notificados pelo Java ao sistema em tempo de execução. Agora,o programador pode criar um 
observador e associá-lo ao componente gráfico, digamos um botão. Assim, o observador fica 
aguardando até que o botão seja pressionado e tome as ações necessárias se isto acontecer. O 
sistema em tempo de execução notifica o observador se o botão foi pressionado. A notificação é 
feita chamando-se um método específico do observador. O nome deste método é predefinido na 
interface do observador. O programador tem que caracterizar este método inserindo o código que 
será executado em resposta ao botão que foi pressionado. 
 21 
Em nossa aplicação, o contador tem que ser incrementado ou decrementado em resposta ao 
respectivo botão pressionado. O observador é portanto associado aos três botões, ou seja, ele 
monitora todos. Se um botão for pressionado o observador é avisado. A fim de tomar a ação 
apropriada ele tem que saber qual botão foi pressionado. Esta informação é fornecida pelo 
sistema em tempo de execução na forma de um objeto do tipo ActionEvent. Esta classe 
também se encontra na biblioteca AWT (em java.awt.events). Um objeto do tipo 
ActionEvent contém informação acerca do evento notificado pelo sistema em tempo de 
execução. 
Para este exercício, criaremos um observadores na classe ObservadorPainel. Esta classe 
representa a interface Java ActionListener. A criação da classe requererá ainda a definição 
de um único método actionPerformed (ação executada): 
public void actionPerformed(ActionEvent evento) 
Este é o método chamado pelo sistema em tempo de execução sempre que um botão for 
pressionado ou um item de menu for selecionado. Você não terá que chamar esse método, aliás 
nem deve. O sistema em tempo de execução também gera uma ação evento e a passa como 
um argumento do método actionPerformed. Este código é então executado em resposta ao 
pressionar de um botão. A informação contida na ação evento pode ser utilizada para obter mais 
informações sobre o quê disparou o evento. A listagem abaixo é da classe ObservadorPainel: 
package br.unip.cc4si4.ALPOO; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
 
public class ObservadorPainel implements ActionListener{ 
 private PainelDoContador pdc; 
 public ObservadorPainel(PainelDoContador painel) { 
 pdc = painel; 
 } 
 //Este método é chamado pelo sistema em tempo de execução. 
 //Você deve adicionar o código a ser executado 
 //em resposta ao evento. 
 public void actionPerformed(ActionEvent evento){ 
 //Início do seu código: 
 String actionCommand = evento.getActionCommand(); 
 if(actionCommand.equals("Incrementar")){ 
 pdc.incrementa(); 
 } 
 else if(actionCommand.equals("Decrementar")){ 
 pdc.decrementa(); 
 } 
 else if(actionCommand.equals("Restaurar")){ 
 pdc.restaura(); 
 } 
 else if(actionCommand.equals("Sair")){ 
 System.exit(0); 
 } 
 else{ 
 System.out.println("ERRO: ActionCommand inesperado."); 
 } 
 //Fim do seu código 
 } 
} 
O coração da classe ObservadorPainel é a codificação do método actionPerformed. 
Primeiro, determinamos quais dos botões foi pressionado ou qual dos itens de menu foi 
selecionado. Isto é feito inspecionando-se o objeto de ação evento que o método 
actionPerformed recebeu do sistema em tempo de execução. A linha: 
 22 
String actionCommand = evento.getActionCommand(); 
Extrai o comando da ação do objeto evento. O comando da ação é geralmente o texto do botão 
que foi pressionado ou o texto do item de menu. Em nosso caso ele só pode ser “Incrementar”, 
“Decrementar”, “Restaurar” ou “Sair”. Para verificar qual desses textos foi obtido usamos uma 
estrutura if-then-else. Dependendo do resultado do teste, chamamos o método incrementa(), 
decrementa() ou restaura() do painel, ou ainda finalizamos a aplicação. Neste ponto vemos 
porque ao observador é dada uma referência para um objeto PainelDoContador no construtor 
da classe. O observador, dessa maneira, sabe qual painel ele tem que atuar em resposta ao 
evento. Isto é importante se tivermos diversos painéis em uma aplicação. Para fazer com que o 
painel e o observador se comuniquem, acrescente no construtor da classe PainelDoContador 
as seguintes linhas de código: 
 //Cria os observadores de botao. 
 ObservadorPainel op = new ObservadorPainel(this); 
 botaoIncrementa.addActionListener(op); 
 botaoDecrementa.addActionListener(op); 
 botaoRestaura.addActionListener(op); 
 //Cria os observadores de menu/itens de menu. 
 opcoes.addActionListener(op); 
 incrementar.addActionListener(op); 
 decrementar.addActionListener(op); 
 restaurar.addActionListener(op); 
 sair.addActionListener(op); 
1. Desenhe o diagrama de classes do pacote br.unip.cc4si4.ALPOO, apresentando os 
métodos de cada classe e as relações entre as classes, inclusive as classes da biblioteca Swing 
utilizadas para gerar os diferentes componentes gráficos desta aplicação. 
Módulo 4 – Swing parte 3: Tratamento de eventos 
Caixas de texto 
Caixas de texto apresentam uma única linha de texto. O texto pode ser editado pelo usuário. A 
classe JTextField representa caixas de texto no Java. Para editar um texto, clique dentro da 
caixa de texto e um cursor piscante aparecerá. A caixa de texto automaticamente desloca o 
conteúdo na horizontal se o texto for maior que a caixa. Esta funcionalidade é inerente. Caixas de 
texto são opacas e têm cor de fundo branca e texto preto por padrão. Abaixo, o construtor e 
alguns métodos: 
public JTextField(String texto) 
public String getText() 
public void setText(String texto) 
public void setForeground(Color cor) 
public void setBackground(Color cor) 
JTextField(String texto) constrói uma caixa de texto que exibe texto. 
setText(String texto) substitui o texto atualmente exibido na caixa de texto por texto. 
getText() devolve o texto atualmente exibido na caixa de texto no formato String. 
 23 
setForeground(Color cor) ajusta a cor do texto para cor. 
setBackground(Color cor) ajusta a cor de fundo para cor. 
Botões de rádio 
Botões de rádio são representados usando-se a classe JRadioButton. Um botão de rádio é 
retangular. Ele contém uma área circular à sua esquerda e um rótulo à sua direita. Botões de rádio 
podem ser pressionados bem como podem ser agrupados. Somente um botão de rádio pode ser 
pressionado de cada vez e o botão permanecerá pressionado até que outro botão do grupo o 
seja. Um ponto preto surge dentro da área circular do botão que for selecionado. A seguir, o 
construtor e alguns de seus métodos: 
JRadioButton(String nomeDoBotao) 
setSelected(boolean pressionado) 
setActionCommand(String comando) 
String getActionCommand() 
JRadioButton(String nomeDoBotao) cria um botão rotulado de nomeDoBotao. 
setSelected(boolean pressionado) determina qual botão foi selecionado (pressionado 
= true) ou não (pressionado = false). No primeiro caso o ponto preto fica visível dentro da 
área circular do botão. Este método é utilizado inicialmente para definir qual dos botões estará 
pressionado antes da primeira interação com o usuário. 
setActionCommand(String comando) associa a string comando como uma ação de 
comando para o botão. Botões de rádio não são associados automaticamente a uma ação de 
comando. Isto porque seus rótulos geralmente recebem uma imagem e não um texto. Definimos a 
ação de comando nós mesmos através do método setActionCommand. 
getActionCommand() devolve a ação de comando associada ao botão de rádio. 
Além disso, devemos nos certificar que somente um botão será pressionado de cada vez. Isto é 
conseguido agrupando-se os botões. Usamos para isso a classe ButtonGroup da biblioteca AWT. 
Abaixo listamos o seu construtor e alguns métodos: 
JButtonGroup() 
add(JRadioButton botao) 
String getSelection().getActionCommand() 
JButtonGroup() constrói um grupo de botões mas ainda sem conter nenhum botão.add(JRadioButton botao) adiciona o botão de rádio botao ao grupo. 
String getSelection().getActionCommand() devolve a ação de comando do botão que 
estiver atualmente selecionado dentro do grupo. 
Uma vez os botões dentro de um grupo, somente um de cada vez pode ser pressionado. 
Pressionar um botão não pressionado libera o que estiver pressionado. 
 24 
Botões de seleção 
O botão de seleção pode ser utilizado para indicar conjuntos de opções em que nenhuma, uma, 
várias ou todas as opções são selecionadas. Botões de seleção são representados pela classe 
JCheckBox. Um botão de seleção é retangular e contém uma área quadrada à sua esquerda e 
um rótulo à sua direita. Quando um botão de seleção é pressionado, um sinal de verificação (�) 
surge na área quadrada do botão. A seguir, um de seus construtores: 
JCheckBox(String texto) 
JCheckBox(String texto) constrói um botão de seleção rotulado de texto. 
Exercícios de Laboratório do módulo 4 
1. Construir uma aplicação que contenha um frame, um panel e, dentro deste, uma caixa de texto, 
um botão e dois rótulos. Esta aplicação deve ser capaz de ler uma temperatura em graus Celsius 
fornecida pelo usuário e convertê-la em Farenheit, ao clicar o botão da aplicação. Abaixo, a 
listagem da classe JanelaTemperaturas: 
package br.unip.cc4si4.ALPOO; 
import java.awt.BorderLayout; 
 
import javax.swing.JFrame; 
 
public class JanelaTemperaturas extends JFrame { 
 public JanelaTemperaturas(){ 
 //Define o tamanho e a posição do frame na tela 
 this.setSize(200, 100); 
 this.setLocation(200, 200); 
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
 //Cria e insere um panel do tipo PainelTemperaturas 
 PainelTemperaturas pt = new PainelTemperaturas(); 
 this.getContentPane().add(pt, BorderLayout.CENTER); 
 } 
 public void exibeFrame(String title){ 
 this.setTitle(title); 
 this.setVisible(true); 
 } 
 public static void main(String[] args){ 
 JanelaTemperaturas jt = new JanelaTemperaturas(); 
 jt.exibeFrame("Conversor"); 
 } 
} 
A seguir, a listagem do panel PainelTemperaturas: 
package br.unip.cc4si4.ALPOO; 
import javax.swing.JPanel; 
import javax.swing.JLabel; 
import javax.swing.JButton; 
import javax.swing.JTextField; 
import java.awt.GridLayout; 
 
public class PainelTemperaturas extends JPanel { 
 private JLabel rotuloCelsius, rotuloFarenheit; 
 private JButton botaoConverteTemperatura; 
 private JTextField caixaTextoTemperatura; 
 
 public PainelTemperaturas(){ 
 //Define o gerenciador de leiaute 
 GridLayout gridlayout = new GridLayout(2,2,1,1); 
 this.setLayout(gridlayout); 
 //Cria, na sequência indicada, uma caixa de texto 
 //um rótulo, um botão e outro rótulo 
 caixaTextoTemperatura = new JTextField(); 
 rotuloCelsius = new JLabel("Celsius", JLabel.RIGHT); 
 botaoConverteTemperatura = new JButton("Converter"); 
 rotuloFarenheit = new JLabel("Farenheit", JLabel.RIGHT); 
 //Acrescenta uma dica na caixa de texto e no 
 25 
 //botão para auxílio do usuário 
 caixaTextoTemperatura.setToolTipText("Temperatura em graus Celsius"); 
 botaoConverteTemperatura.setToolTipText("Converte Celsius para Farenheit"); 
 //Exibe os componentes gráficos no painel 
 this.add(caixaTextoTemperatura); 
 this.add(rotuloCelsius); 
 this.add(botaoConverteTemperatura); 
 this.add(rotuloFarenheit); 
 //Insere o observador dos componentes do painel 
 ObservadorPainelTemperaturas opt = new ObservadorPainelTemperaturas(this); 
 //Conecta o observador aos componentes 
 caixaTextoTemperatura.addActionListener(opt); 
 botaoConverteTemperatura.addActionListener(opt); 
 } 
 //Método para leitura do conteúdo da caixa de texto 
 public float leTemperatura(){ 
 try{ 
 float temp = 1.8f*Float.parseFloat(caixaTextoTemperatura.getText()); 
 rotuloFarenheit.setText(temp+" F"); 
 return temp; 
 } catch (NumberFormatException nfe) { 
 rotuloFarenheit.setText("Valor invalido!"); 
 return 0.0f; 
 } 
 } 
} 
E por fim o observador do panel, ObservadorPainelTemperaturas: 
package br.unip.cc4si4.ALPOO; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
 
public class ObservadorPainelTemperaturas implements ActionListener { 
 //Cria um atributo privado do tipo PainelTemperaturas 
 private PainelTemperaturas pt; 
 //Define o construtor da classe que recebe como parâmetro 
 //o painel PainelTemperaturas 
 public ObservadorPainelTemperaturas(PainelTemperaturas painel){ 
 pt = painel; 
 } 
 //Este método é chamado pelo sistema em tempo de execução 
 //Você deve adicionar o código a ser executado em resposta ao evento 
 public void actionPerformed(ActionEvent evento){ 
 //Seu código 
 pt.leTemperatura(); 
 } 
} 
2. Construir uma aplicação que contenha dois grupos de botões: um com botões de verificação e 
outro com botões de rádio. Incluir também dois rótulos que indiquem as opções feitas pelo 
usuário. Utilizar um panel colado ao frame que contenha os dois grupos de botões e seus rótulos. 
Para esta aplicação teremos cinco classes: uma para o frame, duas para os panels e demais 
componentes gráficos e outras duas classes contendo os observadores de eventos, um para cada 
panel. A listagem abaixo apresenta a classe JanelaDeBotoes, que representa o frame: 
package br.unip.cc4si4.ALPOO; 
import javax.swing.JFrame; 
import java.awt.GridLayout; 
 
public class JanelaDeBotoes extends JFrame { 
 public JanelaDeBotoes(){ 
 //Define o tamanho e a posicao do frame na tela 
 this.setSize(200,150); 
 this.setLocation(200,200); 
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
 //Cria e define o gerenciador de leiaute do frame 
 GridLayout gridlayout = new GridLayout(1,2); 
 this.setLayout(gridlayout); 
 //Cria a insere o panel PainelBotaoDeRadio no frame 
 PainelBotaoDeRadio pbdr = new PainelBotaoDeRadio(); 
 this.getContentPane().add(pbdr); 
 //Cria e insere o panel PainelBotaoDeVerificacao no frame 
 PainelBotaoDeVerificacao pbdv = new PainelBotaoDeVerificacao(); 
 this.getContentPane().add(pbdv); 
 26 
 } 
 public void exibeFrame(String titulo){ 
 this.setTitle(titulo); 
 this.setVisible(true); 
 } 
 public void ocultaFrame(){ 
 this.setVisible(false); 
 } 
 public static void main(String[] args){ 
 JanelaDeBotoes jdb = new JanelaDeBotoes(); 
 jdb.exibeFrame("Aplicação 2"); 
 } 
} 
A seguir, a listagem de PainelBotaoDeRadio, que gera um panel que será colado ao frame: 
package br.unip.cc4si4.ALPOO; 
import javax.swing.JPanel; 
import javax.swing.ButtonGroup; 
import javax.swing.JRadioButton; 
import javax.swing.JLabel; 
import java.awt.GridLayout; 
 
public class PainelBotaoDeRadio extends JPanel { 
 private JRadioButton rb[] = new JRadioButton[3]; 
 private JLabel botaoradio = new JLabel("Sem seleção"); 
 
 public PainelBotaoDeRadio(){ 
 //Define o gerenciador de leiaute do panel 
 GridLayout gridleiaute = new GridLayout(4,1); 
 this.setLayout(gridleiaute); 
 //Cria um grupo de botões 
 ButtonGroup bg = new ButtonGroup(); 
 //Cria o observador dos botões de rádio 
 ObservadorDoPainelBotaoDeRadio opbr = new ObservadorDoPainelBotaoDeRadio(this); 
 //Cria e insere os botões de verificação no panel, o grupo de botões 
 //bem como os seus observadores de evento 
 for(int i=0; i<3; i++){ 
 this.add(rb[i] = new JRadioButton("Alternativa "+(i+1))); 
 bg.add(rb[i]); 
 rb[i].addItemListener(opbr); 
 } 
 //Insere o label no panel bem como o seu observador de evento 
 this.add(botaoradio); 
 } 
 //Método para renomear o texto do label: botaoradio 
 public void renomeiaBotaoRadio(String nome){ 
 botaoradio.setText(nome); 
 } 
} 
Agora, a listagem de PainelBotaoDeVerificação: 
package br.unip.cc4si4.ALPOO;import javax.swing.JPanel; 
import javax.swing.JCheckBox; 
import javax.swing.JLabel; 
import java.awt.GridLayout; 
 
public class PainelBotaoDeVerificacao extends JPanel { 
 private JCheckBox cb[] = new JCheckBox[3]; 
 private JLabel botaoverificacao = new JLabel("Sem seleção"); 
 
 public PainelBotaoDeVerificacao(){ 
 //Define o gerenciador de leiaute do panel 
 GridLayout gridleiaute = new GridLayout(4,1); 
 this.setLayout(gridleiaute); 
 //Cria o observador de botões de verificação 
 ObservadorDoPainelBotaoDeVerificacao opbv = new ObservadorDoPainelBotaoDeVerificacao(this); 
 //Cria e insere os botões de verificação no panel 
 //bem como os seus observadores de evento 
 for(int i = 0; i<3; i++){ 
 this.add(cb[i] = new JCheckBox("Alternativa "+(i+1))); 
 cb[i].addItemListener(opbv); 
 } 
 //Insere o label no panel bem como o seu observador de evento 
 this.add(botaoverificacao); 
 } 
 //Método para verificar se um botão foi selecionado 
 public boolean botaoFoiSelecionado(int i){ 
 27 
 if(cb[i].isSelected()) 
 return true; 
 else 
 return false; 
 } 
 //Método para renomear o label botaoverificacao 
 public void renomeiaBotaoVerificacao(String nome){ 
 botaoverificacao.setText(nome); 
 } 
} 
Temos em seguida a listagem do observador ObservadorDoPainelBotaoDeRadio: 
package br.unip.cc4si4.ALPOO; 
import javax.swing.JRadioButton; 
import java.awt.event.ItemListener; 
import java.awt.event.ItemEvent; 
 
public class ObservadorDoPainelBotaoDeRadio implements ItemListener { 
 //Cria um atributo privado do tipo PainelBotaoDeRadio 
 private PainelBotaoDeRadio pbdr; 
 //Define o construtor da classe que recebe como parametro 
 //o painel PainelBotaoDeRadio 
 public ObservadorDoPainelBotaoDeRadio(PainelBotaoDeRadio painel){ 
 pbdr = painel; 
 } 
 //Este metodo e chamado pelo sistema em tempo de execucao 
 //Voce deve adicionar o codigo a ser executado em resposta ao evento 
 public void itemStateChanged(ItemEvent evento){ 
 //Inicio do seu codigo: 
 JRadioButton rb = (JRadioButton)evento.getSource(); 
 String nomeDoBotao = rb.getText(); 
 pbdr.renomeiaBotaoRadio("Selecao: " + nomeDoBotao.charAt(nomeDoBotao.length()-1)); 
 //Fim do seu codigo. 
 } 
} 
Finalmente, a listagem do ObservadorDoPainelBotaoDeVerificacao: 
package br.unip.cc4si4.ALPOO; 
import java.awt.event.ItemListener; 
import java.awt.event.ItemEvent; 
 
public class ObservadorDoPainelBotaoDeVerificacao implements ItemListener { 
 //Cria um atributo privado do tipo PainelBotaoDeVerificacao 
 private PainelBotaoDeVerificacao pbdv; 
 //Define o construtor da classe que recebe como parametro 
 //o painel PainelBotaoDeVerificacao 
 public ObservadorDoPainelBotaoDeVerificacao(PainelBotaoDeVerificacao painel){ 
 pbdv = painel; 
 } 
 //Este metodo e chamado pelo sistema em tempo de execucao 
 //Voce deve adicionar o codigo a ser executado em resposta ao evento 
 public void itemStateChanged(ItemEvent evento){ 
 //Inicio do seu codigo: 
 StringBuffer itens = new StringBuffer("Selecao: "); 
 for(int i=0; i<3; i++){ 
 itens.append(pbdv.botaoFoiSelecionado(i)?(i+1)+" ":""); 
 } 
 pbdv.renomeiaBotaoVerificacao(itens.toString()); 
 //Fim do seu codigo. 
 } 
} 
3. Desafio: construir uma calculadora em Java. A calculadora deve ter: um JTextField onde o 
usuário visualiza os números e as contas; JButtons para cada número e pelo menos as quatro 
operações básicas, além de botões para limpar e corrigir, bem como um JPanel que receberá os 
componentes gráficos e será colado ao frame, criado com um JFrame. Os botões com números 
devem reagir às ações do teclado e somente responder a teclas numéricas, ponto decimal e sinais 
para soma, subtração, divisão e multiplicação. Para isso, deve-se utilizar o observador de eventos 
de teclado: KeyListener e criar uma classe observadora que trate os eventos gerados pelo 
teclado com o KeyEvent. A aplicação pode ser aprimorada com um menu, via JMenu.

Continue navegando