Gabarito da 2a Prova de Características das Linguagens de Programação – 1997 – 20 período 1a questão: //****************************************************************************** // Supermercado.java: Applet // //****************************************************************************** 1. import java.applet.*; 2. import java.awt.*; 3. import java.net.*; 4. import CarrinhoPanel; //Panel para mostrar o carrinho de compras // other imports... 5. public class Supermercado extends Applet implements Runnable 6. { // ... some code goes here... A. CarrinhoPanel panelcar; // Panel do carrinho de compras L. Image imgcar; 7. public void init() 8. { // Inicialização do Supermercado Virtual H. panelcar = new CarrinhoPanel(); E. imgcar=getImage(getDocumentBase(),"images/car.gif"); G. setLayout(new BorderLayout()); D. add ("Center", panelcar); C. panelcar.setImage(imgcar); F. resize(300,300); B. show(); 9. } 10. public void destroy() 11. { // Place applet cleanup code here 12. } // Supermercado Paint Handler 13. public void paint(Graphics g) 14. { // Place applet paint code here 15. } 16. public void start() 17. { // Place additional applet start code here 18. } 21. // The stop() method is called when the page containing the applet is // no longer on the screen. public void stop() { // Add additional applet stop code here... } 22. // The run() method is called when the applet's thread is started. If public void run() 19. 20. 23. 24. 25. } { // Some aditional code goes here... } //CarrinhoPanel.java 28. import java.awt.*; // Panel para mostrar o carrinho de compras do supermercado 29. public class CarrinhoPanel extends Panel 30. { 31 Image imgcar; 32. public void setImage(Image img) 33. { J. imgcar = img; K. repaint(); 34. } 35. 36. L. 37. 38. } public void paint(Graphics g) { g.drawImage(imgcar, 0, 0, this); } 2a questão: import java.util; public class Stack extends Vector throws EmptyStackException { //para colocar da pilha public Object push(Object item) { addElement item; return item; } //para retirar um elemento do topo da pilha public ynchronized Object pop() { int len = size(); if (len = 0) throw new EmptyStackException(); return elementAt(len-1); removeElementAt(len-1); } } 3a questão: Trata-se de um applet que implementa um slide show. Há uma imagem que serve de background e, em cima da qual são apresentadas as outras imagens da primeira à última, daí retornando-se à primeira e daí até à última, e assim sucessivamente. Tanto o applet como as imagens (6 arquivos .gif) poderiam estar fisicamente localizadas em um servidor http instalado em um computador Y. O applet começaria a sua execução em uma dada máquina X, quando um browser, em execução na máquina X, efetuasse um acesso a uma página html disponibilizada pelo servidor http instalado em Y, página esta contendo uma referência (<applet code=”ImageBlaster”, p. ex.) ao applet ImageBlaster. Alternativamente a página html, o applet e as imagens gifs poderiam estar disponíveis em um local host (vide o diretório ~oscar/olmf/Java/JavaCode/myexamples em suporte2.eng.uerj.br, arquivos ImageBlaster.html, ImageBlaster.java – o applet – e as imagens em ~oscar/olmf/Java/JavaCode/myexamples/images). O applet inicia a sua execução criando um objeto vetor Image - anim – em que serão armazenadas as imagens correspondentes ao slide show, uma referência a outro objeto Image – bg – em que será armazenada uma imagem de background, uma variável int – index – para controlar a imagem sendo desenhada na tela, uma referência a um objeto Thread –animator – e uma referência a um objeto MediaTracker – tracker – para acompanhar o download dos diversos arquivos .gif.. Anim, bg, index e tracker são variáveis de instância do applet e reconhecidas em todos os métodos do applet ImageBlaster. Quando o applet é apresentado pela primeira vez na janela do browser, o método init() é executado. init() instancia o objeto MediaTracker - tracker – note que o argumento do construtor MediaTraker – this - é o componente em que as imagens serão mostradas, ou seja, o applet. A seguir init() recupera as imagens nas URLs especificadas. Para a imagem que servirá de background para o slide show (url da página html que contém a referência ao applet – getDocumentBase() - concatenada com o endereço relativo da imagem que servirá como background – images/background.gif). Para as imagens que irão compor o slide show (url da página html que contém a referência ao applet – getDocumentBase() - concatenada com o endereço relativo das imagens - images/anim”+i+”.gif – i variando de 0 a 4). Por último init() adiciona os objetos Image à lista de imagens cujo download será acompanhado pelo objeto MediaTracker – tracker – aatravés do método tracker.addImage(). Reparem que no caso da imagem de background o segundo parâmetro que é um id (espécie de flag) é 0 – zero – e no caso das imagens do slideshow o id é 1 – um. O método start() é executado quando o applet é mostrado pela primeira vez na janela do browser. O método stop() será invocado sempre que o browser deixar o documento html que contém a referência ao applet ou quando se faz o scroll do applet na tela. init() também será invocado sempre que o browser retornar ao documento html e assim sucessivamente. No applet ImageBlaster o método start() instanciará o novo thread de execução – animator. O construtor para este novo thread recebeu como parâmetro – this – o que significa que ao iniciarmos este novo thread – animator.start() – será executado o método run() do applet. O método run() encerra o controle da animação. Na cláusula try os métodos tracker.waitForID() fazem que as imagens acompanhadas pelo MediaTracker tracker iniciem o processo de download e esperam – bloqueiam - até que cada uma das imagens tenha sido totalmente carregada, a ocorrência de um erro, ou o processo tenha sido por algum motivo interrompido (aborted). Após todas as imagens estarem disponíveis será executado o comando Thread me = Thread.current.Thread(); isto é, o thread me assume o valor do thread corrente. O while loop interrompe a execução do thread por 100 milisegundos – para que cada imagem possa ser apresentada (Na realidade este tempo é muito curto. Você deve aumentá-lo para 1000 ou 2000 para que você possa ver as diferentes imagens confortavelmente.). Depois há um trecho antecedido pela keyword synchronized, indicando que se trata de uma região crítica – o índice do Image vetor anim não pode ser alterado por dois threads simultâneos. Ainda dentro do while é invocado o método repaint(), que na realidade chama o método update() do applet. update() redesenha o background e então invoca o método paint(). Em geral o método paint() pode ser invocado a qualquer tempo, mas na prática isto ocorre quando o objeto (o applet) torna-se visível pela primeira vez ou quando ele altera a sua aparência. No exemplo, paint() será invocado cada vez que se alterar o índice - index - do Image vetor – anim -. index referencia o objeto Image a ser desenhado na tela, o qual está sempre sendo alterado dentro do while loop. Ainda no corpo do método paint(), dentro do if, é invocado o método tracker.statusAll(true). Este método retorna o status de toda a media acompanhada pelo MediaTracker tracker (true se ainda existir alguma imagem a ser carregada). No if testa-se também a eventual ocorrência de um erro. Caso falte alguma imagem ou tenha ocorrido um erro será desenhado um retângulo vermelho na tela. A seguir será desenhada a imagem de background e finalmente a imagem correspondente a anim[index], desde que todas as imagens do slide show já tenham sido recebidas. 4a questão: Você poderia simplesmente usar o echo client dado em aula e comunicar-se com o servidor de echo na porta 7. Segue-se o código do echo client. import java.net.*; import java.io.*; public class echoClient { public static void main(String[] args) { Socket theSocket; String hostname; DataInputStream theInputStream; DataInputStream userInput; PrintStream theOutputStream; String theLine; if (args.length > 0) { hostname = args[0]; } else { hostname = "localhost"; } try { theSocket = new Socket(hostname, 7); theInputStream = new DataInputStream(theSocket.getInputStream()); theOutputStream = new PrintStream(theSocket.getOutputStream()); userInput = new DataInputStream(System.in); while (true) { theLine = userInput.readLine(); if (theLine.equals(".")) break; theOutputStream.println(theLine); System.out.println(theInputStream.readLine()); } } // end try catch (UnknownHostException e) { System.err.println(e); } catch (IOException e) { System.err.println(e); } } // end main } // end echoClient 5a questão: //****************************************************************************** // Animation.java: // //****************************************************************************** 1. import java.applet.*; 2. import java.awt.*; 3. import java.net.*; //other imports... 4. public class Animation extends Applet implements Runnable 5. { // ... some code goes here... Thread MyAnimation; 6. public void init() 7. { // Inicialização do Applet Animation 8. } 9. public void destroy() 10. { // Place applet cleanup code here 11. } 12. public void start() 13. { // Place additional applet start code here if (MyAnimation == null) { MyAnimation = new Thread (this); MyAnimation.start(); } 14. } 15. public void stop() 16. { // Add additional applet stop code here... if MyAnimation != null) { MyAnimation.stop(); MyAnimation = null; } 17. } //The run() method is called when the applet's thread is started. If 18. public void run() 19. { // Some aditional code goes here... //animation starts While (true) { //Draw frames //... repaint(); } //animation ends 20. } 21 } 6a questão: package exploringjava.threads; import java.awt.*; public class Animation extends UpdateApplet { boolean toggle = true; public void paint( java.awt.Graphics g ) { if (toggle) { g.setColor(Color.red); toggle = false; } else { g.setColor(Color.yellow); toggle = true; } g.fillOval(50, 50, 50, 50); } } 7a questão: Em Java toda a entrada e saída é baseada no conceito de streams. Um stream representa um fluxo de dados, ou um canal de comunicação entre um elemento responsável pela gravação dos dados, em uma extremidade, e um elemento responsável pela leitura dos dados, em outra extremidade. Pode-se acoplar um stream a diferentes repositórios de dados: Strings, Sockets, Files, passando-se um destes objetos como parâmetro para o construtor do Stream. As classes InputStream e OutputStream são classes abstratas que definem a interface de mais baixo nível para todos os streams. Elas possuem métodos para ler e gravar um fluxo não estruturado de dados a nível de byte. Outras classes derivadas de InputStream e OutputStream herdam os seus métodos básicos e acrescentam uma maior funcionalidade aos streams. Em particular, as classes DataInputStream e DataOutputStream são filtered streams (com capacidade de filtrar dados) que nos permitem ler ou gravar em um stream - Strings e tipos de dados primitivos - que são representados por um dado conjunto de bytes (ex. float 32 bits ou 4 bytes). Para isto possuem métodos especiais, cujos nomes já indicam o tipo de operação a ser realizada e em que tipo de dado. O exemplo a seguir ilustra o uso destes métodos. import java.io.*; public class Binario { public static void main(String args[]) { float Input_float, Myfloat = 17E2F; //valor arbitrário int Input_int, Myint = 100; //valor arbitrário String Input_String, MyString = "Java enabled students have been approved"; //valor arbitrário try { FileOutputStream saida = new FileOutputStream("Mydata"); DataOutputStream d_saida = new DataOutputStream(saida); d_saida.writeFloat (Myfloat); d_saida.writeInt (Myint); d_saida.writeUTF(MyString); d_saida.close(); FileInputStream entrada = new FileInputStream("Mydata"); DataInputStream d_entrada = new DataInputStream (entrada); Input_float = d_entrada.readFloat(); Input_int = d_entrada.readInt(); Input_String = d_entrada.readUTF(); System.out.println(Input_float); System.out.println(Input_int); System.out.println(Input_String); d_entrada.close(); } catch (IOException ioe) { System.out.println(ioe); } } }