Criação de interfaces gráficas

Modelos
 Interacção por terminal de texto
 Pergunta-resposta fácil de seguir
 Alternativa: criação de uma interface complexa com objectos variados
 Interacção pode ser com vários desses objectos
 Gera-se um evento, ao nível do sistema operativo (tecla, rato, ...), que é passado ao
Java e tratado pela aplicação
 Construir a interface, aguardar eventos e processá-los


Em vez de atitude activa de interrogar cada objecto para saber se tem algum pedido
Os eventos podem ocorrer sem ordem nem momento pre-determinados
 Mais próximo do paradigma de objectos
 Cada objecto trata dos seus eventos
 Fluxo da computação passa mais para as mãos do utilizador
Swing
Criação de GUIs em Java

Biblioteca de classes AWT (Abstract Window Toolkit)
 Fornece todas as classes básicas para a construção de interfaces
 Incluída em todos os sistemas Java no pacote java.awt
 Portável entre plataformas
 Modelo de eventos suportado pelo pacote java.awt.event
 Com problemas de eficiência e aspecto

Biblioteca Swing
 Trabalha sobre a AWT, mas mais eficiente
 Incluída em javax.swing
 Tem mais estruturas para a construção do GUI
 Suporta look-and-feel (Windows, Unix, Macintosh, independente, adaptado)
Swing
Objectos em Swing
Combo box (JComboBox)
Janela (Jframe)
Tela (Jpanel)
Etiqueta (JLabel)
Lista (Jlist)
Campo de texto (JTextField)
desenho
Botão de rádio (JRadioButton)
Grupo de botões (ButtonGroup)
Botão (JButton)
Campo de texto não editável
Caixa de escolha (JCheckBox)
 Apenas se mostram alguns objectos simples; a biblioteca Swing tem muitos mais
Swing
Hierarquia de classes
 Maior parte dos objectos descende
de Component
 Tem posição e tamanho, pode ser
mostrado no ecrã e receber eventos
 Classe abstracta
 Alguns métodos
 void setSize( int width, int height );

Usar antes setPreferredSize;
 void setBackground ( Color c );
 void setFont( Font f );
 void show()

Torna o componente visível
 As classes Font e Color estão
definidas noutra hierarquia, em AWT
(Só se mostra parte da hierarquia)
Swing
Contentores

Container
 Um contentor é um componente que pode conter outros componentes
 É necessário saber-se como dispor os componentes
 Ajudante: posicionador (LayoutManager) associado com
 void setLayout( LayoutManager mgr );
 Depois adicionam-se os componentes por ordem
 void add( Component c ); ou void add( Component c, Object where );

Dois tipos de contentores
 Janelas de topo, até Jframe
 Componente pesado porque interage com o sistema de janelas nativo na máquina
 JComponent e suas subclasses (muitos dos outros componentes)
 Componente leve porque é completamente desenhado numa tela pelo Swing
Swing
Janelas

Tipos de janelas de topo
 JWindow : janela sem caixilho
 JFrame : janela com caixilho que pode ter também um menu (JMenuBar)
 JDialog : janela para criar diálogos
 Uma aplicação deve ter um JFrame ou uma sua subclasse

Não é possível adicionar componentes directamente à janela
 Para deixar ao Swing controlo sobre o posicionamento
 Obtém-se um contentor que representa o conteúdo da janela
 Container getContentPane( );
Swing
Painel

Um painel destina-se a organizar componentes numa unidade de
apresentação
 Podem existir contentores dentro de contentores e painéis dentro de painéis
 É habitual usar uma subclasse de Jpanel para permitir acrescentar código
específico (GUI é uma subclasse de Jpanel)
 GUI implementa a interface ActionListener
 É um atendedor para tratar o evento “carregar no botão”
 Tem que fornecer o método actionPerformed
 Tem que ligar o atendedor ao objecto que pode produzir o evento

theDrawButton.addActionListener( this )
 JPanel herda de JComponent várias funcionalidades, incluindo palpites e
dimensionamento
 void setToolTipText( String txt );
 void setPreferredSize( Dimension d );
Swing
Classe GUI principal
import java.awt.*;
public void actionPerformed( ActionEvent evt )
import javax.swing.*;
{ /* ver a frente*/ }
import java.awt.event.*;
class GUI extends JPanel implements ActionListener
private GUICanvas theCanvas;
{
private JComboBox theShape;
public GUI( )
private JList
theColor;
{
private JTextField theXCoor;
makeTheObjects( );
private JTextField theYCoor;
doTheLayout( );
private JRadioButton smallPic;
theDrawButton.addActionListener( this );
private JRadioButton mediumPic;
}
private JRadioButton largePic;
// Make all the objects
private JCheckBox
private void makeTheObjects( )
private JButton
{ /* ver a frente*/ }
theDrawButton;
private JTextField theMessage;
// Layout all the objects
private void doTheLayout( )
theFillBox;
}
{ /* ver a frente*/ }
Swing
Relacionamento entre classes
JComponent
ActionListener
ActionPerformed
extends
JPanel
implements
extends
GUI
includes
GUICanvas
JComboBox
JList ...
GUICanvas
Swing
Etiquetas e botões

Componente destinado a etiquetas: JLabel
 Normalmente associado a campos de texto, campos combo, listas e paineis,
uma vez que os outros já têm etiqueta própria
 Construção de um objecto etiqueta vazio: JLabel( );
 Construção de um objecto com a etiqueta theLabel: JLabel( String theLabel );
 Alteração da etiqueta no objecto: setText( String theLabel );
 Pode ser usado para mensagens para o utilizador mas habitualmente usa-se campos
de texto não editáveis para esse fim

Um botão (caso de Draw) pode ser visto como uma etiqueta
activa: gera eventos para “click com o botão esquerdo”
 Métodos: JLabel( ); JLabel( String theLabel ); setText( String theLabel );
Swing
Caixas de selecção

Nas caixas de selecção (“combo box”), é possível escolher um objecto de uma
lista pop-up de alternativas, ficando apenas a escolha visível
 No caso de a lista ser editável, pode escrever-se um valor não previsto
 A lista de valores pode ser fornecida na criação do objecto ou ser manipulada
posteriormente
 Criação de caixa de selecção vazia: JComboBox( );
 Idem, com as opções: JComboBox( Object[] choices );
 Acrescentar opção no fim: void addItem( Object item );
 Devolver o objecto correspondente ao item seleccionado: Object getSelectedItem( ); ou
o respectivo número de ordem int getSelectedIndex( );
 Permitir a especificação de um novo valor: void setEditable( boolean edit );
 Indicar o valor seleccionado (ex. por omissão): void setSelectedIndex( int index );
Swing
Listas

O componente JList permite fazer escolhas numa lista de valores
possivelmente com rolamento, se o número de valores exceder o espaço
disponível
 Principais diferenças relativamente à combo box:
 A lista permite, por omissão, selecção múltipla
 A lista deixa ver vários valores simultaneamente
 A lista ocupa maior superfície do ecrã
 Criação de lista vazia: JList( ); ou com os valores: JList( Object[] values );
 Indicar os valores: void setListData( Object[] values );
 Selecção simples, devolver o objecto correspondente: Object getSelectedValue( ); ou o
respectivo número de ordem int getSelectedIndex( );
 Selecção múltipla: Object [] getSelectedValues( ); int[] getSelectedIndices( );
 Escolher
modo
de
selecção
ListSelectionMode.SINGLE_SELECTION);
simples:
void
setSelectionMode(
 Indicar o valor seleccionado: void setSelectedIndex( int index ); void setSelectedValue(
Object value );
Swing
Caixas de marcação e botões de rádio

Estes componentes (JCheckBox e JRadioButton) só têm dois estados: on (true)
e off (false)
 Por isso, têm etiqueta no próprio objecto e podem ser agrupados
 JCheckBox para dizer sim ou não
 JRadioButton para escolher um entre alternativas
 Criação de uma caixa sem etiqueta: JCheckBox( ); com etiqueta: JCheckBox( String
theLabel); com etiqueta e estado inicial: JCheckBox( String theLabel, boolean state);
 Idem para JRadioButton
 Altera a etiqueta: void setLabel( String theLabel );
 Indicar o estado: void setSelected( boolean state);
 Consulta o estado: boolean isSelected ( );

Para criar um grupo de escolha mutuamente exclusiva: ButtonGroup( );
 Não é um componente
 Para adicionar os botões (ou caixas) em causa: void add( AbstractButton b );
Swing
Texto

Um campo de texto JTextField permite escrever uma linha de texto

Para mais do que uma linha, usa-se a área de texto JTextArea
 A tecla Enter funciona aqui como uma mudança de linha e não como um evento do
teclado a significar “fim de entrada de dados”

Métodos
 Campo de texto: JTextField( );
 Idem com indicação do comprimento: JTextField( int cols);
 Idem com valor inicial e comprimento: JTextField( String text, int cols);
 Obter o texto escrito no campo: String getText( );
 Indicar o texto escrito no campo: void setText( String text );
 Indicar se é editável ou não (só para display de mensagens): void setEditable( boolean
editable );
Swing
// Make all the objects
private void makeTheObjects( )
ButtonGroup theSize = new ButtonGroup( );
{
smallPic = new JRadioButton( "Small", false );
theCanvas = new GUICanvas( );
mediumPic = new JRadioButton( "Medium", true );
theCanvas.setBackground( Color.green );
largePic = new JRadioButton( "Large", false );
theCanvas.setPreferredSize(
theSize.add( smallPic );
new Dimension( 100, 100 ) );
theSize.add( mediumPic );
theSize.add( largePic );
theShape = new JComboBox(
new String [ ] { "Circle", "Square" } );
theFillBox = new JCheckBox( "Fill" );
theFillBox.setSelected( false );
theColor = new JList(
new String [ ] { "red", "blue" } );
theDrawButton = new JButton( "Draw" );
theColor.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION );
theMessage = new JTextField( 25 );
theColor.setSelectedIndex( 0 ); // make red default
theXCoor = new JTextField( 3 );
theMessage.setEditable( false );
}
theYCoor = new JTextField( 3 );
Swing
// Layout all the objects
private void doTheLayout( )
{
// Layout the bottom half
JPanel topHalf = new JPanel( );
bottomHalf.setLayout( new FlowLayout( ) );
JPanel bottomHalf = new JPanel( );
bottomHalf.add( smallPic );
bottomHalf.add( mediumPic );
// Layout the top half
bottomHalf.add( largePic );
topHalf.setLayout( new FlowLayout( ) );
bottomHalf.add( theFillBox );
topHalf.add( theCanvas );
bottomHalf.add( theDrawButton );
topHalf.add( new JLabel( "Shape" ) );
bottomHalf.add( theMessage );
topHalf.add( theShape );
topHalf.add( theColor );
// Now layout GUI
topHalf.add( new JLabel( "X coor" ) );
setLayout( new BorderLayout( ) );
topHalf.add( theXCoor );
add( topHalf, "North" );
topHalf.add( new JLabel( "Y coor" ) );
add( bottomHalf, "South" );
topHalf.add( theYCoor );
}
Swing
Telas

Uma tela é uma área rectangular onde se pode desenhar e que
recebe eventos
 Em AWT, usava-se a classe Canvas
 Em Swing, cria-se uma subclasse de JPanel, que permite redefinir o método de
desenhar a interface: void paintComponent( Graphics g );
 g é uma instância da classe abstracta Graphics que o Swing associa ao dispositivo
de visualização

Métodos para desenhar
 void drawOval( int x, int y, int width, int heigth );
 drawRect, fillOval, fillRect; indica canto superior esquerdo e dimensões
 void drawLine( int x1, int y1, int x2 int y2 ); superior esquerdo e inferior direito
 void DrawString( String str, int x, int y );
 void setColor ( Color c );
Swing
Definição da tela
class GUICanvas extends JPanel
public void paintComponent( Graphics g )
{ super.paintComponent( g );
{
if( theColor.equals( "red" ) )
public void setParams( String aShape,
g.setColor( Color.red );
String aColor, int x, int y, int size, boolean fill )
else if( theColor.equals( "blue" ) )
{
g.setColor( Color.blue );
this.theShape = aShape;
this.theColor = aColor;
theWidth = 25 * ( theSize + 1 );
xcoor = x;
if( theShape.equals( "Square" ) )
if( fillOn )
ycoor = y;
g.fillRect( xcoor, ycoor, theWidth, theWidth );
theSize = size;
else
fillOn = fill;
g.drawRect( xcoor, ycoor, theWidth, theWidth );
repaint( );
else if( theShape.equals( "Circle" ) )
}
if( fillOn )
g.fillOval( xcoor, ycoor, theWidth, theWidth );
public void update( Graphics g )
{
else
System.out.println( "Update called" );
g.drawOval( xcoor, ycoor, theWidth, theWidth );
}
}
Swing
Resto da tela
private String theShape = "";
private String theColor = "";
private int xcoor;
private int ycoor;
private int theSize; // 0 = small, 1 = med, 2 =
large
private boolean fillOn;
private int theWidth;
}
Swing
Responder ao evento
public void actionPerformed( ActionEvent evt )
{
try
{
theCanvas.setParams(
(String) theShape.getSelectedItem( ),
(String) theColor.getSelectedValue( ),
Integer.parseInt( theXCoor.getText( ) ),
Integer.parseInt( theYCoor.getText( ) ),
smallPic.isSelected( ) ? 0 :
mediumPic.isSelected( ) ? 1 : 2,
theFillBox.isSelected( ) );
theMessage.setText( "" );
}
catch( NumberFormatException e )
{ theMessage.setText( "Incomplete input" ); }
}
Swing
Adaptadores e classes internas
JFrame
WindowListener
JFrame
windowClosing
windowClosed
windowIconified
windowOpened
...
extends
WindowListener
windowClosing
windowClosed
windowIconified
windowOpened
...
extends
implements
implements
ClosableFrame
ClosableFrame
(classe interior)
• Jframe por si só não
fecha
extends
BasicGUI
• Para ter uma janela que
feche implementa-se o
WindowListener
• Obriga a implementar
muitos métodos vazios
WindowAdapter
extends
• Adaptador implementa todos os métodos
vazios e permite overriding
extends
BasicGUI
• Por não haver herança múltipla, cria-se uma
classe interior (para ter acesso às variáveis de
ClosableFrame) que trata dos eventos
• esta classe pode ser anónima
Swing
Tratamento de eventos
// Class that implements a Window that closes on a window-close event
class CloseableFrame extends JFrame
{
public CloseableFrame( )
{
addWindowListener( new WindowAdapter( )
{
public void windowClosing( WindowEvent event )
{ System.exit( 0 ); }
}
);
}
}
Swing
Classe principal
class BasicGUI extends CloseableFrame
{
public static void main( String [ ] args )
{
JFrame f = new BasicGUI( );
f.setTitle( "GUI Demo" );
Container contentPane = f.getContentPane( );
contentPane.add( new GUI( ) );
f.pack( );
f.show( );
}
}
Swing
Quadro completo
JFrame
JComponent
WindowListener
windowClosing
ActionListener
implements
ActionPerformed
extends
extends
WindowAdapter
JPanel
implements
ClosableFrame
(classe interior)
extends
extends
extends
GUI
includes
GUICanvas
JComboBox
JList ...
extends
GUICanvas
BasicGUI
includes
BasicGUI
(contentPane)
GUI
Swing
Arquitectura MVC

Arquitectura para construção de aplicações OO em que se
separam três dimensões
 Modelo: mantém dados usando os algoritmos apropriados e fornece métodos
de acesso
 Vista: constroi uma representação visual de parte ou todos os dados do modelo
 Controlador: trata os eventos

Quando o modelo altera os seus dados, gera eventos que fazem
com que a vista actualize a sua representação, segundo as ordens
do controlador

Podem existir várias vistas e controladores para o mesmo
modelo, o qual pode permancer inalterado quando este evolui
Swing
Comunicação MVC

Uma alteração no modelo provoca um
evento de alteração que é difundido
para todos os objectos que estão à
escuta desse evento e desencadeia as
alterações
 Facilita manter o sincronismo entre vistas
diferentes de um mesmo modelo
 Actuar numa vista pode provocar
alterações no modelo que são reflectidas
nas outras vistas
actualiza
Vista 1
vê dados
actualiza
vê dados
Vista 2
altera
altera

Modelo
Controlador
altera
No exemplo anterior, o modelo não está
claramente separado da vista (GUI)
 as variáveis estão “misturadas” na tela
GUICanvas
Evento
Swing
Arquitectura MVC em Swing

Um componente Swing leve inclui os seguintes objectos
 Um modelo que mantém os dados (  modelo da MVC básica)
 fornece métodos de acesso
 notifica os listeners quando é alterado
 Um delegado da IU que é uma vista (  vista) com listeners (  controladores)
 combina as duas funções colocando os listeners junto dos objectos controlados
 listeners são habitualmente implementados por classes internas
 Um componente que estende JComponent
 um componente fornece uma API para o programador
 transfere a construção de interfaces para os delegados; passa-lhes os eventos
 torna o modelo transparente para o programador; atravessado pelos métodos

Facilita acopular diferentes estilos de interfaces (look & feel)
 Macintosh, Windows, Motif, Metal
Swing
Comunicação MVC em Swing

Componente
 Faz alterações ao modelo e faz seguir
para o modelo alterações que venham
da interface
 Escutam o modelo para passarem os
eventos para os seus listeners

Listeners do delegado IU
 Tanto escutam o modelo como o
componente
Modelo
actualiza
Delegado IU
actualiza
vê dados
Listeners
altera
altera
actualiza
Componente
altera
 Pedem informação ao modelo
 Alteram o próprio delegado
Evento
Swing
Perspectiva estática de um componente
Bounded
RangeModel
DefaultBounded
RangeModel
JComponent
Component
UI
JSlider
SliderUI
Focus
Handler
Scroll
Listener
Track
Listener
Metal
SliderUI
BasicSliderUI
Windows
SliderUI
Component
Handler
PropertyChange
Handler
Change
Handler
Motif
SliderUI
Swing
Eventos de modelo

Um modelo pode produzir muitos eventos
 Eventos leves: ChangeEvent
 só indicam o objecto fonte do evento
 Ex: posição de uma barra de deslocamento
 ChangeListener
 Eventos com estado
 Transportam os parâmetros tipicamente necessários para o processamento
 Ex: retirar um elemento de uma lista
 PropertyChangeListener
Swing
Download

Component