16
Curso de Java – Módulo I Exceções, Entrada e Saída Programação Swing Fábio Mengue – [email protected] Centro de Computação - Unicamp Exceções O termo exception é uma abreviatura da frase “exceptional event”. Sua definição formal é um evento que ocorre durante a execução de um programa que quebra o fluxo normal dessa execução. Vários eventos podem causar exceções. Desde problemas sérios com hardware (como um crash de disco) até um erro simples de programação, como acessar um elemento de um vetor com um índice inválido. Quando um erro desses tipos ocorrem em um método Java, o método cria um objeto do tipo Exception e o envia para o sistema. Esse objeto contém informação sobre o erro, incluindo seu tipo e o estado em que o programa se encontrava quando o erro aconteceu. O sistema fica responsável por encontrar alguma maneira de lidar corretamente com o erro. Na linguagem usada pelos programadores Java, dizemos que o sistema gerou uma exceção (em inglês, throwed an exception). Depois que o método gerou uma exceção, o sistema tenta encontrar algum código que possa ser utilizado para lidar com a exceção. Os candidatos mais prováveis são os que “chamaram” o método onde o erro aconteceu. Se eles não tiverem condições de lidar com o erro, o sistema continua a seguir a pilha de chamadas, até encontrar o código apropriado. Por sua vez, o código é considerado apropriado para lidar com uma exceção quando o tipo da exceção gerada é o mesmo tipo para o qual ele foi programado. Ao ser encontrado o código correto, o sistema o executa (em inglês, catch the exception). Caso o sistema não consiga identificar um código correto para gerenciar a exceção, o sistema (normalmente representado pelo programa Java) se encerra. Claro que é desnecessário dizer que isso não é exatamente o que gostaríamos que acontecesse na maioria das vezes. Pelo fato de utilizar exceções para gerenciar erros, os programas em java possuem vantagens sobre as linguagens tradicionais. A primeira grande vangatem é poder separar o gerenciamento de erros do código comum. Outra vantagem é a propagação de erros, que permite que se crie uma classe especializada apenas no gerenciamento destes eventos. E por fim, é possível agrupar erros por tipo, tratando-os de uma vez. Veremos exemplos para cada uma das vantagens a seguir. 1

Curso Java I

Embed Size (px)

Citation preview

Page 1: Curso Java I

Curso de Java – Módulo IExceções, Entrada e Saída

Programação SwingFábio Mengue – [email protected] de Computação - Unicamp

ExceçõesO termoexceptioné umaabreviaturadafrase“exceptionalevent”. Suadefiniçãoformalé

um eventoque ocorre durantea execuçãode um programaque quebrao fluxo normal dessaexecução.

Várioseventospodemcausarexceções.Desdeproblemassérioscomhardware(comoumcrashde disco)atéum erro simplesde programação,comoacessarum elementode um vetorcom um índice inválido. Quandoum erro dessestipos ocorremem um métodoJava,o métodocria um objetodo tipo Exceptione o enviaparao sistema.Esseobjetocontéminformaçãosobreo erro, incluindoseutipo e o estadoemqueo programaseencontravaquandoo erro aconteceu.O sistemafica responsávelpor encontraralgumamaneirade lidar corretamentecom o erro.Nalinguagemusadapelos programadoresJava,dizemosque o sistemagerou uma exceção(eminglês, throwed an exception).

Depoisqueo métodogerouumaexceção,o sistematentaencontraralgum códigoquepossaser utilizado para lidar com a exceção.Os candidatosmais prováveis são os que“chamaram”o métodoondeo erro aconteceu.Se elesnão tiverem condiçõesde lidar com oerro,o sistemacontinuaaseguira pilha dechamadas,atéencontraro códigoapropriado.Porsuavez, o códigoé consideradoapropriadoparalidar com umaexceçãoquandoo tipo da exceçãogeradaé o mesmotipo parao qual ele foi programado.Ao serencontradoo códigocorreto,osistema o executa (em inglês, catch the exception).

Casoo sistemanão consigaidentificar um código corretoparagerenciara exceção,osistema(normalmenterepresentadopelo programaJava)seencerra.Claro queé desnecessáriodizer que isso não é exatamente o que gostaríamos que acontecesse na maioria das vezes.

Pelo fato de utilizar exceçõespara gerenciarerros, os programasem java possuemvantagenssobre as linguagenstradicionais.A primeira grandevangatemé poder separarogerenciamentodeerrosdo códigocomum.Outravantagemé a propagaçãodeerros,quepermiteque se crie uma classeespecializadaapenasno gerenciamentodesteseventos.E por fim, épossívelagruparerrospor tipo, tratando-osde umavez. Veremosexemplosparacadaumadasvantagens a seguir.

1

Page 2: Curso Java I

Nas linguagensde programaçãotradicionais,a detecçãode erros e seu tratamentonormalmentecausauma certa confusãono código, pois tudo está misturado.Por exemplo,imaginequevocêtenhaumafunçãoqueleia um arquivodo discoparaa memória.Imaginequeesse programa se parece com isso:

lerArquivo{abrir o arquivo;determinar seu tamanho;alocar memória;ler o arquivo para a memória;fechar o arquivo;

}

Parece muito simples. Mas o que acontece se:

� O arquivo não puder ser aberto ?� For impossível determinar o tamanho do arquivo ?� Não for possível alocar a quantidade total de memória ?� A leitura falhar ?� O arquivo não puder ser fechado ?

Então,criamoscódigo a mais para detectare lidar com essespossíveiserros.Assim,nosso programa agora ficaria assim:

lerArquivo {codigoErro=0;abrir arquivo;if (arquivoAberto) {

determinar tamanho;if (tamanhoDeterminado) {

alocar memória;if (memoriaAlocada) {

ler o arquivo para a memória;if (leituraFalhou) {

codigoErro=-1;} else {

codigoErro=-2; }

} else {codigoErro=-3;

}fechar arquivo;if (arquivoNaoFechado) && codigoErro=0) {

codigoErro=-4;}

2

Page 3: Curso Java I

}}

Destamaneira,seuprogramacom 7 linhas ficou praticamente3 vezesmaior. O pior équeo códigoa maistornao programaum tanto ilegível, e a lógica seperdeno meio dosif's eelse's,dificultandoa identificaçãode quaispedaçosdo códigoestãorealmentefazendopartedalinha deraciocíniodesteprograma. Depoisdealgumasmanutenções,o códigodeveficar aindapior de ler, e os programadoresgeralmenteirão resolvero problemasimplesmenteignorandoaprevenção aos erros; eles irão aparecer quando o programa “der pau”.

A soluçaõencontradapeloJavaé maiselegante.O programadorirá escrevero programade maneirausual, mas o tratamentode erros estaráseparado.Se sua função for reescritaàmaneira Java, ficaria assim:

lerArquivo {try {

abrir arquivo;determinar tamanho;alocar memória;ler o arquivo para memória;fechar arquivo;

} catch (falhaAberturaArquivo) {Código de tratamento

}} catch (falhaDeterminarTamanho) {

Código de tratamento}} catch (falhaAlocacaoMemoria) {

Código de tratamento}} catch (falhaLeitura) {

Código de tratamento}} catch (falhaFechamentoArquivo) {

Código de tratamento}

}

Note que o trabalhode criar código paragerenciaro erro continua.O que temosé aseparaçãodos detalhesdo que fazer quandoalgo acontece.O Javaautomaticamenteexecutaapenaso códigoqueserelacionacomo erro,tornandodesnecessáriaa construçãodecadeiasif-elseparagerenciaroserros.O programatambémfica maior,masmaislegivel e aindasim menordo que na abordagem tradicional.

A segundavantagemque existena utilizaçãode exceçõesé a habilidadede propagarerros. Suponhaque nossafunção lerArquivo é o quarto método em uma série de métodos

3

Page 4: Curso Java I

implementadosem sua classe. O metodo1 chama o metodo2, que chama metodo3, quefinalmente chama lerArquivo.

metodo1 {call method2;

}metodo2 {

call method3;}metodo3 {

call lerArquivo;}

Suponhaque o código em metodo1seja o único interessadonos erros que podemacontecerem lerArquivo. Se isso fosse ser implementadousandoa notificação tradicional,metodo3 e metodo2 deveriam ter maneiras de propagar códigos de erro eventualmenteretornados por lerArquivo para os métodos que os invocaram, até chegar a metodo1.

metodo1 { errorCodeType error; error = call metodo2; if (error) doErrorProcessing; else proceed;}errorCodeType metodo2 { errorCodeType error; error = call metodo3; if (error) return error; else proceed;}errorCodeType metodo3 { errorCodeType error; error = call lerArquivo; if (error) return error; else proceed;}

4

Page 5: Curso Java I

Comojá visto, o sistemaJavairá procurarautomaticamenteum códigoadequadoparaogerenciamentodeerros.Usamosentãoumapalavraqueindicaquequalquerexceçãoocorrida(enão tratada) deve ter propagada para a classe que “chamou” a classe corrente. Veja o exemplo:

metodo1 { try { call metodo2; } catch (Exception) { doErrorProcessing; }}metodo2 throws Exception { call metodo3;}metodo3 throws Exception { call lerArquivo;}

Entretanto,comopodeservisto no código,o enviodasexceçõesexigeum certoesforçodos métodosintermediários,que tambémnecessitamrepassara exceçãocom throws até ométodocorreto.Mesmoassim,essatécnicaobviamenteé mais vantajosaquea tradicional,nosentido que evita confusão no código.

A última mas não menosimportantevantagemé que as exceçõessão agrupadas.Porexemplo,imagineum grupode exceções.Todaselasdizemrespeitoa errosquepodemocorrerquandosemanipulaum vetor.Exceçãoparaestourodo vetor,parainclusãode tipo inválido, oumesmoparaquandoo elementoprocuradonão faz partedo vetor. Cadauma dessasexceçõespode ser tratadade maneiraindependente,ou você pode ter um método que trate todasasexceções deste grupo, tornando a coisa mais simples.

Pelofato dasexceçõesseremclassesJavacomoqualqueroutra,a hierarquiapresenteemtodasasclassesJavatambémestápresenteaqui. Todaselassãoinstânciasou descendentesdaclasseThrowable. Cada“folha” da árvorequese inicia em Throwable representaumaexceçãoespecífica, e cada “tronco” representa um grupo relacionado de exceções.

Porexemplo,ArrayException é umasubclassedeException (por suavez,umasubclassede Throwable), e possui 3 subclasses:InvalidIndexException, ElementTypeException,NoSuchElementException. Cadaumadelasrepresentaum erro específico,quepodeocorrernamanipulação de um vetor. Uma maneira de lidar com as exceções é uma a uma:

catch (InvalidIndexException e) { . . .}

Outramaneiraseriatratandoa exceçãodeacordocomo grupoaoqualelapertence.Issopode ser feito por vários motivos, o mais forte deles é manter a simpliciadade.No nossoexemplo, temos ArrayException, que representaqualquer erro que pode acontecercom a

5

Page 6: Curso Java I

manipulaçãode um vetor. Assim, um métodopode lidar com uma exceçãobaseadaem suahierarquia. Por exemplo:

catch (ArrayException e) { . . .}

Estemétodolida com todasasexceçõesquedizemrespeitoa vetores.É possívelsaberqual a exceçãoatravésde uma perguntaao objeto e, recebidocomo parâmetro.Tambémépossível definir um método que lida com qualquer exceção que chegar até ele, como no exemplo:

catch (Exception e) { . . .}

Seu primeiro encontro com exceções Java.

Veja a mensagemde erro abaixo.Ela é geradapois a classeque estamoscompilandocontém chamadas a métodos que lançam exceções quando um erro acontece.

InputFile.java:8: Warning: Exception java.io.FileNotFoundException must be caught, or it must be declared in throws clause of this method. in = new FileReader(filename); ^

A linguagemJavaexige que os métodoscapturemou especifiquemo lançamentodeexceçõesque podemacontecerdentrodaqueleescopo.Se o compiladoridentifica que aquelepedaçode código nãopossuicódigoadequadoparao tratamentode exceções,a mensagemdeerro acima é apresentada e o programa simplesmente não é compilado.

Vamos ver o código do programa InputFile.java e verificar a causa do erro.

import java.io.*;

public class InputFile {

private FileReader in;

public InputFile(String filename) { in = new FileReader(filename); }

public String getWord() { int c; StringBuffer buf = new StringBuffer();

6

Page 7: Curso Java I

do { c = in.read(); if (Character.isWhitespace((char)c)) return buf.toString(); else buf.append((char)c); } while (c != -1);

return buf.toString(); } }

O compilador apresentao erro na linha 8 (in = new FileReader(filename);).Essainstruçãocria um objeto FileReader,usadoparaabrir um arquivo cujo nomeé passadocomoparâmetro.

O que acontecese o arquivo não existir no disco ? Os profissionaisquedesenharamaclasseFileReadernãotinhama menoridéiado queo programadorgostariaqueacontecessecasoo arquivo não existisse.O programadeveterminar? Um nomede arquivo diferentedevesertestado? O arquivo deveser criado? Não existejeito de sabero queo programadorqueestáutilizandoo FileReadergostariaqueacontecessenessasituação.Assim,elesgeramumaexceção(do tipo java.io.FileNotFoundException). Assim, o métodoque chamoua instruçãodecideamaneira apropriada de tratar do assunto.

No nossoexemplo,podese ver queo programa ignorao fato de queFileReaderpodegerarumaexceção.Maso compiladorJavanãodeixaqueo fatopasseembranco,serecusandoacompilar o programa e gerando uma mensagem de erro que alerta o programador a respeito.

Além da mensagem vista acima, outra mensagem deve ser gerada:

InputFile.java:15: Warning: Exception java.io.IOException must be caught, or it must be declared in throws clause of this method. while ((c = in.read()) != -1) { ^

Agora, o problemaestáno objetoin, quedaclasseFileReader.O métodoread()tambémpodegerarumaexceção,destavezcasoalgumproblemaaconteçanaleitura.Porexemplo,seaspermissõesdo arquivo não estejamconfiguradasde modo que esseprogramapossaler seusdados. A exceção gerada pode esse método é java.io.IOException.

Nesseponto,você tem duasopções.Ou podecriar o códigoparacapturaras exceçõesdentro do programaInputFile ou propaga-laspara outros métodosmais acima na pilha deexecução.De qualquermaneira,o programaInputFiledevefazeralgumacoisa.E parafazerissoexiste uma maneira correta.

7

Page 8: Curso Java I

O Bloco try

O primeiro passoparaconstruirum programacapazde gerenciarexceçõesé colocaroscomandosquepodemgerarexceçõesdentrodeum mesmocontexto,usandoa palavrareservadatry:

try { Comandos... }

Você podecolocarcadaum dos comandosem um contextopróprio, ou podecolocartodos os comandosque podem gerar exceçãoem apenasum contexto e depois programar(separadamente) o código que irá lidar com cada uma das exceções.

Por exemplo:

PrintWriter out = null; try { out = new PrintWriter( new FileWriter("OutFile.txt"));

for (int i = 0; i < size; i++) out.println("Value at: " + i + " = " + victor.elementAt(i)); }

O bloco try nesteprograma delimita o escoposobreo qual o códigode tratamentodeerrosirá atuar.Nessepedaçodecódigoexistemduasinstruçõesquepodemgerarexceções;vocêconsegue identifica-las ?

Uma instrução try deve ser acompanha de pelo menos um bloco catch.

O Bloco catch

A instruçãocatch definequal o código que irá ser executado,dependendoda exceçãogerada. Você os associa aos blocos definidos pelo try colocando-os logo após o bloco:

try { . . . } catch ( . . . ) { . . . } catch ( . . . ) { . . . } . . .

Não se deveter nenhumaoutra instruçãoentreo final do contextodo try e o início docatch.

8

Page 9: Curso Java I

A forma geral do catch é:

catch (SomeThrowableObject variavel) { Comandos... }

Note que ele é muito parecidocom um método.Todo bloco catch identifica o tipo deexceçãoque ele trata (SomeThrowableObjet,que é o nome da classe-filhode Throwable) erecebe como parâmetro a exceção recebida.

Essaexceção,como tudo em Java,é um objeto. Sendosubclassede Throwable, esseobjeto herdauma sériede métdos.Um dos mais utilizadosé o getMessage(),que serveparamostrarquala mensagemdeerro.Temosaindamétodosparamostrarapilha deexecuçãoe vocêpode definir ainda suas próprias exceções (basta criar uma classe que extends Throwable).

O bloco catch contémnormalmentecomandoscomunsdo Java.Muitas vezeso blocoservesimplesmentepara imprimir uma mensagemindicandoo erro e parandoo programa.Obloco é executado apenas se a exceção for disparada; os outros blocos catch são ignorados.

Seutilizarmoscomoexemploo códigoapresentadona páginaanterior,podemosdefiniros blocos catch da maneira mostrada abaixo:

try { . . . } catch (ArrayIndexOutOfBoundsException e) { System.err.println("Caught ArrayIndexOutOfBoundsException: " + e.getMessage()); } catch (IOException e) { System.err.println("Caught IOException: " + e.getMessage()); }

O primeiroblocoirá serexecutadoquandofor disparadaumaexceçãodeíndicedo vetor,e o outro quando ocorrer um erro de escrita no arquivo.

A granularidadepermitidaé muito grande,como podemosver. Mas é possíveldefinirapenasalguns(ou mesmoum) blocospara todasas exceções.Criar código diferenciadoparaerrosde acessoa um vetorou errono discopodeserpoucoprodutivo.O Javatema capacidadede agrupar as exceções, baseado na organização hierárquica das mesmas.

Quantomais próximo da classe“folha”, mais específicaé o tratamentoda exceção.Podemos escolher em tratar as classes mais próximas do “tronco” ou mesmo da “raiz”.

Veja a imagem:

9

Page 10: Curso Java I

Assim, podemosreescrevernossoexemplode modo que apenasum bloco catch podelidar com todas as exceções:

try { . . . } catch (Exception e) { System.err.println("Exception caught: " + e.getMessage()); }

A classeException é a maisalta na hierarquiaThrowable. Assim, qualquerexceçãoqueocorrerserátratadapor essebloco.A idéiaemsi é queelebastaparatratardeerrosgerais,maséum tanto inútil paraum tratamentoadequado,perdendoum poucoda vantagemde tratamentoque o Java fornece.

Finalmente, temos o bloco finally.

O Bloco finally

Todo try deveter pelo menosum catch. Existemaisum bloco de códigoquepodeserdefinido, masele nãoé obrigatório.Ele existeparaquesepossarealizarcertasatividadesquedevemser feitas independentementedo curso de execuçãoter geradoexceçõesou não. Umexemplo é fechar um arquivo ou conexão com o banco de dados.

Lembremos novamente de nosso exemplo da página 8. Três casos ocorrer.

1) O FileWriter falha e lança uma IOException.2) O victor.elementAt(i) falha e lança uma ArrayIndexOutOfBoundsException. 3) Tudo dá certo, e nenhuma exceção é gerada.

Certas instruções devem ser executadas para qualquer um dos casos. O bloco finally servejustamenteparaisso.Suasinstruçõesserãoexecutadassempre,com exceçõesou semelas.Suadefinição permite que eliminemos código duplicado e facilita o encerramento de uma rotina.

10

Page 11: Curso Java I

Exercícios:

1. O código abaixo é válido ?

try { ... } finally { ... }

2.Quais as exceções que serão capturadas pelo bloco abaixo ?

catch (Exception e) { ... }

Cite uma desvantagem de usar esse tipo de classe de exceção.

3.Quais as exceções que serão capturadas pelo bloco abaixo ?

... } catch (Exception e) { ... } catch (ArithmeticException a) { ... }

Há alguma coisa errada com esses blocos ? O código compila ?

11

Page 12: Curso Java I

Entrada e saida

As vezesum programanecessitatrazer informaçãode uma fonte externaou enviarinformaçãoparaum destinofora do programa.A informaçãopodeestarem qualquerlugar: umarquivoemdisco,narede,emoutroprograma.A informaçãotambémpodeserdequalquertipo:um objeto, um caracter, uma imagem, um som...

Para lidar com essasinformações,o Javautiliza o conceitode stream. Ele pode serentendidocomosefosseum “tubo”, ondeasinformaçõessãoenviadasem fluxo, quesãolidas(ou escritas). Veja o desenho:

Nãoimportadeondeo dadoestejavindo (ou indo),e nãoimportaseutipo. Osalgoritmosque lidam com streams tratam de maneira sequencial do dados:

abrir o streamenquanto houver informação

ler informaçãofechar o stream

O pacote java.io possui classesque tratam e criam os streams. Basicamente,temosstreams paraleitura de caracterese paraleitura de bytes.Os primeirospossibilitama leitura eescrita de palavras de 16 bits, e são originários da classe abstrata java.io.Reader e java.io.Writer.

12

Page 13: Curso Java I

Os streams para leitura de bytes lidam com palavras de 8 bits, e são subclasses dejava.io.InputStream e java.io.OutputStream.

Os streams mais fáceis de entender são os relacionados a arquivos. Segue um exemplo deprograma que copia um arquivo de um stream para outro.

import java.io.*;

public class Copy { public static void main(String[] args) throws IOException { File inputFile = new File("entrada.txt");

13

Page 14: Curso Java I

File outputFile = new File("saida.txt");

FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c;

while ((c = in.read()) != -1) out.write(c);

in.close(); out.close(); } }

Como podemos ver, o programa é muito simples. Ele abre um FileReader no arquivoentrada.txt e abre um FileWriter no arquivo saida.txt. O programa lê caracteres enquanto houverno stream de entrada e os escreve no stream de saída. Quando terminar, ele fecha ambos osstreams.

O assunto é um tanto extenso, e esse curso se propõe a passar apenas a idéia básica sobreo assunto. Temos capacidade de gerar ou ler streams com arquivos zipados, serializar objetos(artifício utilizado para comunicação remota) e mesmo acessar arquivos de maneira nãosequencial.

Introducao ao Swing

O pacoteSwingé partedaJavaTMFoundationClasses(JFC)naplataformaJava.Existena linguagemcomopacotede extensãodesdea versão1.1,e servebasicamenteparaauxiliar aspessoasa construiremGUI's (GuidedUser Interface).O Swing fornecetodosos componentesbásicos, de botões a tabelas.

Seu primeiro Swing

A maneiramais fácil de ensinara utilizar o Swing mostrandocódigo. Vamos a umprograma bem simples, que exibe “Alo Mundo”.

import javax.swing.*;

public class HelloWorldSwing { public static void main(String[] args) { JFrame frame = new JFrame("HelloWorldSwing"); final JLabel label = new JLabel("Hello World"); frame.getContentPane().add(label);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack();

14

Page 15: Curso Java I

frame.setVisible(true); } }

Estaé a aplicaçãomaissimplesquesepodeescrever.Vamosanalisaro código linha alinha.

Inicialmente, como sempre, importamos os pacotesque iremos utilizar. No caso,javax.swing.*. A outra linha interessanteé a ondese definenossaraiz, ou container. Ele é oelementoprincipal, e ondeiremos“dependurar”tudo quequeremosqueaparecaemnossatela.No nossocaso,eho JFrame. Elepermitequeoutroscomponentessejamadicionadosa ele,e tema capacidadede gerenciareventos.Existemoutros2 containers Swing: JDialoge JApplet(esseúltimo, utilizado apenas para Applets).

CadaobjetoJFrame implementaumaúnicajanelaprincipal,quepossuidecorações.Elassãoa borda,o título e botõesparamaximizar,minimizare fechara janela.UmaaplicaçãoSwingusa normalmente pelo menos um JFrame.

Nossoframe tem um componente.Um label, ondeescrevemos“Alo Mundo”. As duaslinhas de código abaixo constroem e adicionam o componente ao frame:

final JLabel label = new JLabel("Hello World"); frame.getContentPane().add(label);

Parafechara janelaquandoo botãode fecharé clicado,devemosincluir a linha abaixono nosso programa:

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

O comportamentopadrãode um framequandoo botãode fecharé clicadoé esconderajanela, coisa que não desejamos.

A linha ondeconstao métodopack()determinao tamanhodo framede modoquetodosos componentesestejamem um tamanhopadrão.Essemétodoutiliza algumaspropriedadesdosistema para criar e colocar o frame em um tamanho considerado adequado.

A última linha, que chama o método setVisible(), faz com que o frame apareça na tela.

Veja o resultado:

15

Page 16: Curso Java I

Notas sobre o Swing:

Paraaparecerna tela, todosos componentesdevemseradicionadose estarempresentesem alguma parte de hierarquia, que se inicia na raiz (JFrame, JDialog ou JApplet).

Todososcomponentesraiz possuemum content pane, quecontéma partevisível do queestamos montando, como mostrado na figura abaixo:

Opcionalmente,você pode adicionar um menu a um componenteraiz. O menu éposicionado diretamente na raiz, fora do content pane.

Bibliografia

The Java Tutorial – http://www.sun.com/docsCore Java – Horstmann, Cay S., Cornell, Gary. Makron Books

Proibida a alteração, reprodução e cópia de parte deste material para qualquer finalidade sem a permissão do Centrode Computação da Unicamp.

A utilização deste material é permitida desde que conste a autoria do mesmo.

2002 Centro de Computação da Unicamp.

16