Rafael Santos
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
1 /122
Apresentao
Curso
Parte 1: Orientao a Objetos e Java Parte 2: IO, Sockets e rede, Threads, Texto, Estruturas de Dados. Parte 3: Interfaces grficas, componentes, aplicaes desktop completas. Rafael Santos: rafael.santos@lac.inpe.br www.lac.inpe.br/~rafael.santos/ Ensino
Instrutor
Material
Metodologia
http://www.lac.inpe.br/~rafael.santos 2 /122
Janeiro/Fevereiro 2010
Metodologia
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
3 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
4 /122
A maioria das IDEs permite a criao de interfaces grficas (aplicaes, applets, dilogos) por composio visual. Realmente til para layouts complexos. importante saber como cdigo relacionado funciona para compreender o que a IDE escreve!
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
5 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
6 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
7 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
8 /122
Modo manual:
Exige conhecimento das classes e APIs. Exige conhecimento de herana e interfaces (de OO). Complicado fazer layout! Seu cdigo. Seu estilo.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
9 /122
O construtor pode ser usado para montar a interface grfica. A prpria classe pode ter um mtodo main que simplesmente cria uma instncia dela mesma. Vrios mtodos para JFrames podem ser executados pela nossa classe. Podemos sobreescrever mtodos com comportamento especfico.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
10 /122
Janeiro/Fevereiro 2010
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
12 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
13 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
14 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
15 /122
Componentes de IU
Customizveis por chamada a mtodos ou herana. Criamos instncias das classes dos componentes. Modificamos atributos destas instncias. Adicionamos estas instncias interface grfica. Registramos eventos que indicam o que fazer se houver interao com o componente.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
16 /122
Adicionando componentes
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
17 /122
Componentes de IU
Layouts.
Para usar um layout, executamos um mtodo para indicar o layout do painel de contedo da aplicao. O layout tambm indica como os componentes sero rearranjados se o tamanho da janela mudar.
http://www.lac.inpe.br/~rafael.santos 18 /122
Janeiro/Fevereiro 2010
Oeste public class ExBorderLayout extends JFrame { public ExBorderLayout() { super("Exemplo de BorderLayout"); Container c = getContentPane(); c.setLayout(new BorderLayout()); c.add(new JLabel("Norte"),BorderLayout.NORTH); c.add(new JLabel("Sul"),BorderLayout.SOUTH); c.add(new JLabel("Leste"),BorderLayout.EAST); c.add(new JLabel("Oeste"),BorderLayout.WEST); JLabel centro = new JLabel("Centro"); centro.setForeground(Color.RED); centro.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); c.add(centro,BorderLayout.CENTER); pack(); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
public static void main(String[] args) { new ExBorderLayout(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
19 /122
C1
C2
Componente 3 Componente 5 C6
C4
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
20 /122
Comp 1 Comp 4 7
Comp 3 Comp 6
public ExGridLayout() Comp { super("Exemplo de GridLayout"); Container c = getContentPane(); c.setLayout(new GridLayout(3,3)); for(int i=1;i<=8;i++) { JLabel l = new JLabel("C"+i); l.setBorder(BorderFactory.createLineBorder(Color.BLUE)); c.add(l); } pack(); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new ExGridLayout(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
21 /122
BoxLayout: permite arranjar componentes em uma nica linha ou coluna. CardLayout: permite empilhar conjuntos de componentes na direo Z. GridBagLayout: permite arranjo de componentes com propores diferentes. SpringLayout: permite arranjar componentes relativamente uns aos outros.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
22 /122
Podemos adicionar uma instncia de JPanel como um componente. Esta instncia de JPanel pode ter seu prprio layout e conter outros componentes.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
23 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
24 /122
Layout nulo
Podemos simplesmente no usar layouts: setLayout(null). Devemos posicionar cada componente manualmente, com coordenadas em pixels. Mtodos teis:
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
25 /122
Layout nulo
import java.awt.*; import javax.swing.*; public class ExLayoutNulo extends JFrame { public ExLayoutNulo() { super("Exemplo de Layout Nulo"); Container c = getContentPane(); c.setLayout(null); JLabel l1 = new JLabel("Label 1"); JLabel l2 = new JLabel("Label 2"); JLabel l3 = new JLabel("Label 3"); l1.setBackground(Color.WHITE); l1.setOpaque(true); l1.setBounds(0,0,100,20); l2.setBackground(Color.YELLOW); l2.setOpaque(true); l2.setBounds(20,20,100,20); l3.setBackground(Color.GREEN); l3.setOpaque(true); l3.setBounds(40,20,100,20); c.add(l1); c.add(l2); c.add(l3); pack(); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new ExLayoutNulo(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
26 /122
Layout nulo
import java.awt.*; import javax.swing.*; public class ExLayoutNulo extends JFrame { public ExLayoutNulo() { super("Exemplo de Layout Nulo"); Container c = getContentPane(); c.setLayout(null); JLabel l1 = new JLabel("Label 1"); JLabel l2 = new JLabel("Label 2"); JLabel l3 = new JLabel("Label 3"); l1.setBackground(Color.WHITE); l1.setOpaque(true); l1.setBounds(0,0,100,20); l2.setBackground(Color.YELLOW); l2.setOpaque(true); l2.setBounds(20,20,100,20); l3.setBackground(Color.GREEN); l3.setOpaque(true); l3.setBounds(40,20,100,20); c.add(l1); c.add(l2); c.add(l3); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(140,40); } public static void main(String[] args) { new ExLayoutNulo(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
27 /122
Layout nulo
import java.awt.*; import javax.swing.*; public class ExLayoutNulo extends JFrame { public ExLayoutNulo() { super("Exemplo de Layout Nulo"); Container c = getContentPane(); c.setLayout(null); JLabel l1 = new JLabel("Label 1"); JLabel l2 = new JLabel("Label 2"); JLabel l3 = new JLabel("Label 3"); l1.setBackground(Color.WHITE); l1.setOpaque(true); l1.setBounds(0,0,100,20); l2.setBackground(Color.YELLOW); l2.setOpaque(true); l2.setBounds(20,20,100,20); l3.setBackground(Color.GREEN); l3.setOpaque(true); l3.setBounds(40,20,100,20); c.add(l1); c.add(l2); c.add(l3); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Insets i = getInsets(); setSize(140+i.left+i.right,40+i.bottom+i.top); } public static void main(String[] args) { new ExLayoutNulo(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
28 /122
Outros componentes
Vimos JLabels. Controles simples como JButton, JComboBox, JList, JMenu, JSlider, JSpinner, JTextField, etc. Controles complexos como JColorChooser, JFileChooser, JTable, JTree. Containers top-level como JApplet, JDialog, JFrame. Outros containers como JPanel, JScrollPane, JSplitPane, JTabbedPane, JInternalFrame. No d para ver exemplos de uso de todos...
http://www.lac.inpe.br/~rafael.santos 29 /122
Janeiro/Fevereiro 2010
Eventos
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
30 /122
Componentes e Eventos
Componentes so realmente teis para interao com usurio. Quando alguma interao for feita com um componente, devemos executar parte do cdigo. Problema com cdigo procedural: interaes podem ocorrer a qualquer momento! Soluo: uso de eventos.
Criamos os componentes, registramos eventos que podem ocorrer, criamos mtodos para processar estes eventos. Existem vrios tipos de eventos...
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
31 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
32 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
33 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
34 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
35 /122
Botes que podem ser combinados em um ButtonGroup. Somente um boto pode ser selecionado.
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ExJRadioButton extends JFrame implements ActionListener { private String[] imagens = {"eclipse01.png","eclipse02.png","eclipse03.png", "eclipse04.png","eclipse05.png","eclipse06.png", "eclipse07.png","eclipse08.png","eclipse09.png",}; private JLabel imagem;
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
36 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
37 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
38 /122
public class ExSliders extends JFrame implements ChangeListener { private JSlider naipe,face; private JLabel carta; public ExSliders() { super("Exemplo de JSliders"); Container c = getContentPane(); criaSliderNaipes(); criaSliderFaces(); JPanel controle = new JPanel(new GridLayout(2,1)); controle.add(naipe); controle.add(face); carta = new JLabel(); carta.setPreferredSize(new Dimension(99+20,134+20)); carta.setHorizontalAlignment(SwingConstants.CENTER); c.add(controle,BorderLayout.SOUTH); c.add(carta,BorderLayout.CENTER); pack(); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
39 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
40 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
42 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
43 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
44 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
45 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
46 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
47 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
48 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
49 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
50 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
51 /122
JInternalFrame e MDI
Podemos ter vrias frames internas em uma mesma aplicao: Multiple Document Interface.
import java.awt.Image; import javax.swing.*; public class ImagemIF extends JInternalFrame { public ImagemIF(String name,float escala,ImageIcon cone) { // Resizable, closable, maximizable e iconifiable. super(name,true,true,true,true); // Vamos mudar a escala da imagem? float width = cone.getIconWidth(); float height = cone.getIconHeight(); width *= escala; height *= escala; cone = new ImageIcon(cone.getImage().getScaledInstance((int)width,(int)height, Image.SCALE_SMOOTH)); // Mostra em um JLabel. getContentPane().add(new JScrollPane(new JLabel(cone))); pack(); setVisible(true); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
52 /122
JInternalFrame e MDI
import import import import import import import java.awt.*; java.awt.event.*; java.awt.image.BufferedImage; java.io.IOException; java.net.*; javax.imageio.ImageIO; javax.swing.*;
public class MostraMultiplasImagens extends JFrame implements ActionListener { private JDesktopPane desktop; private JTextField url; private JComboBox escala; private String[] escalas = {"0.01","0.05","0.1","0.2","0.5","1","2","5","10","20"};
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
53 /122
JInternalFrame e MDI
public MostraMultiplasImagens() { desktop = new JDesktopPane(); JPanel controle = new JPanel(new FlowLayout(FlowLayout.LEFT)); controle.add(new JLabel("URL da Imagem:")); url = new JTextField(50); url.addActionListener(this); url.setText("http://www.lac.inpe.br/~rafael.santos/Java/JAI/datasets/pyramids.jpg"); controle.add(url); controle.add(new JLabel("Escala:")); escala = new JComboBox(escalas); escala.setSelectedIndex(5); controle.add(escala); getContentPane().add(controle,BorderLayout.NORTH); getContentPane().add(desktop,BorderLayout.CENTER); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800,600); setVisible(true); } public static void main(String[] args) { new MostraMultiplasImagens(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
54 /122
JInternalFrame e MDI
public void actionPerformed(ActionEvent e) { BufferedImage imagem = null; boolean carregada = true; try { imagem = ImageIO.read(new URL(url.getText())); } catch (MalformedURLException e1) { JOptionPane.showMessageDialog(this,"Erro na URL: "+url.getText(), "Erro na URL",JOptionPane.ERROR_MESSAGE); carregada = false; } catch (IOException e1) { JOptionPane.showMessageDialog(this,"Erro de IO: "+e1.getMessage(), "Erro de IO",JOptionPane.ERROR_MESSAGE); carregada = false; } if (carregada) { if (imagem == null) JOptionPane.showMessageDialog(this,"No pode ler "+url.getText(), "No pode ler",JOptionPane.ERROR_MESSAGE); else { float usaEscala = Float.parseFloat(escalas[escala.getSelectedIndex()]); ImagemIF i = new ImagemIF(url.getText(),usaEscala,new ImageIcon(imagem)); desktop.add(i); } } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
55 /122
JInternalFrame e MDI
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
56 /122
JInternalFrame e MDI
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
57 /122
Applets
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
58 /122
Applets
Aplicaes com interface grfica que so executadas em um navegador. Mais seguras (para o cliente) do que aplicaes. Menos flexveis do que aplicaes (sandbox). Idia: apresentao de dados que so obtidos do servidor. Tm mtodos que devem ser sobreescritos, em particular:
init(): inicializa a applet. paint(Graphicsg): faz com que a applet seja pintada/desenhada.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
59 /122
Applets
import import import import java.awt.Color; java.awt.Graphics; java.awt.Graphics2D; javax.swing.JApplet;
public class Applet1 extends JApplet { public void paint(Graphics g) { Graphics2D g2d = (Graphics2D)g; g2d.setColor(Color.BLUE); g2d.drawString("Ol, Mundo",5,15); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
60 /122
Applets
import java.awt.*; import javax.swing.JApplet; public class Applet2 extends JApplet { public void paint(Graphics g) { Graphics2D g2d = (Graphics2D)g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(Color.BLUE); g2d.setFont(new Font("SansSerif",Font.ITALIC,24)); g2d.drawString("Texto",5,25); g2d.setFont(new Font("Serif",Font.ITALIC|Font.BOLD,36)); g2d.drawString("Texto",5,65); g2d.setFont(new Font("Dialog",Font.PLAIN,48)); g2d.drawString("Texto",5,115); g2d.setFont(new Font("DialogInput",Font.PLAIN,48)); g2d.drawString("Texto",5,175); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
61 /122
Applets
import import import import java.awt.*; java.util.Hashtable; javax.swing.*; javax.swing.event.*;
public class AppletSliders extends JApplet implements ChangeListener { private JSlider naipe,face; private JLabel carta; public void init() { Container c = getContentPane(); criaSliderNaipes(); criaSliderFaces(); JPanel controle = new JPanel(new GridLayout(2,1)); controle.add(naipe); controle.add(face); carta = new JLabel(); carta.setPreferredSize(new Dimension(99+20,134+20)); carta.setHorizontalAlignment(SwingConstants.CENTER); c.add(controle,BorderLayout.SOUTH); c.add(carta,BorderLayout.CENTER); setSize(200,300); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
62 /122
Applets
private void criaSliderNaipes() { naipe = new JSlider(0,3,0); Hashtable<Integer,JLabel> labels = new Hashtable<Integer,JLabel>(); labels.put(new Integer(0),new JLabel("Paus")); labels.put(new Integer(1),new JLabel("Ouros")); labels.put(new Integer(2),new JLabel("Copas")); labels.put(new Integer(3),new JLabel("Espadas")); naipe.setLabelTable(labels); naipe.setPaintLabels(true); naipe.setPaintTicks(true); naipe.setSnapToTicks(true); naipe.setBorder(BorderFactory.createTitledBorder("Naipe")); naipe.addChangeListener(this); } private void criaSliderFaces() { face = new JSlider(0,12,0); Hashtable<Integer,JLabel> labels = new Hashtable<Integer,JLabel>(); for(int l=2;l<11;l++) labels.put(new Integer(l-1),new JLabel(""+l)); labels.put(new Integer(0),new JLabel("A")); labels.put(new Integer(10),new JLabel("J")); labels.put(new Integer(11),new JLabel("Q")); labels.put(new Integer(12),new JLabel("K")); face.setLabelTable(labels); face.setPaintLabels(true); face.setPaintTicks(true); face.setSnapToTicks(true); face.setBorder(BorderFactory.createTitledBorder("Face")); face.addChangeListener(this); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
63 /122
Applets
public void stateChanged(ChangeEvent e) { String nome = String.format("%d-%02d.png",naipe.getValue()+1,face.getValue()+1); ImageIcon cone = new ImageIcon(nome); carta.setIcon(cone); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
64 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
65 /122
Pode ser necessrio criar novos componentes para exibio ou entrada de informaes especializadas ou para exibir comportamento diferente dos componentes j existentes. Duas abordagens:
Criar componentes que herdam de outros, j existentes. Criar novos componentes a partir de um componente genrico.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
66 /122
import java.awt.*; import javax.swing.JButton; public class JButtonPedra extends JButton { private int tipo; public JButtonPedra() { super(); tipo = 0; } public Dimension getMaximumSize() { return getPreferredSize(); } public Dimension getMinimumSize() { return getPreferredSize(); } public Dimension getPreferredSize() { return new Dimension(40,40); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
67 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
68 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
69 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
70 /122
paintComponent(Graphicsg): sempre! getMaximumSize(),getMinimumSize(), getPreferredSize(): sempre que quisermos impor regras sobre tamanhos.
Usar construtor para passar atributos adicionais. Usar classe/componente j existente quando comportamento for similar.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
71 /122
import java.awt.*; import javax.swing.JComponent; public class BarraProporcional extends JComponent { private int x1,x2; public BarraProporcional(int x1,int x2) { this.x1 = x1; this.x2 = x2; } protected void paintComponent(Graphics g) { float w = getWidth()*x1/(x1+x2); g.setColor(Color.BLUE); g.fillRect(0,0,(int)w,getHeight()); g.setColor(Color.RED); g.fillRect((int)w,0,getWidth(),getHeight()); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
72 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
73 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
74 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
75 /122
Componentes e eventos
public class ComponenteParaRabiscos extends JComponent implements MouseListener, MouseMotionListener { private ArrayList<Point> pontos; private int size = 8; private int halfsize = size/2; private Color cor; public ComponenteParaRabiscos(Color cor) { this.cor = cor; pontos = new ArrayList<Point>(1024); addMouseListener(this); addMouseMotionListener(this); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
76 /122
Componentes e eventos
protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D)g; g2d.setColor(Color.WHITE); g2d.fillRect(0,0,getWidth(),getHeight()); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(cor); for(Point p:pontos) g2d.fillOval(p.x-halfsize,p.y-halfsize,size,size); } public void mousePressed(MouseEvent e) { pontos.add(e.getPoint()); repaint(); } public void mouseDragged(MouseEvent e) { pontos.add(e.getPoint()); repaint(); } public public public public public } void void void void void mouseReleased(MouseEvent e) { } // NOP mouseClicked(MouseEvent e) { } // NOP mouseEntered(MouseEvent e) { } // NOP mouseExited(MouseEvent e) { } // NOP mouseMoved(MouseEvent e) { } // NOP
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
77 /122
Componentes e eventos
import java.awt.*; import javax.swing.*; public class AppletRabiscos extends JApplet { public void init() { ComponenteParaRabiscos c1 = new ComponenteParaRabiscos(Color.RED); c1.setBorder(BorderFactory.createLineBorder(Color.RED)); ComponenteParaRabiscos c2 = new ComponenteParaRabiscos(Color.BLUE); c2.setBorder(BorderFactory.createLineBorder(Color.BLUE)); getContentPane().setLayout(new GridLayout(1,2)); getContentPane().add(c1); getContentPane().add(c2); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
78 /122
Componentes e eventos
public class ComponenteLuzVermelha extends JComponent implements ActionListener { private int nvel,passo; private Timer timer; public ComponenteLuzVermelha(int passo) { this.passo = passo; nvel = 0; timer = new Timer(50,this); timer.setCoalesce(true); timer.start(); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
79 /122
Componentes e eventos
protected void paintComponent(Graphics g) { g.setColor(Color.WHITE); g.fillRect(0,0,getWidth(),getHeight()); // Calculamos a cor de acordo com o passo. g.setColor(new Color(nvel/100,0,0)); g.fillArc(0,0,getWidth(),getHeight(),0,360); } public void actionPerformed(ActionEvent e) { if (nvel < 25500) nvel += passo; repaint(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
80 /122
Componentes e eventos
import java.awt.GridLayout; import javax.swing.JApplet; public class AppletLuzVermelha extends JApplet { public void init() { getContentPane().setLayout(new GridLayout(2,2)); ComponenteLuzVermelha c1,c2,c3,c4; c1 = new ComponenteLuzVermelha(10); c2 = new ComponenteLuzVermelha(50); c3 = new ComponenteLuzVermelha(100); c4 = new ComponenteLuzVermelha(250); getContentPane().add(c1); getContentPane().add(c2); getContentPane().add(c3); getContentPane().add(c4); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
81 /122
Aplicao completa
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
82 /122
Visualizao de Syscalls
Arquivos que listam chamadas feitas por aplicaes ao sistema operacional. Usados em anlise de malware. Grande coleo de arquivos, organizados no formato Famlia/Malware/syscalls.txt
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
83 /122
Visualizao de Syscalls
IntellectualHeaven (R) System Call Tracer for NT, 2K, XP, 2K3. Copyright (C) Pankaj Garg. All rights reserved. Tracing command: ["C:\ANALYSIS\Malware\malware.exe"] [T924] SetLastError(0, 12f2b4, 77f65fa2, 145240, ...) = 7ffdd000 [T924] SetLastError(0, 12f2b4, 77f65fa2, 145268, ...) = 7ffdd000 [T924] SetLastError(0, 12f2b4, 77f65fa2, 145290, ...) = 7ffdd000 [T924] InterlockedIncrement(7e471088, 7e418f9c, 7e418fd7, 1, ...) = 1 [T924] InterlockedDecrement(7e471088, 7e418f9c, 7e418fd7, 1, ...) = 0 [T924] InterlockedIncrement(7e471088, 7e418f9c, 7e419f41, 7e419f06, ...) = 1 [T924] InterlockedDecrement(7e471088, 7e418f9c, 7e419f41, 7e419f06, ...) = 0 .... (aprox. 41000 linhas)
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
84 /122
Visualizao de Syscalls
Criar mecanismo que leia um arquivo de syscalls e calcule estatsticas e parmetros do mesmo. Criar componente grfico que represente esta abstrao dos arquivos de syscalls. Criar aplicao que visualize os componentes/syscalls.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
85 /122
Visualizao de Syscalls
Verso simples: calcula o ndice discreto de cada chamada a syscall, sem os parmetros.
IntellectualHeaven (R) System Call Tracer for NT, 2K, XP, 2K3. Copyright (C) Pankaj Garg. All rights reserved. 1 1 1 2 3 2 3 Tracing command: ["C:\ANALYSIS\Malware\malware.exe"] [T924] SetLastError(0, 12f2b4, 77f65fa2, 145240, ...) = 7ffdd000 [T924] SetLastError(0, 12f2b4, 77f65fa2, 145268, ...) = 7ffdd000 [T924] SetLastError(0, 12f2b4, 77f65fa2, 145290, ...) = 7ffdd000 [T924] InterlockedIncrement(7e471088, 7e418f9c, 7e418fd7, 1, ...) = 1 [T924] InterlockedDecrement(7e471088, 7e418f9c, 7e418fd7, 1, ...) = 0 [T924] InterlockedIncrement(7e471088, 7e418f9c, 7e419f41, 7e419f06, ...) = 1 [T924] InterlockedDecrement(7e471088, 7e418f9c, 7e419f41, 7e419f06, ...) = 0 .... (aprox. 41000 linhas)
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
86 /122
Visualizao de Syscalls
ndice discreto: precisamos de um mapa que ser geral para todas os arquivos de syscalls. Quando passamos uma String:
Se ela for conhecida, retorna o ndice da String. Se no, coloca no mapa e retorna o novo ndice.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
87 /122
Visualizao de Syscalls
package vizsyscalls; import java.util.HashMap; public class BaseDeSyscalls { private HashMap<String,Integer> base; public BaseDeSyscalls() { base = new HashMap<String, Integer>(); } public int cataloga(String syscall) { // J existe a chamada? if (base.containsKey(syscall)) return base.get(syscall); // Se no, temos que adicion-la! else { int ltimo = base.size()+1; base.put(syscall,ltimo); return ltimo; } } public int size() { return base.size(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
88 /122
Visualizao de Syscalls
package vizsyscalls; import java.io.*; import java.util.*; import java.util.regex.*; public class MalwareFile { private boolean existe; private String categoria; private String nome; private ArrayList<Integer> syscallsDiscretizadas; private static BaseDeSyscalls base; public MalwareFile(File baseDir,String c,String n,BaseDeSyscalls database) { categoria = c; nome = n; base = database; File dir = new File(baseDir,c); File subdir = new File(dir,nome); syscallsDiscretizadas = new ArrayList<Integer>(); processaArquivo(new File(subdir,"syscalls.txt")); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
89 /122
Visualizao de Syscalls
Classe MalwareFile.
private void processaArquivo(File file) { existe = file.exists(); try { BufferedReader br = new BufferedReader(new FileReader(file)); String linha; for(int cab=0;cab<5;cab++) linha = br.readLine(); // Pulamos 5 linhas. while(true) // Analisamos o resto. { linha = br.readLine(); if (linha == null) break; else { Pattern p = Pattern.compile("^\\[T[0-9]+\\]"); Matcher m = p.matcher(linha); if (m.find()) { String[] tokens = linha.split("[ \\(\\)]"); String syscall = tokens[1]; int index = base.cataloga(syscall); syscallsDiscretizadas.add(index); } } } br.close();
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
90 /122
Visualizao de Syscalls
Classe MalwareFile.
catch (ArrayIndexOutOfBoundsException e) { System.err.println("Erro procurando syscalls no arquivo "+file); existe = false; } catch (FileNotFoundException e) { System.err.println("Arquivo "+file+" no existe!"); existe = false; } catch (IOException e) { System.err.println("Erro lendo "+file); existe = false; } } public String getCategoria() { return categoria; }
public String getNome() { return nome; } public boolean exists() { return existe; } public String toString() { return categoria+" / "+nome+" : "+syscallsDiscretizadas.size(); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
91 /122
Visualizao de Syscalls
Classe MalwareFile.
// Vrios mtodos que retornam "vises" do que processamos nesta classe. public ArrayList<Integer> getSyscalls() { return syscallsDiscretizadas; } public float[] getContadores() { float[] acum = new float[base.size()]; for(int i:syscallsDiscretizadas) acum[i-1]++; return acum; } public float[] getPropores() { float[] prop = getContadores(); for(int i=0;i<prop.length;i++) prop[i] = prop[i]/syscallsDiscretizadas.size(); return prop; } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
92 /122
Visualizao de Syscalls
package vizsyscalls; import java.io.File; import java.util.ArrayList; public class App1 { public static void main(String[] args) { BaseDeSyscalls base = new BaseDeSyscalls(); // Cria a lista de Malwares considerando a estrutura do diretrios. ArrayList<MalwareFile> listaDeMalwares = new ArrayList<MalwareFile>(); File baseDir = new File(args[0]); String[] categorias = baseDir.list(); for(String c:categorias) { File subdir = new File(baseDir,c); String[] malwares = subdir.list(); for (String m:malwares) { listaDeMalwares.add(new MalwareFile(baseDir,c,m,base)); } } System.out.println(base.size()); for(MalwareFile s:listaDeMalwares) System.out.println(s+" "+s.exists()); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
93 /122
Visualizao de Syscalls
Arquivo ../Data/Trojan.SDBot/67a66839f746f274a5a997d7b157af21/syscalls.txt no existe! Arquivo ../Data/Trojan.Agent/e7c2edc2b413e2ef9bc29a3584f45356/syscalls.txt no existe! Erro procurando syscalls no arquivo ../Data/Trojan.KillAV/ff86998ed2b0cbcbcd1ad0e9b318ab87/syscalls.txt 539 Trojan.SDBot / 68283f4c2c59e70a96b8997ece41c0d5 : 2252 true Trojan.SDBot / 67a66839f746f274a5a997d7b157af21 : 0 false Trojan.SDBot / 1bcc533cc610257b1800804800fd7803 : 1712 true Trojan.SDBot / 4d55ba404916b31e34aea0018873f6dc : 0 true Trojan.SDBot / cbed16069043a0bf3c92fff9a99cccdc : 1712 true Trojan.SDBot / 7dc73bfa4d78284155dd5101991eeb34 : 0 true Trojan.SDBot / 1fb45b941436fca4b410a67927967778 : 0 true Trojan.VanBot / f037d930fb09e2e4c0db28154d1f4c4f : 243 true Trojan.VanBot / 875a3741efebc3279dd05f05353b5ea6 : 0 true Trojan.VanBot / 6daa9b20832e356c4ad3400023908e6e : 243 true Trojan.VanBot / 524bc0f75c12683f73ce0ceed70faab8 : 243 true Trojan.VanBot / 954a98c971fda498f9d1211f18e75cd7 : 920 true Trojan.VanBot / c67ec9815a48ea5db03d853d855cfbf9 : 243 true
Janeiro/Fevereiro 2010 http://www.lac.inpe.br/~rafael.santos 94 /122
Visualizao de Syscalls
package vizsyscalls; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MalwareFileComponent extends JComponent implements MouseMotionListener { private MalwareFile malware; private float[] prop; public MalwareFileComponent(MalwareFile mf) { malware = mf; prop = malware.getPropores(); if (malware.exists()) setBorder(BorderFactory.createLineBorder(Color.BLUE,3)); else setBorder(BorderFactory.createLineBorder(Color.RED,3)); addMouseMotionListener(this); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
95 /122
Visualizao de Syscalls
Classe MalwareFileComponent.
public Dimension getMaximumSize() { return new Dimension(800,120); } public Dimension getMinimumSize() { return new Dimension(200,30); } public Dimension getPreferredSize() { return new Dimension(400,60); } public void mouseDragged(MouseEvent arg0) { } public void mouseMoved(MouseEvent arg0) { int x = arg0.getX(); int i = (int)(prop.length*x/getWidth()); setToolTipText("pos:"+i+" val:"+String.format("%7.4f",prop[i])); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
96 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
97 /122
package vizsyscalls; import java.awt.*; import java.io.File; import javax.swing.JFrame; public class TestComponent extends JFrame { private static BaseDeSyscalls database = new BaseDeSyscalls(); private static File baseDir = new File("Data"); public TestComponent() { super("Syscalls de Malware"); Container c = getContentPane(); c.setLayout(new GridLayout(3,2,5,5)); // Adiciona alguns componentes baseados em arquivos de syscalls de malware. MalwareFile f1 = new MalwareFile(baseDir,"Trojan.KillAV","54640b8eb9aa593b83d12c92ed99d284",database); MalwareFile f2 = new MalwareFile(baseDir,"Trojan.KillAV","c1975317759121bb4b856e0c04011b7b",database); MalwareFile f3 = new MalwareFile(baseDir,"Trojan.Agent","51a98b7c350b6fdd8b84fbcb7d3041fd",database); MalwareFile f4 = new MalwareFile(baseDir,"Trojan.Agent","d838192c513fc43c91228998a74b54fe",database); MalwareFile f5 = new MalwareFile(baseDir,"Trojan.SDBot","67a66839f746f274a5a997d7b157af21",database); MalwareFile f6 = new MalwareFile(baseDir,"Trojan.VanBot","954a98c971fda498f9d1211f18e75cd7",database);
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
98 /122
Visualizao de Syscalls
Classe TestComponent.
MalwareFileComponent MalwareFileComponent MalwareFileComponent MalwareFileComponent MalwareFileComponent MalwareFileComponent c.add(mf1); c.add(mf4); mf1 mf2 mf3 mf4 mf5 mf6 = = = = = = new new new new new new MalwareFileComponent(f1); MalwareFileComponent(f2); MalwareFileComponent(f3); MalwareFileComponent(f4); MalwareFileComponent(f5); MalwareFileComponent(f6);
c.add(mf2); c.add(mf5);
c.add(mf3); c.add(mf6);
pack(); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { new TestComponent(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
99 /122
Visualizao de Syscalls
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
100 /122
Finalizando...
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
101 /122
Vimos...
Algumas noes de programao com interfaces grficas em Java. Como usar alguns componentes comuns. Como usar eventos em suas aplicaes.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
102 /122
No vimos...
Muita coisa! Formalizao do modelo MVC. Alguns exemplos de componentes para aplicaes de processamento de imagens podem ser vistos em http://www.lac.inpe.br/JIPCookbook e/ou https://jaistuff.dev.java.net
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
103 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
104 /122
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
105 /122
Referncias
Java Tutorial: http://java.sun.com/docs/books/tutorial/index.html Java SE Desktop Articles: http://java.sun.com/javase/technologies/desktop/articles.jsp Filthy Rich Clients, de Chet Haase and Romain Guy
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
106 /122
Extra: Tanques
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
107 /122
Tanques
Primeiros passos em uma simulao muito simples. Tanques podem andar para a frente, modificar a velocidade, girar nos sentidos horrio e anti-horrio. Arena comporta vrios tanques e permite a manipulao dos mesmos atravs do mouse. Aplicao cria instncia da Arena. Arena um componente bastante especfico, Tanque no.
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
108 /122
Classe Tanque
package tanques; import java.awt.*; import java.awt.geom.AffineTransform; public class Tanque { private double x,y; private double ngulo; private double velocidade; private Color cor; private boolean estAtivo; public Tanque(int x,int y,int a,Color c) { this.x = x; this.y = y; ngulo = 90-a; cor = c; velocidade = 0; estAtivo = false; }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
109 /122
Classe Tanque
public void aumentaVelocidade() { velocidade++; } public void giraHorrio(int a) { ngulo += a; } public void giraAntiHorrio(int a) { ngulo -= a; } public void move() { x = x + Math.sin(Math.toRadians(ngulo))*velocidade; y = y - Math.cos(Math.toRadians(ngulo))*velocidade; } public void setEstAtivo(boolean estAtivo) { this.estAtivo = estAtivo; }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
110 /122
Classe Tanque
public void draw(Graphics2D g2d) { // Armazenamos o sistema de coordenadas original. AffineTransform antes = g2d.getTransform(); // Criamos um sistema de coordenadas para o rob. AffineTransform at = new AffineTransform(); at.translate(x,y); at.rotate(Math.toRadians(ngulo)); // Aplicamos o sistema de coordenadas. g2d.transform(at); // Desenhamos o rob na posio 0,0. Primeiro o corpo: g2d.setColor(cor); g2d.fillRect(-10,-12,20,24);
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
111 /122
Classe Tanque
// Agora as esteiras for(int e=-12;e<=8;e+=4) { g2d.setColor(Color.LIGHT_GRAY); g2d.fillRect(-15,e,5,4); g2d.fillRect(10,e,5,4); g2d.setColor(Color.BLACK); g2d.drawRect(-15,e,5,4); g2d.drawRect(10,e,5,4); } // Finalmente o canho. g2d.setColor(Color.LIGHT_GRAY); g2d.fillRect(-3,-25,6,25); g2d.setColor(cor); g2d.drawRect(-3,-25,6,25);
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
112 /122
Classe Tanque
// Se o tanque estiver ativo, desenhamos uma margem nele. if (estAtivo) { g2d.setColor(new Color(120,120,120)); Stroke linha = g2d.getStroke(); g2d.setStroke(new BasicStroke(1f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,0, new float[]{8},0)); g2d.drawRect(-24,-32,48,55); g2d.setStroke(linha); } // Aplicamos o sistema de coordenadas original. g2d.setTransform(antes); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
113 /122
Classe Tanque
public Shape getRectEnvolvente() { AffineTransform at = new AffineTransform(); at.translate(x,y); at.rotate(Math.toRadians(ngulo)); Rectangle rect = new Rectangle(-24,-32,48,55); return at.createTransformedShape(rect); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
114 /122
Classe Arena
package tanques; import import import import java.awt.*; java.awt.event.*; java.util.HashSet; javax.swing.*;
public class Arena extends JComponent implements MouseListener, ActionListener { private int w,h; private HashSet<Tanque> tanques; private Timer timer; public Arena(int w,int h) { this.w = w; this.h = h; tanques = new HashSet<Tanque>(); addMouseListener(this); timer = new Timer(500,this); timer.start(); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
115 /122
Classe Arena
public void adicionaTanque(Tanque t) { tanques.add(t); } public Dimension getMaximumSize() { return getPreferredSize(); } public Dimension getMinimumSize() { return getPreferredSize(); } public Dimension getPreferredSize() { return new Dimension(w,h); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
116 /122
Classe Arena
protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D)g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(new Color(245,245,255)); g2d.fillRect(0,0,w,h); g2d.setColor(new Color(220,220,220)); for(int _w=0;_w<=w;_w+=20) g2d.drawLine(_w,0,_w,h); for(int _h=0;_h<=h;_h+=20) g2d.drawLine(0,_h,w,_h); // Desenhamos todos os tanques for(Tanque t:tanques) t.draw(g2d); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
117 /122
Classe Arena
public void mouseClicked(MouseEvent e) { for(Tanque t:tanques) t.setEstAtivo(false); for(Tanque t:tanques) { boolean clicado = t.getRectEnvolvente().contains(e.getX(),e.getY()); if (clicado) { t.setEstAtivo(true); switch(e.getButton()) { case MouseEvent.BUTTON1: t.giraAntiHorrio(3); break; case MouseEvent.BUTTON2: t.aumentaVelocidade(); break; case MouseEvent.BUTTON3: t.giraHorrio(3); break; } break; } } repaint(); }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
118 /122
Classe Arena
public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void actionPerformed(ActionEvent e) { for(Tanque t:tanques) t.move(); repaint(); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
119 /122
Classe App
package tanques; import java.awt.Color; import javax.swing.JFrame; public class App { public static void main(String[] args) { Arena arena = new Arena(600,400); arena.adicionaTanque(new Tanque(100,200, 0,Color.BLUE)); arena.adicionaTanque(new Tanque(200,200, 45,Color.RED)); arena.adicionaTanque(new Tanque(470,360, 90,Color.GREEN)); arena.adicionaTanque(new Tanque(450, 50,157,Color.YELLOW)); JFrame f = new JFrame("Tanques"); f.getContentPane().add(arena); f.pack(); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
120 /122
Tanques
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
121 /122
Tanques
Janeiro/Fevereiro 2010
http://www.lac.inpe.br/~rafael.santos
122 /122