Java para Crianças: Aprenda Programação
Java para Crianças: Aprenda Programação
[Link] 1/303
22/03/2025, 18:48 Programação Java para crianças
Índice
Prefácio
1. Escrevendo seu primeiro programa
1.1. Instalando Java no seu computador
1.1.1. Somente para usuários do Windows
1.2. Três etapas principais na programação Java
1.2.1. Janela de comando
1.2.2. Etapa 1 – Escreva o programa
1.2.3. Passo 2 – Compilar o Programa
1.2.4. Etapa 3 – Execute o programa
2. Ficando confortável no IDEA IDE
2.1. Instalando o IntelliJ IDEA
2.2. Criando seu primeiro projeto
2.3. Criando a classe HelloWorld no IDEA
2.3.1. Adicionando o método main
2.3.2. Executando HelloWorld no IDEA
2.4. Como HelloWorld funciona?
3. Conheça as classes - as principais construções da linguagem
3.1. Dissecando classes e objetos
3.1.1. Aulas
3.1.2. Objetos
3.2. Tipos de dados e variáveis Java
3.2.1. Primitivos
3.2.2. Classes como tipos de dados
3.2.3. Quanta memória é necessária
3.3. Criação de um animal de estimação
3.4. Herança – um peixe também pode ser um animal de estimação
3.5. Substituição de método
3.6. Desafie-se
4. Blocos de construção Java
4.1. Comentários do programa
4.2. Tomando decisões
4.2.1. A declaração if
4.2.2. Operadores Lógicos
4.2.3. Operador condicional
4.2.4. Usando else if
4.2.5. A switch Declaração
4.3. Quanto tempo uma variável viverá?
4.3.1. A palavra-chave static
[Link] 2/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 3/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 4/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 5/303
22/03/2025, 18:48 Programação Java para crianças
14.5.4. Clonagem
14.5.5. Bifurcação e solicitações de pull
14.5.6. Clonagem do IntelliJ IDEA
Epílogo
[Link] 6/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 7/303
22/03/2025, 18:48 Programação Java para crianças
Prefácio
O livro "Java para Crianças" foi escrito por Yakov Fain, Java Champion ([Link] . O
objetivo é ajudar os alunos a aprender a programar na linguagem mais popular do mundo: Java. Este livro
começa com uma introdução ao Java e então explica como escrever programas que tenham Interface Gráfica de
Usuário escrevendo os jogos Tic-Tac-Toe e Ping-Pong.
2. Os pais podem usar este livro para ensinar Java aos seus filhos
3. Professores escolares podem usá-lo como um livro-texto em aulas introdutórias sobre programação
4. Professores universitários podem usá-lo como um suplemento para suas aulas de "Ciência da Computação
101".
Embora este livro tenha sido escrito para crianças de 12+ anos, adultos que procuram uma introdução fácil ao
Java também podem achar este livro útil. No livro, você usará as mesmas ferramentas usadas por programadores
profissionais. Como bônus, o último capítulo lhe ensinará como publicar seu código na Web em um site super
popular chamado GitHub ([Link] . Milhões de programadores compartilham seus programas lá e você
também deveria.
Yuri Fain ([Link] produziu ilustrações para este livro. Se este material parece muito fácil para
você, compre a segunda edição do meu livro para adultos "Java 24-Hour Trainer"
([Link] ou um curso em vídeo "Introdução
ao Java e Java EE" ([Link] .
A versão online deste livro é oferecida gratuitamente sob a licença Creative Commons
([Link] , mas o autor apreciaria uma doação
([Link] se você achasse este
livro útil. Após fazer uma doação, você terá direito a receber a versão em PDF do livro, bem como nos formatos
MOBI (para Kindle) e EPUB (para iBook).
Se você encontrar um erro nos exemplos de código, envie seus comentários diretamente para mim em
yakovfain@[Link] ([Link] ou abra um problema no repositório de exemplos de código
([Link] no GitHub.
[Link] 8/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 9/303
22/03/2025, 18:48 Programação Java para crianças
Programadores escrevem aplicativos como jogos, calculadoras e editores de texto usando diferentes linguagens
de programação. Sem aplicativos, computadores, smartphones e consoles de jogos teriam uso muito limitado
para a maioria das pessoas. Dispositivos de computação geralmente vêm com um Sistema Operacional (SO)
instalado, como Windows, Mac OS, iOS e Android, mas imagine um iPhone que não tem nenhum aplicativo ou
um laptop que só pode mostrar o logotipo do SO. Quem iria querer um dispositivo desses?
Os programadores criam aplicativos usando diferentes linguagens de programação, como Java, Python, C++,
JavaScript, C e muitas outras. Algumas das linguagens são boas para produzir pequenos programas que exigem
muito pouco espaço de memória e podem ser incorporados em chips de computador. Algumas linguagens de
programação são ótimas para programar aplicativos da Web que rodam dentro dos navegadores da Web.
Algumas linguagens de programação são ótimas para rodar no servidor e lidar com milhares de solicitações de
usuários. Existem linguagens que são ajustadas para criar belos gráficos. Semelhante às linguagens humanas, as
linguagens de programação têm um conjunto de palavras (também conhecidas como palavras-chave) e as regras
para usá-las (a sintaxe).
Neste livro, você aprenderá a sintaxe da linguagem de programação Java, que pode ser usada para programar a
maioria dos tipos de aplicativos. E por muitos anos a linguagem de programação Java tem sido uma das
linguagens de computador mais populares do mundo. Na verdade, enquanto escrevo isso, as estimativas são de
que há cerca de 10 milhões de programadores Java profissionais no mundo, mas o que a torna tão popular?
Por um lado, o mesmo programa Java pode rodar em diferentes dispositivos: de computadores de mesa com
Windows ou MacOS a dispositivos portáteis como smartphones e tablets. Na verdade, os programas Java não se
importam com o dispositivo em que estão rodando porque eles rodam dentro de um tipo de hardware virtual
chamado máquina virtual. Falaremos sobre a Máquina Virtual Java um pouco mais adiante neste capítulo.
Java pode ser incorporado em pequenos microchips que controlam vários eletrodomésticos ou dispositivos
industriais, como os que alimentam casas inteligentes, onde o aquecimento ou a luz podem ser programados
remotamente a partir do seu telefone. Essas coisas conectadas à Internet podem ser programadas em Java.
Linguagens de programação podem ter algumas características gerais e dizemos que Java é uma linguagem
orientada a objetos. Seus elementos de programa ( classes ) representam objetos do mundo real. Por exemplo,
você pode criar uma classe chamada Car e dar a ela atributos que carros reais têm, como portas, rodas e assim
[Link] 10/303
22/03/2025, 18:48 Programação Java para crianças
por diante. Em seguida, você pode criar outra classe baseada na Car classe, como Tesla , com todos os
recursos da Car classe (portas, rodas) mais um motor elétrico.
E o software necessário para escrever Java é gratuito. Com tantos milhões de programadores Java profissionais
no mundo, você encontrará muitos programas de exemplo online, então se você tiver um problema, você pode
encontrar a solução pesquisando ou perguntando em um dos fóruns online populares como Stack Overflow
([Link] , e alguém provavelmente responderá sua pergunta!
[Link] 11/303
22/03/2025, 18:48 Programação Java para crianças
Se você usa o sistema operacional Windows, baixe o arquivo chamado [Link]. Como trabalho
com computadores Apple executando Mac OS X, o arquivo [Link] é meu instalador Java.
Execute seu programa instalador, concorde com todas as respostas padrão (basta pressionar o botão Next) e você
estará quase pronto para começar.
[Link] 12/303
22/03/2025, 18:48 Programação Java para crianças
Pressione o botão inferior Edit e adicione o diretório bin do seu JDK no início do Path valor da variável. Por
exemplo, adicione c:\Program Files\java\jdk1.8.0\bin; se for onde seu JDK está instalado:
[Link] 13/303
22/03/2025, 18:48 Programação Java para crianças
Agora a instalação do JDK no Windows está completa! Tenho certeza de que você está ansioso para começar a
escrever seu primeiro programa agora, então vamos lá.
2. Compile o programa para traduzi-lo da linguagem Java para um código de bytes especial que a JVM
entenda.
3. Execute o programa.
No Windows, para abrir a janela Command, clique no menu Start e digite as letras cmd no campo que diz Search
programs and files . Em um Mac, abra a janela Spotlight clicando no ícone de espelho no canto superior direito
da tela, digite a palavra Terminal e pressione Return no teclado.
prática mkdir
[Link] 14/303
22/03/2025, 18:48 Programação Java para crianças
Por exemplo, se você quiser escrever um programa chamado HelloWorld , insira seu código em um editor de
texto. Aqui está o programa que imprime as palavras Hello World! na tela do seu computador:
JAVA
public class HelloWorld{
[Link]("Hello World!");
}
}
Salve o código acima com o nome [Link] na pasta practice . Tenha em mente que você não tem
permissão para usar espaços em branco em nomes de arquivos Java.
Explicarei como e por que esse programa funciona um pouco mais adiante neste capítulo. Por enquanto, se você
seguiu cada passo corretamente, o programa imprimirá as palavras Hello World na tela, que veremos no passo 3.
[Link] 15/303
22/03/2025, 18:48 Programação Java para crianças
Os programadores geralmente usam as palavras código-fonte para se referir a um programa. Então é seguro dizer
que nós escrevemos o código-fonte do programa Hello World. A menos que você seja um programador Java
experiente, você não pode simplesmente assumir que este programa foi escrito corretamente. Vamos prosseguir
para a Etapa 2 para descobrir.
Altere o diretório para practice com o comando cd practice . Se você nunca usou o comando cd antes, leia as
instruções online sobre como fazê-lo no Windows ([Link]
ou no Mac OS ([Link] . Agora compile o programa
usando o seguinte comando:
javac Olá[Link]
[Link] 16/303
22/03/2025, 18:48 Programação Java para crianças
Você não verá nenhuma mensagem de confirmação de que seu programa HelloWorld foi compilado com
sucesso. Não ter nenhuma mensagem significa que não houve problemas durante a compilação. Digite um
comando dir no Windows ou ls no Mac e você verá a lista de arquivos na pasta practice . É assim que parece na
minha janela do Terminal:
Primeiro, eu digitei o comando pwd para ter certeza de que estou na pasta de prática . Você deve ver um novo
arquivo chamado [Link] . Isso prova que seu programa foi compilado com sucesso. Seu arquivo
original [Link] também pode ser encontrado lá, e você pode modificar esse arquivo mais tarde para
imprimir Hello Mom ou algo assim.
Se o programa tiver erros de sintaxe, por exemplo, você esqueceu de digitar a última chave, o compilador Java
imprimirá uma mensagem de erro. Agora você precisa corrigir o erro e recompilar o programa novamente. Se
tiver vários erros, pode ser necessário repetir essas ações mais de uma vez até que o arquivo
[Link] seja criado.
Após executar este comando, você verá o texto Hello World! impresso na janela Terminal, como mostrado em
Running HelloWorld . Você notou que desta vez você usou o programa java e não javac ? É assim que você
inicia o JRE, fornecendo a ele o nome do aplicativo a ser executado ( HelloWorld neste caso).
[Link] 17/303
22/03/2025, 18:48 Programação Java para crianças
Tenha em mente que Java não trata letras maiúsculas e minúsculas da mesma forma, o que significa que se você
originalmente nomeou o programa HelloWorld com uma maiúscula H e uma maiúscula W , não tente iniciar o
programa helloworld ou helloWorld – o JRE sinalizará um erro. O nome do arquivo deve corresponder ao
nome da classe também. Normalmente, cada arquivo do seu aplicativo contém o código de uma classe.
Agora vamos nos divertir um pouco tentando adivinhar como modificar o código do programa que imprime
Hello World. Explicarei como esse programa funciona no próximo capítulo, mas por enquanto tente adivinhar o
que precisa ser feito para dizer olá ao seu animal de estimação, amigo ou imprimir seu endereço. Siga todas as
três etapas para ver se o programa ainda funciona após suas alterações. Se você não tem um animal de
estimação, pode sempre dizer olá ao meu cachorrinho - o nome dele é Sammy. Você está pronto para o desafio
de escrever um programa que imprima Hello Sammy! na tela?
[Link] 18/303
22/03/2025, 18:48 Programação Java para crianças
No próximo capítulo, você aprenderá como escrever, compilar e executar seus programas em um ambiente mais
conveniente do que apenas um editor de texto e uma janela de comando. :toc-placement!: :imagesdir: .
[Link] 19/303
22/03/2025, 18:48 Programação Java para crianças
Neste capítulo, começaremos baixando e instalando o IntelliJ IDEA IDE (vamos chamá-lo apenas de IDEA).
Então, criaremos um projeto chamado Hello . Você verá que criar o aplicativo Hello World é muito mais fácil
dentro do IDEA.
[Link] 20/303
22/03/2025, 18:48 Programação Java para crianças
No Windows, você precisará selecionar a pasta onde o IDEA será instalado, conforme mostrado abaixo. O
instalador do Windows também oferecerá a criação de um ícone de desktop para o IDEA - concorde com isso.
[Link] 21/303
22/03/2025, 18:48 Programação Java para crianças
Em alguns segundos, você terá o IDEA instalado clicando no botão Avançar. Se você usa o MAC OS, encontre-o
usando o Spotlight no canto superior direito da tela e clique nele. Se você usa o Windows, clique no ícone do
IDEA recém-criado na sua área de trabalho. A primeira pergunta que o IDEA faz é se você deseja importar as
configurações das versões mais antigas do IDEA. Não selecione isso. Em seguida, vem esta tela de boas-vindas:
[Link] 22/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 23/303
22/03/2025, 18:48 Programação Java para crianças
Selecione a opção para criar um projeto Java. No IDEA, os projetos consistem em módulos. Ao selecionar Java,
declaramos que nosso projeto terá um módulo Java. Clique no botão Next e depois novamente na janela seguinte
que perguntará sobre a seleção de um modelo que será usado neste projeto. Agora precisamos dar um nome ao
nosso projeto e selecionar o JDK a ser usado com este projeto.
[Link] 24/303
22/03/2025, 18:48 Programação Java para crianças
Não queremos que nosso projeto fique sem título , então substitua esse nome por hello na caixa superior.
Observe como o nome da pasta na caixa Project location muda de acordo. Quando você tentar fazer isso no seu
computador, o local do projeto aparecerá diferente do meu. Agora você precisa selecionar o JDK. Se você nunca
trabalhou com Java antes, o único JDK que você terá é o instalado no Capítulo 1, embora os programadores Java
às vezes tenham mais de um JDK instalado. Por exemplo, eles podem não ter permissão para usar o JDK 8 mais
recente para projetos de trabalho, então eles mantêm o JDK 7 por perto, mas todos os projetos divertidos serão
criados com o JDK 8.
Não temos tais restrições, então JDK 8 é nossa única escolha. Agora descubra onde localizá-lo.
Clique no botão Novo, selecione o item de menu JDK e você verá uma tela familiar para navegar pelas pastas no
seu computador. Consulte a primeira seção do Capítulo 1 ( Instalando o Java no seu computador ) dependendo
se você está trabalhando com MAC ou Windows. Estou usando MAC, então estou escolhendo Biblioteca , Java ,
JavaVirtualMachines , [Link] . Observe que a janela anterior agora parece diferente.
[Link] 25/303
22/03/2025, 18:48 Programação Java para crianças
Pressione o botão Finish e seu novo projeto é criado. Toda vez que você inicia o IDEA, ele oferece pequenas
dicas sobre como usar seus recursos interessantes. Você pode optar por não participar, mas recomendo que as
leia - você pode encontrar algumas pequenas preciosidades que tornarão seu trabalho com o IDEA mais
divertido. O projeto hello está pronto e você pode começar a escrever seu programa Hello World.
Este projeto consiste no módulo hello e Bibliotecas Externas. O código-fonte do(s) seu(s) programa(s) estará(ão)
localizado(s) na pasta src no módulo hello. O arquivo [Link] é onde o IDEA lembra as configurações do
projeto hello - você não precisa mexer nele. Em Bibliotecas Externas você encontrará um monte de arquivos que
terminam em .jar . Esses JARs são as bibliotecas de código que vieram com o JDK.
Um projeto simples como o nosso HelloWorld terá apenas um arquivo com o código-fonte [Link] .
Projetos mais avançados consistirão em vários arquivos. Para simplificar a implantação do aplicativo, todos
esses arquivos podem ser empacotados em um ou mais JARs também. Tanto o JRE quanto o Java SDK incluem
dezenas de JARs. O Java vem com um utilitário jar que é usado para arquivar várias classes Java e outros
arquivos em um arquivo com a extensão de nome .jar. Os formatos internos dos arquivos .jar e .zip são os
mesmos. Se o seu projeto IDEA tiver várias classes, você pode empacotá-las em um JAR usando o menu
Arquivo | Estrutura do projeto | Artefatos e, em seguida, selecionando o tipo JAR.
[Link] 26/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 27/303
22/03/2025, 18:48 Programação Java para crianças
Em um segundo, o IDEA gerará uma classe vazia, HelloWorld como mostrado abaixo. A área branca à direita
é um editor de texto muito inteligente que permitirá que você não apenas insira o texto do seu programa, mas
também o ajudará sugerindo o que digitar em seguida enquanto você digita. Este editor é realmente inteligente!
O texto entre /** e */ é uma das maneiras de escrever comentários em seus programas. Esta é uma área onde
você pode digitar qualquer texto que queira que descreva seu programa em geral ou qualquer código específico
dentro da classe. Falaremos sobre várias maneiras de escrever comentários no próximo capítulo.
Você certamente pode digitar a declaração acima, e o IDEA obedientemente começará a ajudar conforme você
começa a digitar. Por exemplo, comecei a digitar a palavra public , e depois de entrar o pu IDEA sugeriu a
seguinte seleção de palavras-chave que são apropriadas no local atual dentro da classe.
[Link] 28/303
22/03/2025, 18:48 Programação Java para crianças
Pressionar o botão Tab no teclado se transformará pu em public . Você também pode pressionar as teclas
Control-Space para ver a conclusão de código sugerida a qualquer momento. Mas há uma maneira ainda mais
rápida de inserir a declaração do main método. Basta digitar as primeiras letras dessas palavras-chave psvm e
pressionar a tecla Tab . O IDEA desdobrará essas letras no seguinte:
JAVA
public static void main(String[] args) {
Ótimo trabalho, IDEA! Esse preenchimento de código minimiza a digitação e o número de erros de digitação
que você pode cometer. No final deste capítulo, na seção Leitura Adicional, você encontrará o link para uma
página da Web mostrando recursos mais avançados de preenchimento de código no IDEA. Pode ser um pouco
cedo para você entender tudo o que é explicado lá, mas marque um link para esta página para referência futura.
Para se tornar um verdadeiro profissional no IDEA, você deve usar as teclas de atalho , que
são combinações de pressionamentos de teclas no teclado. Com as teclas de atalho, você
poderá navegar em seus projetos do IDEA muito mais rápido do que clicando em menus.
DICA
Aqui está o link
([Link] para o
[Link] 29/303
22/03/2025, 18:48 Programação Java para crianças
Agora temos a classe HelloWorld com um método main vazio . A palavra método significa ação . Para
executar uma classe Java como um programa, essa classe deve ter um método chamado main . Normalmente,
seus aplicativos terão muitas classes, mas apenas uma delas terá o método main . Essa classe se torna o ponto de
entrada em seu aplicativo.
Para completar nosso programa, coloque o cursor depois da chave na linha com main , pressione o botão Enter
e digite o seguinte na nova linha:
[Link]("Hello World!");
Depois de aprender sobre o psvm atalho, você pode estar se perguntando se há uma maneira de fazer um truque
semelhante com [Link]() . Basta digitar sout e pressionar a tecla Tab . Voilá! O
sout magicamente se transforma em [Link](); . Os programadores Java geralmente usam
impressão no console, então os criadores do IDEA forneceram um atalho para isso.
Para salvar as alterações de código e compilar a classe, basta pressionar Ctrl-S no seu teclado. Se você não
cometeu nenhum erro de sintaxe, não verá nenhuma mensagem de erro, portanto o programa está compilado,
mas vamos introduzir um erro de sintaxe de propósito para ver o que vai acontecer. Apague a última chave na
classe HelloWorld e pressione Ctrl-S novamente. O IDEA adicionará uma linha ondulada onde o compilador
Java encontrou o erro, a linha é marcada com a marca vermelha à direita, e se você passar o ponteiro do mouse
sobre este pequeno retângulo vermelho, verá a mensagem de erro:
[Link] 30/303
22/03/2025, 18:48 Programação Java para crianças
Conforme seu projeto se torna maior, ele terá vários arquivos e o compilador pode capturar mais de um erro.
Você consegue ver uma lista de erros de todas as classes? Por padrão, o IDEA não compila todas as classes do
seu projeto, mas você pode solicitar a compilação do projeto inteiro sempre que fizer uma alteração ou salvar o
código-fonte. Vá para o menu IDEA Preferências (ou Configurações), selecione Compilador e marque a opção
Criar projeto automaticamente . Agora selecione o menu Exibir | Janelas de ferramentas | Problemas para ver
todos os problemas em uma lista:
In our case we only have one compiler error. Java reached the end of the file while parsing (trying to understand
your code), and something could not be found - the curly brace, of course. But what does this mysterious (8,6)
mean? The error was found in the line number 8 around the sixth character from the left. To see line numbers,
right-click on the gray vertical bar to the left of the code editor and select the option Show Line Numbers. Now
it’s easier to map the error messages to the lines in the source code:
[Link] 31/303
22/03/2025, 18:48 Programação Java para crianças
Java programmers can run their programs not only from a command window demonstrated in Chapter 1, but
right from the IDE. Just right-click on the name HelloWorld in the Project view and select the menu item Run
[Link](). The program will run and you’ll see the results in the Console View right inside IDEA:
[Link] 32/303
22/03/2025, 18:48 Programação Java para crianças
Every Java program has at least one class, and Chapter 3 explains classes in detail. Classes can contain methods,
which are the actions that the class can perform. The class HelloWorld has only one method main , which is a
special action. It’s a program starter or an entry point of any Java application. You can tell that main is not a
Java keyword, but a method, because it has parentheses after the word main . Methods can call (invoke) other
methods, for example our method main calls the method println to display Hello World! on the screen.
This method has public access level. The keyword public means that the method main could be
accessed by any other Java class or the JRE itself.
This method is static . The keyword static means that you don’t have to create an instance of the
HelloWorld object in memory to use this method. We’ll talk about classes and object instances in the next
chapter.
Does the method main return any data? Say, if you’ll write a method to add two numbers, it can return a
result. The keyword void means that the method main doesn’t return any data to whomever calls it (JRE
in this case).
[Link] 33/303
22/03/2025, 18:48 Programação Java para crianças
Some methods have parameters (a.k.a. arguments), which go inside the parentheses. It’s the data that could
be given to the method from another place of the program that invokes this method. The method main has
parameters - and an array of text values String[] args . You’ll learn how to use the parameters of the
method main in Chapter 9 in the section Command Line Arguments.
A Java program can consist of several classes, and each class may include methods. Usually, a Java class has
several methods. For example, a class Game can have the methods startGame , stopGame , readScore , and
so on. But only one class in the application will have the method main .
The body of our method main has only only one statement:
[Link]("Hello World!");
Every statement or a method call must end with a semicolon. The method println knows how to print data on
the system console (command window). Java method names are always followed by parentheses. If you see a
method with empty parentheses, this means that this method does not have any arguments and doesn’t expect to
receive any data. The above method println has one argument - a String with the value Hello World! .
[Link] means that the variable out is defined inside the class System that comes with Java. How are
you supposed to know that there’s something called out in the class System ? IDEA will help you with this.
After you type the word System and a dot, IDEA will show you everything that is available in this class. You
can also put a cursor after the dot and press Ctrl-Space at any time to bring up a help box similar to this one:
Figure 23. Peeking inside the System class with code completion
[Link] 34/303
22/03/2025, 18:48 Programação Java para crianças
This tells me that the Java class System has a variable out of type PrintStream . Are you curious as to what
PrintStream is? Click on out in your code and select the menu View | Quick Documentation to read the dry
documentation. The fact that a period goes after out followed by a method name - [Link]() - tells us
that out represents an object, which apparently has a method called println() .
[Link]("Dave", 3);
In this example, the arguments may be given to the method for some kind of processing like saving the score on
the disk. Since the name Dave was placed in parentheses, we can guess that the first argument has a String
type, which is used for text. The second argument is clearly of a numeric type but we can tell what’s the exact
type only after reading the declaration of the method saveScore inside the source code of the class
PingPongGame .
In the next chapter we’ll spend a lot more time seeing what Java classes consist of. :toc-placement!: :imagesdir: .
[Link] 35/303
22/03/2025, 18:48 Programação Java para crianças
Any program that you’ll write will have at least one class. You’ll learn how to declare a class and how to create
one or more objects based on the class declaration. You’ll also learn about a class’s internals – what a class can
consist of. Finally, I’ll show you how to create a class that inherits features of another class.
Java defines a number of data types. Some of them are simple, like int , which represents integer numbers.
Some of them are more complex - they are called classes, like System , which can be used for things like
printing text on the screen, exiting a program, or cleaning a computer’s memory.
When you installed Java on your computer, you installed thousands of Java classes. Your Java programs will also
consist of classes that can represent objects from the real world. If a class is a data type, an object is a
representative of a specific type. For instance, you can see ten dogs on the street, and they all represent the class
Dog .
Programmers start working on any application by deciding which Java classes to include in the program and
how many of each object type to create. Say, they can define a class Player in the gaming application and
create two object instances of this type.
3.1.1. Classes
Let’s see what Java classes can consist of. A very simple class can have nothing inside. Take a look at this class
declaration:
JAVA
class VideoGame {
This class is empty. It knows nothing and can’t do anything because there is no code between the curly braces.
From the Java syntax perspective, this class is legitimate and compiler won’t complain. There is a valid keyword
class followed by its name VideoGame . The opening curly brace has the matching closing one. We need
classes that can do stuff. We can place methods and attributes inside the class.
[Link] 36/303
22/03/2025, 18:48 Programação Java para crianças
A method consists of a callable code fragment, that can be called (and executed) by name from another part of
the program. For example, a class can have a method named saveScore that contains a dozen of lines of code
to save the game score. Let’s add some methods and attributes to the class VideoGame . This class may have
several methods, which can tell what an object of this class can do: start the game, stop it, save the score, ask for
additional lives on Facebook, and so on. This class also may have some attributes (a.k.a. fields): color, price and
others. An object that represents the class VideoGame can look like this:
JAVA
class VideoGame {
String color;
int price;
void start () {
// The code to start the game goes here
}
void stop () {
// The code to stop the game goes here
}
This class has two attributes color and price . The color attribute has the String data type, which is used
for storing any text. The price attribute is of an int type, which is used for storing integer numbers. The
class VideoGame has three methods: start , stop , and saveScore . These are the actions that our video
game should perform. Each of these method declarations start with a keyword void , which means that these
methods do not return a value to the caller of the method. In the next chapter I’ll show you a class Fish , which
will include a method dive that returns a value.
At this point each of these methods has just a single line that starts with two slashes //.
If a line starts with two slashes, it contains a single line comment - just the description of a
NOTE code fragment. If you need to write several lines of comments, just type in a slash followed
by the asterisk /* , then key in as many lines of a text as you want followed by */ .
Our class VideoGame can be used as a starting building block for pretty much any video game – all game
consoles have the color attribute, all of them allow to save score, and all of them have price tags.
[Link] 37/303
22/03/2025, 18:48 Programação Java para crianças
We can be more specific and create another Java class called PlayStation4 . It also belongs to the family of
video games, but has some properties that are specific to the model Play Station 4, for example sharing on
Facebook and Twitter. So among other things, the class PlayStation4 will have methods
shareOnFacebook and shareOnTwitter .
JAVA
class PlayStation4{
int hardDiskSize;
void shareOnFacebook(){
// Code to share on Facebook go here
}
void shareOnTwitter(){
// Code to share on Twitter go here
}
}
[Link] 38/303
22/03/2025, 18:48 Programação Java para crianças
3.1.2. Objects
We’ll often use the phrase create an instance of an object, which means to create an object in a computer’s
memory based on some class declaration. If a game factory will produce ten thousand games, a programmer can
say that they created ten thousand instances of the class PlayStation4 .
The factory description of PlayStation4 relates to an actual game the same way as a Java class relates to its
instance in memory. The process of building actual games based on this description in the game factory is
similar to the process of creating instances of PlayStation4 objects in Java. For example, the next code
sample creates one instance of the class PlayStation4 and calls its method shareOnFacebook .
JAVA
public class CreatePlayStation4Objects {
In many cases, a program can use a Java class only after creating the instance of an object. The same with
manufacturers - they create thousands of game copies based on the same description. Even though these copies
represent the same class, they may have different values in their attributes - some of them are black while others
can be silver. Some of them have 500GB hard disk dive while some are upgraded to 1TB.
[Link] 39/303
22/03/2025, 18:48 Programação Java para crianças
In programmer’s jargon, you can create multiple instances of the PlayStation4 objects with different values
in the hardDiskSize attribute.
Java variables not only can store numbers, but other types of data as well so we need to declare the variable type,
the name, and then assign some value to it. For example, the class attribute that has a value of the disk size can
be stored in the variable of type String that’s called hardDiskSize , which can be declared like this:
JAVA
String hardDiskSize;
If the size of the hard disk is 500GB, we can assign this value to the variable hardDiskSize as follows:
[Link] 40/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
hardDiskSize="500GB";
String values are placed inside the quotes, and the numbers aren’t.
The method parameters (a.k.a. arguments) are also stored in variables. The method saveStore has two
arguments: playerName of type String and score of type int :
3.2.1. Primitives
Simple Java data types are called primitives. Their keywords are written in small letters (e.g. int , long ,
char , boolean ). So the score is of a primitive data type, while the playerName is not. In Java you have
to declare the type and the name of a variable first and then use it.
Remember algebra equations like y=x+2 ? In Java you’d need to start with declaring the variables x and y of
some numeric data type like int , float or double :
JAVA
int x;
int y;
Now you can use the variables. The next two lines show how you can assign them values. If your program
assigns the value of five to the variable x , after evaluating x+2 the variable y will be equal to seven:
JAVA
x=5;
y=x+2;
In Java you are also allowed to change the value of a variable in a somewhat unusual way. The following two
lines change the value of the variable y from five to six:
JAVA
int y=5;
y++;
Despite the two plus signs, JVM is still going to increment the value of the variable y by one. The y++ means
read the value of the variable y , increment it by one, and assign it back to y . The longer syntax to achieve the
same result would be y=y+1 . After the next code fragment, the value of the variable myScore is also equal to
six:
JAVA
int myScore=5;
myScore=myScore+1;
[Link] 41/303
22/03/2025, 18:48 Programação Java para crianças
You can also use multiplication, division and subtraction the same way. Look at the following piece of code:
JAVA
int myScore=10;
myScore--;
myScore=myScore*2;
myScore=myScore/3;
What do you think this code prints? IntelliJ IDEA has a useful tool called Groovy Console (it’s under the Tools
menu). It allows you to test any code snippet (like the one above) without even creating a class or methods. If
you’ll copy the above code fragment into Groovy Console and hit the green button play, you see that the value of
the variable myScore is 6.
JAVA
To see the result of the score calculations, just click on the console tab at the bottom of
the screen:
My score is 6
In this example the argument of the method println was constructed from two pieces – the text “My score is ”
and the value of the variable myScore . Putting two or more strings together is called concatenation. Even
though myScore is a number, Java is smart enough to convert this variable into a String and then attach it to
the text "My Score is ".
[Link] 42/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
myScore=myScore*2; // it's the same as `myScore*=2;
myScore=myScore+2; // it's the same as `myScore+=2;
myScore=myScore-2; // it's the same as `myScore-=2;
myScore=myScore/2; // it's the same as `myScore/=2;
There are eight primitive data types in Java, and you have to decide which ones to use depending on the type and
size of data you are planning to store in your variables. These are Java primitives:
Four data types for storing integer values – byte , short , int , and long .
Two data types for values with a decimal point – float and double .
One logical data type boolean that allows only two values: true or false .
You can assign an initial value to a variable during its declaration, and this is called variable initialization, for
example:
JAVA
char grade = 'A';
int chairs = 12;
boolean playSound = false;
double nationalIncome = 23863494965745.78;
float gamePrice = 12.50f;
long totalCars =4637283648392l;
In the last two lines the values have letters at the end. The f is for float and l means long.
If you declare, but won’t initialize primitive variables, Java will do it for you by assigning zero to each numeric
variable, false to boolean variables, and a special code ‘\u0000’ to variables of type char .
In some cases there is no primitive type that suits your needs. For example, there is no primitive type for storing
long texts. While the char data type is used to store only one character, Java also has a class String for
working with a longer text, for example:
String lastName="Smith";
If you declare your own class, consider it a new data type. You can start declaring variables of this type, for
example, you can declare the variable named myFirstGame of type VideoGame :
[Link] 43/303
22/03/2025, 18:48 Programação Java para crianças
VideoGame myFirstGame
Java programmers have agreed to name variables starting with small letters. To make the variable name more
meaningful, it can consist of several words, and each word starts with the capital letter as in myFirstGame .
You’re also allowed to start variable names with the dollar sign like $myMoney or underscore:
_myBestFriend . Variable names cannot contain spaces.
Java also has a special keyword final , and if it’s used in a declaration of a variable, it means that you can
assign a value to this variable only once, and this value cannot be changed afterwards. In Java we usually name
final variables using capital letters:
Numeric data types that take more bytes can store larger numbers.
It’s time for hands-on work. Start IDEA IDE and create a new project as explained in Chapter 2. This time name
it MyPet instead of Hello . Click on the src folder in IDEA and create a Java class called Pet using the menu
File | New | Java Class.
[Link] 44/303
22/03/2025, 18:48 Programação Java para crianças
Now we are ready to declare attributes and methods in the class Pet . Java classes and methods enclose their
bodies in curly braces.
To declare variables for class attributes we should pick data types for them. I suggest an int type for the age,
float for weight and height, and String for the pet’s color.
JAVA
public class Pet {
int age;
float weight;
float height;
String color;
}
The next step is to add some methods to this class. Before declaring a method you should decide if it should take
any arguments and should return a value. This is what I suggest:
The method sleep will just print a message Good night, see you tomorrow – it does not need any
arguments and will not return any value.
The same is true for the method eat .It will print the message I’m so hungry, let me have a snack like
nachos!.
The method talk will not be printing any messages, but will prepare a message based on the word or a
phrase passed to this method as an argument. This method will build a phrase using the argument and will
return it back to the calling program.
The new version of the class Pet will look like this:
[Link] 45/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class Pet {
int age;
float weight;
float height;
String color;
This class represents these friendly little monsters from the "real world":
Let’s talk now about the signatures of each method in detail starting with the method sleep :
[Link] 46/303
22/03/2025, 18:48 Programação Java para crianças
This method signature tells us that sleep can be called from any other Java class ( because it’s public ). This
method does not return any data (the keyword void ). The empty parentheses mean that this method does not
take any arguments - it does not need any data from the outside world to print the same text.
This method can also be called from any other Java class, but has to return some text, which is prescribed by the
keyword String in front of the method name. Besides, it expects some text data from outside, hence the
argument String aWord .
How do you decide if a method should or should not return a value? If a method performs some data
manipulations and has to give the result of these manipulations back to the calling class, it has to return a value.
You may say that the class Pet does not have any calling class! That’s correct, so let’s create one called
PetMaster . We’ll create it in the same IDEA project MyPet.
This class will need a method main to become a runnable program (the class Pet didn’t have one). Remember
from Chapter 2, typing psvm followed by the Tab key will quickly create the method main . We’ll place the
code communicating with the class Pet inside the method main .
NOTE Do not forget to press Ctrl-S (CMD-S on Mac) to save and compile this class!
[Link] 47/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class PetMaster {
[Link](); (3)
[Link](petReaction); (5)
[Link](); (6)
}
}
1. The variable petReaction will store the value returned by the method say .
2. This is how to create an instance of the object Pet using the Java operator new . This line declares a
variable of type Pet - that’s right, you can treat any classes created by you as new Java data types.
3. Calling the method eat on the object Pet . After the instance of Pet was created, the variable myPet
knows its address in memory. So you can call the method eat (as well as any other) on this particular
instance of Pet .
4. If a method returns a value, specify a variable that will store returned value to the left of the equal sign. In
our code it’s petReaction of type String . Such variable should have the same type as the return value
of the method.
5. The value of the variable petReaction is passed as an argument to the method prinln for output.
To run the class PetMaster right-click on its name in the Project view in IDEA, and select the option Run
[Link](). This program will output the following:
I’m so hungry,let me have a snack like nachos! OK!! OK!! Tweet!! Tweet!! Good night, see you tomorrow!
[Link] 48/303
22/03/2025, 18:48 Programação Java para crianças
At this point the project MyPet consists of two Java classes: Pet and PetMaster . The role of the class Pet is
to represent attributes and behavior of a pet, while the class PetMaster starts the program, instantiates the
class Pet and calls its methods. Your typical projects will consist of multiple Java classes, but only one of them
will have have the main method, which is the entry point of the application.
The class Pet can include behaviors and attributes that are shared by many pets – all of them eat and sleep,
some of them make sounds, their skin has different colors, and so on. On the other hand, not all pets are the
same. Dogs bark, fish swim and don’t make sounds, and parakeets speak better than dogs. But all of them eat
and sleep. That’s why it’s easier to create a class Fish that will inherit some common behavior and attributes
from the class Pet , rather than creating Dog , Parrot or Fish from scratch every time.
Java has a special keyword extends that will do the trick. Create a new class Fish in IDEA and then add to
its declaration extends Pet so it’ll look as follows:
JAVA
class Fish extends Pet{
[Link] 49/303
22/03/2025, 18:48 Programação Java para crianças
This class Fish is a subclass of the class Pet . Accordingly, the class Pet is a superclass of the class Fish .
In other words, you use the class Pet as a template for creating a class Fish . The keyword extends defines
relationship between classes. Since our Fish extends a Pet , we can say that a fish is a pet. But we can’t say
that a pet is a fish.
Even if you will leave the class Fish empty as it is now, you can still use every method and attribute inherited
from the class Pet , because a fish is a pet! Take a look, we’re creating an instance of the object Fish and are
calling its method sleep :
JAVA
Fish myLittleFish = new Fish();
[Link]();
Even though we have not declared any methods in the class Fish yet, we call (invoke) the method sleep ,
which was declared in its superclass Pet ! In Java all classes are automatically inherited from the class
Object . Even though we’ve declared the class Pet without using the keyword extends it still extends the
class Object . With the keyword extends you can build class hierarchies. For example, many animal classes
can extend the class Pet .
Let’s not forget, however, that we’ve created the class Fish as a subclass of Pet , because we wanted to add
some additional features that only fish have and reuse some of the code that we wrote for a general [Link]
instance, not all pets can dive, but fish certainly can. Let’s add a new method dive to the class Fish .
[Link] 50/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class Fish extends Pet {
int currentDepth=0;
currentDepth=currentDepth + howDeep;
[Link]("Diving for " +
howDeep + " feet");
[Link]("I'm at " + currentDepth +
" feet below sea level");
return currentDepth;
}
}
O método dive tem um argumento (também conhecido como parâmetro) howDeep que diz ao peixe o quão
fundo ele deve ir. Também declaramos uma variável de classe currentDepth que armazenará e atualizará a
profundidade atual toda vez que você chamar o método dive . Este método retorna o valor atual da variável
currenDepth para a classe que faz a chamada. O sinal de mais nas pintln linhas não é sobre adição - estamos
construindo sequências de caracteres concatenando suas partes.
Usando o IDEA, crie outra classe chamada FishMaster que ficará assim:
JAVA
public class FishMaster {
[Link](2);
[Link](3);
[Link]();
}
}
O método main instancia o objeto Fish e chama seu método dive duas vezes com argumentos diferentes -
dois e três. Depois disso, ele chama o método sleep . Quando você executa o programa FishMaster , ele
imprime as seguintes mensagens:
TEXT
Diving for 2 feet
I'm at 2 feet below sea level
Diving for 3 feet
I'm at 5 feet below sea level
Good night, see you tomorrow
[Link] 51/303
22/03/2025, 18:48 Programação Java para crianças
Você notou que além dos métodos definidos na classe Fish , o FishMaster também chama o método sleep
de sua superclasse Pet ? É disso que se trata a herança – você não precisa copiar e colar o código da classe
Pet – basta usar a palavra-chave extends , e a classe Fish pode usar Pet os métodos de !
Mais uma coisa, mesmo que o método dive retorne o valor de currentDepth , nosso FishMaster não o usa.
Tudo bem, porque nossa classe `FishMaster` não usa o valor retornado, mas pode haver algumas outras classes
que também usarão a classe Fish , e elas podem achar útil saber a profundidade atual. Por exemplo, pense em
uma classe FishTrafficDispatcher que tem que saber as posições de outros peixes sob o mar antes de dar
permissões para mergulhar para evitar acidentes de trânsito.
Você realmente quer que nossos peixes falem? Se você não quer que isso aconteça, a classe Fish tem que
sobrescrever o Pet comportamento típico do - o método talk . Se você declarar um método com exatamente a
mesma assinatura em uma subclasse como em sua superclasse, o método da subclasse será usado em vez do
método da superclasse. Vamos adicionar o seguinte método talk à classe Fish .
JAVA
public String talk(String something){
return "Don't you know that fish do not talk?";
}
Agora adicione as três linhas a seguir ao método main da classe FishMaster (depois de criar a instância do
Fish ):
JAVA
String fishReaction;
fishReaction = [Link]("Hello");
[Link](fishReaction);
[Link] 52/303
22/03/2025, 18:48 Programação Java para crianças
Isso prova que Pet o método de talk foi substituído ou, em outras palavras, suprimido.
3.6. Desafie-se
1. Usamos a variável do tipo int to para armazenar o preço na classe VideoGame . Existe um tipo de dado
primitivo mais adequado para armazenar preços?
2. Crie um novo projeto no IDEA chamado chapter3 e uma nova classe Java Car com os seguintes métodos:
O método drive tem um argumento - o tempo de condução. O método tem que retornar a distância total
percorrida pelo carro no tempo especificado. Use a seguinte fórmula para calcular a distância: distance =
howlong*60; . Use a declaração return distance como a última linha no método drive .
4. Escreva outra classe CarOwner com o método main que cria uma instância do objeto Car e chama seus
métodos. O resultado de cada chamada de método tem que ser impresso usando [Link]() .
5. Crie uma subclasse de Car named JamesBondCar e sobrescreva o método drive lá. Agora use a seguinte
fórmula para calcular a distância: distance = howlong*180;
6. Crie uma instância da classe JamesBondCar no main método de CarOwner . Execute novamente o
programa CarOwner para ver se ele chama o método substituído drive . :toc-placement!: :imagesdir: .
[Link] 53/303
22/03/2025, 18:48 Programação Java para crianças
Existem três tipos diferentes de comentários - comentários de linha única, comentários de bloco e comentários
javadoc. Eis para que servem:
JAVA
// This method calculates the distance between A and B.
Se você quiser escrever comentários de várias linhas, em vez de começar cada linha com duas barras, basta
cercar o texto inteiro com estes símbolos: /* e */ , por exemplo:
JAVA
/* Now we'll handle the current
position of the Fish.
*/
O Java vem com um programa especial javadoc que pode extrair todos os comentários dos seus programas em
um arquivo de ajuda separado que pode ser exibido por qualquer navegador da Web. Este arquivo pode ser usado
como uma documentação técnica para seus programas. Tais comentários são colocados entre os símbolos /** e
*/ . Observe os dois asteriscos após a primeira barra. Somente os comentários mais importantes, como a
descrição de uma classe ou um método, devem ser colocados entre esses símbolos.
[Link] 54/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
/** This method calculates the discount that depends
on the price paid. If the price is more than $100,
give the user 20% off, otherwise only 10%.
*/
The javadoc tool can process your code, extract all comments that start with /** and create program
documentation that can be published online or kept locally on the company server. We are not going to use
javadoc in this book, but if you’re interested in learning more about this tool, read Oracle’s tutorial How to Write
Doc Comments for the Javadoc Tool ([Link]
From now on, I’ll be adding comments to code samples to give you a better idea how and where to use them.
Based on the result of evaluating this expression, your program execution forks, and only the relevant portion of
the code will be invoked.
For example, if the expression Do I want to go to grandma’s? is true , turn to the left, otherwise turn to the
right.
[Link] 55/303
22/03/2025, 18:48 Programação Java para crianças
Take a look at the following code sample. If an expression inside the parentheses is true , JVM will execute the
code between the first pair of curly braces, otherwise it goes to the code after the else statement. In other
words, if the value of the variable totalSpent is more than a hundred, give a 20% discount, otherwise take
only 10% off.
[Link] 56/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
// Assume that the method getTotalAmount()
// adds up the prices from your shopping cart
Let’s modify the method dive() in the class Fish from Chapter 3 to make sure that our fish is not allowed to
dive below 100 feet:
JAVA
public class Fish extends Pet {
int currentDepth=0;
Now just make a small change in the class FishMaster – let it try to make our fish go deep under the sea:
[Link] 57/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class FishMaster {
[Link]();
}
}
Run this program and it’ll print the following on the system console:
HTML
Diving for 2 feet.
I'm at 2 feet below the sea level.
Diving for 97 feet.
I'm at 99 feet below the sea level.
I am a little fish and can't dive below 100 feet.
Good night, see you tomorrow.
In Java the sign for a logical or is one or two vertical bars. It works like this – if any of the two conditions is
true , the result of the entire expression is also true .
In the following examples I use a variable of type String , which has a method equals() that compares the
values of two strings. I use it to see whether the value of the variable state is "Texas" or "California":
JAVA
if ([Link]("Texas") | [Link]("California"))
{
// do something
}
You can also rewrite this if statement using two vertical bars:
[Link] 58/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
if ([Link]("Texas") || [Link]("California"))
{
// do something
}
The difference between these two examples is that if you use two bars, and the first expression is true , the
second expression won’t even be checked. If you place just a single bar, JVM will evaluate both expressions.
The logical and is represented by one or two ampersands ( && ) and each expression in the parentheses must be
true to make the entire expression true . For example, charge the sales tax only if the state is New York and
the price is more than $110. Both conditions must be true at the same time:
JAVA
if ([Link]("New York") && price >110)
{
// do something
}
or
JAVA
if ([Link]("New York") & price >110)
{
// do something
}
If you use double ampersand and the first expression is false , the second one won’t even be checked, because
the entire expression will be false anyway. With the single ampersand both expressions will be evaluated.
The logical not is also known as negation and is represented by the exclamation point. The logical not
changes expression to the opposite meaning. For example, if you want to perform some actions only if the state
is not New York, use this syntax:
JAVA
if () {
// do something
}
The following two expressions will produce the same result, because more than 50 and not less than or equal to
50 have the same meaning:
[Link] 59/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
if (price > 50) {
// do something
}
In the second example the logical not is applied to the expression in parentheses.
If the price is greater than fifty, the variable discount will get a value of 10, otherwise discount will have a
value of 5. It’s just a shorter replacement of the following if statement:
JAVA
if (price > 50){
discount = 10;
} else {
discount = 5;
}
[Link] 60/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class ReportCard {
String studentName;
/**
The method convertGrades has one integer argument - the result of the school test. The method
returns one letter A, B, C or D depending on the argument's value.
*/
public char convertGrades( int testResult){
char grade;
return grade;
}
yourGrade = [Link](79);
[Link]("Your second grade is " +
yourGrade);
}
}
Beside using the else if condition, this example also shows you how to use variables of type char . You can
also see that with the && operator you can check if a number falls into specific range. You can not just write if
testResult between 80 and 89, but with logical and you can check the condition when testResult is greater
than or equal to 80 and less then 89 at the same time:
Take a guess as to why we could not use the logical or operator here? Say the testResult is 100. It’s greater
than 80, and the above expression would evaluate to true, because for the || operator having one true is enough
to make the entire expression true. But this is not what we want - we need the above expression to be true only if
[Link] 61/303
22/03/2025, 18:48 Programação Java para crianças
the value of testResult is between 80 and 89. The logical and operator does the job by ensuring that both
conditions are true.
JAVA
public static void main(String[] args){
switch (yourGrade){
case 'A':
[Link]("Excellent Job!");
break;
case 'B':
[Link]("Good Job!");
break;
case 'C':
[Link]("Need to work more!");
break;
case 'D':
[Link]("Change your attitude!");
break;
}
// Some other program code goes here
Say, the value of yourGrade is B . Then the above code will print "Good Job!" and will break out of the
switch statement to continue executing the rest of the program code if any.
Do not forget to put the keyword break at the end of each case statement to make the code jump out of the
switch . For example, if you forget to put the break in the case 'B' block, the above code would print
"Good Job!" followed by "You need to work more!".
[Link] 62/303
22/03/2025, 18:48 Programação Java para crianças
Programmers use the word scope to say how long a variable will live, for example you can say that variables
declared inside a method have a local scope. If a variable is declared within the code block surrounded with
curly braces (e.g. in the if statement), it has a block scope and won’t be visible outside of this block.
[Link] 63/303
22/03/2025, 18:48 Programação Java para crianças
If a variable has to be reused by several method calls, or it has to be visible from more than one method in a
class, you should declare such a variable outside of any method. In the class Fish from Chapter 3, the
currentDepth is a member variable. The member variable currentDepth is alive until the instance of the
object Fish exists in the computer’s memory. You can call currentDepth a instance variable, because its
declaration doesn’t include the keyword static , which we’ll discuss shortly.
Member variables can be shared and reused by all methods of the class, and we can make them visible from
external classes too, if need be. For example the method main of the class ReportCard includes the statement
[Link]() . It uses the class variable out that was declared in the Java class System .
When you start any Java program it loads the definition of the required classes in memory. The definition of a
class can be used for creation of one or more instances of this class. For example:
JAVA
ReportCard rc = new ReportCard();
[Link] = "Jerry Lee";
In this example we have two instances of the class ReportCard , and each of them has its own value in the
variable studentName , which is an instance variable. Now, let’s change the declaration of this variable by
adding the keyword static :
In this case both instances of the ReportCard would share the same variable studentName , and the above
code would first assign "Jerry Lee" to this variable, and then it would be replaced with "Sarah Smith". This
doesn’t seem like a good idea does it?
Moreover, if the declaration of a member variable or a method starts with static , you do not have to create an
instance of this class to use such a variable or a method. Static members of a class are used to store the values
that are the same for all instances of the class.
For example, the method convertGrades should be declared as static in the class ReportCard , because
its code does not use member variables to store values specific to a particular instance of the class.
[Link] 64/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public static char convertGrades( int testResult){
// the code of this method goes here
}
There is no need to create instances to call static methods or access static variables. Just write the name of the
class followed by the dot and the name of the static member:
Here’s another example: Java has a class Math that contains several dozen mathematical methods like sqrt ,
sin , abs and others. All these methods are static and you do not need to create an instance of the class
Math to invoke them, for example:
Parentheses after the word Fish tell us that this class has some method called Fish . Yes, there are special
methods that are called constructors, and these methods have the following features:
Constructors are special methods that are called only once during construction of the object in memory.
They do not return a value, and you do not even have to use the keyword void in the constructor’s
declaration.
Any class can have more than one constructor. If you do not create a constructor for the class, Java automatically
creates one during the compilation time - it’s so-called default no-argument constructor. That’s why Java
compiler has never complained about the statements new Fish() or new ReportCard() , even though
neither class Fish nor class ReportCard has any explicitly declared constructor.
In general, constructors are used to assign initial values to member variables of the class, for example the next
version of the class Fish has a one-argument constructor that just assigns the argument’s value to the instance
variable currentDepth for future use.
[Link] 65/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class Fish extends Pet {
int currentDepth;
// This is constructor
Fish(int startingPosition){
currentDepth=startingPosition;
}
}
Now the class FishMaster can create an instance of the Fish and assign the initial position of the fish. The
next example creates an instance of the Fish that is “submerged” 20 feet under the sea:
If a constructor with arguments has been defined in a class, you can no longer use the default no-argument
constructor. If you’d like to have a constructor without arguments - write one.
JAVA
class Fish {
int currentDepth ;
Fish(int currentDepth){
[Link] = currentDepth;
}
}
Have you noticed that the member variable and the constructor’s argument have the same name? The keyword
this helps to avoid name conflicts. In this code sample [Link] refers to the object’s member
variable currentDepth , while the currentDepth refers to the argument’s value. In other words, the code
points at the current instance of the Fish object.
[Link] 66/303
22/03/2025, 18:48 Programação Java para crianças
You’ll see another important example of using the keyword this in Chapter 6 in the section How to Pass Data
Between Classes.
4.6. Arrays
An array is an object that holds several values of the same type - primitives or objects. Let’s say your program
has to store the names of four game players. Instead of declaring four different String variables, you can
declare one String array that has four elements. Arrays are marked by placing square brackets either after the
variable name, or after the data type:
String [] players;
[Link] 67/303
22/03/2025, 18:48 Programação Java para crianças
or
String players[];
These declarations just tell the Java compiler that you are planning to store several text strings in the array
players . Each element has its own index (position number) starting from zero. The next sample actually
creates an instance of an array that can store four String elements and assigns the values to the elements of
this array:
JAVA
players = new String [4];
players[0] = "David";
players[1] = "Daniel";
players[2] = "Anna";
players[3] = "Gregory";
You must declare the size of the array before assigning values to its elements. If you do not know in advance
how many elements you are going to have, you cannot use arrays, but you should look into other classes - Java
collections. For example the ArrayList object does not require you to announce the exact number of elements
in advance. I’ll show you some examples of using the ArrayList collection in Chapter 10 about data
collections.
Any array has an attribute called length that stores the number of elements in this array, and you can always
find out how many elements are there:
If you know all the values that will be stored in the array at the time when you declare it, Java allows you to
declare and initialize such array in one shot:
[Link] 68/303
22/03/2025, 18:48 Programação Java para crianças
Imagine that the second player is a winner and you’d like to write the code to congratulate this kid. If the players’
names are stored in an array get its second element:
JAVA
String theWinner = players[1];
[Link]("Congratulations, " + theWinner + "!");
The output from these two lines of code will look like this:
Congratulations, Daniel!
Do you know why the second element has the index [1]? Of course you do, because the index of the first
element is always [0].
The array of players in our example is called one-dimensional array. Imagine the players sitting like ducks in a
row. The single dimension is the seat number here. If the players (or game spectators) will occupy several rows,
then we’ll have two dimensions - the row number and a set number within the row. This is the case where we’d
need to declare a two-dimensional array. Java allows creation of multi-dimensional arrays, and I’ll show you
how to do this in Chapter 10.
JAVA
int totalPlayers = [Link];
int counter;
Print the value of the element from the players array whose number is the same as the current value of the
counter . Start from the element number 0: _ counter=0) , _and increment the value of the counter by
one: (counter++) . Keep doing this while the counter is less than totalPlayers`:
`counter<totalPlayers .
[Link] 69/303
22/03/2025, 18:48 Programação Java para crianças
JVM executes every line between the curly braces and then returns back to the first line of the loop to increment
the counter and check the conditional expression.
There is another flavor of the for loop known as for each loop. It allows the program to repeat the same action
to every element of the collection without even knowing how many are there. You are basically saying, do this
for each [Link] for-each loop allows to congratulate players in a more concise manner:
JAVA
for (String pl: players){
[Link]("Congratulations," + pl +"!");
}
The variable pl has the type String - the same as as the array’s elements. Use this variable as a cursor, point
it to each element in the array players one by one and repeatedly execute the code inside the curly brackets
for the current element.
There is another keyword for writing loops - while . In these loops you do not have to declare exactly how
many times to repeat the action, but you still need to know when to end the loop. Let’s see how we can
congratulate players using the while loop that will end when the value of the variable counter becomes
equal to the value of totalPlayers :
JAVA
int totalPlayers = [Link];
int counter=0;
In Chapter 9 you’ll learn how to save the data on the disk and how to read the saved data back into computer’s
memory. If you read game scores from the disk file, you do not know in advance how many scores were saved
there. Most likely you’ll be reading the scores using the while or for-each loop, which don’t require you to
state the number of iterations upfront.
You can also use two important keywords with loops: break and continue .
As with switch statements, the keyword break is used to jump out of the loop when some particular
condition is true . Let’s say we do not want to print more than 3 congratulations, regardless of how many
players we’ve got. In the next example, after printing the array elements 0, 1 and 2, the break will make the
code go out of the loop and the program will continue from the line after the closing curly brace.
[Link] 70/303
22/03/2025, 18:48 Programação Java para crianças
The next code sample has the double equal sign == in the if statement. This means that you are comparing the
value of the variable counter with number 3. A single equal sign in the here would mean assigning the value
of 3 to the variable counter . Placing = in an if statement instead of == is a very tricky mistake, and it can
lead to unpredictable program errors that may be dificcult to find.
JAVA
int counter =0;
while (counter< totalPlayers){
if (counter == 3){
break; // Jump out of the loop
}
String thePlayer = players[counter];
[Link]("Congratulations, "+thePlayer+ "!");
counter++;
}
The keyword continue allows the code to skip some code lines and return back to the beginning of the loop.
Imagine that you want to congratulate everyone but David – the keyword continue will return the program
back to the beginning of the loop:
JAVA
while (counter< totalPlayers){
counter++;
if ([Link]("David"){
continue;
}
[Link]("Congratulations, "+ thePlayer+ !");
}
There is yet another type of the while loop that starts with the word do , for example:
JAVA
do {
[Link]("Congratulations, "+
players[counter] + !");
counter++;
Such loops check an expression after executing the code between curly braces, which means that code in the
loop will be executed at least once. Loops that start with the keyword while might not be executed at all if the
loop expression is false to begin with.
[Link] 71/303
22/03/2025, 18:48 Programação Java para crianças
2. In the src directory of the project create a new class (the menu File | New) named TemperatureConverter.
3. Add the method convertTemp() so the code of the class looks like this:
JAVA
public class TemperatureConverter {
public static float convertTemp (float temperature,
char convertTo) {
}
}
4. Write the if statement inside the method convertTemp to check the value of the argument convertTo . If
it’s F , the temperature has to be converted to Fahrenheit, and if it’s C , convert it to Celsius. Return the
result. The method convertTemp should look like this:
JAVA
public static String convertTemp (float temperature, char convertTo) {
if (convertTo=='F'){
return "The temperature in Fahrenheit is " + (9*temperature/5 + 32);
} else if(convertTo=='C') {
return "The temperature in Celsius is " + (temperature - 32) * 5/9;
} else{
return "You can enter either F or C as convertTo argument";
}
}
5. Add the method main using the shortcut psvm + Tab as explained in Chapter 2. It should look like this:
JAVA
public static void main(String[] args) {
6. Run the program TemperatureConverter using the IDEA menu Run | Run TemperatureConverter. If you
did everything right, you should see the following output on the IDEA console:
EXT
Converting 21C to Fahrenheit. The temperature in Fahrenheit is 69.8
Converting 70F to Celsius. The temperature in Celsius is 21.11111
7. Do a little research to change this program so it always prints the temperature with two digits after the
decimal point. Study Oracle’s tutorial about formatting numeric output: [Link] :toc-
placement!: :imagesdir: .
[Link] 72/303
22/03/2025, 18:48 Programação Java para crianças
The phrase to implement a method simply means to write code in a method. Starting from Java 8 you can also
program behavior in so called lambda expressions covered later in this chapter.
So far I was declaring and implementing behavior in methods located inside Java classes. But there is a way and
a reason to separate the method declaration from its implementation. Such separation can be done using
interfaces.
For years, Java interfaces were used mainly for holding method declarations and final static variables. For
example, the interface Talkable contains the declaration of just one method talk :
JAVA
interface Talkable{
public void talk();
}
Since the method talk is not implemented here, it’s called abstract.
To create a new interface in IDEA, select the menu File | New | Java class and select Interface
NOTE
in the Kind box.
[Link] 73/303
22/03/2025, 18:48 Programação Java para crianças
You should be thinking, "What’s the point of simply declaring a method without implementing it?" The thing is
that more than one class can exhibit the same behavior. For example, a dog, a cat, and a parrot can "talk". But
they "implement it" differently. A parrot can repeat words, while dogs bark. Cats talk by meowing. Accordingly
you can declare three classes that will implement Talkative interface differently, as shown below:
JAVA
public class Parrot implements Talkative {
public void talk(){
[Link]("My name is Kesha.");
}
}
These three classes use the Java keyword implements , which means they promise to implement all abstract
methods in the interface(s) listed after the keyword implements otherwise the Java compiler will complain:
"You promised to implement all abstract methods from Talkable , where are they? Keep your promise!"
What if we need to create the class Fish that uses interfaces? Fish don’t talk. But they swim. Dogs can talk
(bark) and swim, right? Why won’t we declare yet another interface Swimmable with the methods swim and
dive ?
JAVA
public interface Swimmable {
Now let’s leave the parrots alone. Let’s create a new class Fish and change the class Dog just a little bit. The
Fish will implement Swimmable and the Dog will implement two interfaces:
[Link] 74/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class Fish implements Swimmable {
public void swim(int howFar){
[Link]("OK, will swim " + howFar + " feet");
}
public void dive(int howDeep){
[Link]("OK, will dive " + howDeep + " feet");
}
}
When a class implements several interfaces, make sure to implement each and every abstract method declared in
these interfaces. A class can extend another class and implement interfaces at the same time, for example:
JAVA
class Fish extends Pet implements Swimmable{
Java includes several interfaces that don’t declare any methods (e.g. Serializable ). They
are called marker interfaces. You don’t need to implement any methods in classes that
NOTE
implement marker interfaces. They are used by the Java compiler internally to generate the
byte code in a special way.
[Link] 75/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public interface Swimmable {
Now the class Dog doesn’t have to implement the method dive - the compiler will see a default
implementation and won’t complain. The next version of the class Dog implements only the method swim
from Swimmable .
JAVA
public class Dog implements Talkative, Swimmable {
public void talk(){
[Link]("Bark! Bark-bark!");
}
There is no need to change the class Fish . It also implements Swimmable , but has its own version of the
method dive , which will override the default implementation of the dive from Swimmable . You can still
invoke the method dive on the instance of the Dog class - the default implementation will be invoked. The
next class PetMaster will demonstrate this.
JAVA
public class PetMaster {
public static void main(String[] args) {
Run this program and you’ll see the following output on the console:
[Link] 76/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
_Bark! Bark-bark!
Will swim about a half of this distance: 3 feet
Can't dive, sorry
OK, will swim 50 feet
OK, will dive 20 feet
The message "Can’t dive, sorry" was printed by the default method dive from the interface Swimmable .
The modified version of the Swimmable interface includes a static method isSummer that checks the current
month and returns true if it’s June, July, or August. I’m using the Java Date and Time API here. The default
method dive calls the static method isSummer and either agrees or disagrees to dive depending on the time of
the year.
[Link] 77/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
import [Link];
if (isSummer()){
[Link]("OK, will dive. The water should be warm.");
} else {
[Link]("Can't dive, sorry. The water's cold for diving.");
}
};
O método isSummer usa a classe LocalTime para obter Month , que tem um tipo de dado enum que eu não
usei até agora. É um tipo de dado especial para representar um número fixo de alguns valores, como meses neste
caso. Há apenas 12 meses, e a API Java Date and Time os listou por nome no enum chamado Month . Os únicos
valores permitidos aqui são [Link] para [Link] . Usar enums torna os programas mais
legíveis - é mais fácil lidar com meses por nomes do que por números.
Para que o compilador saiba onde a classe LocalDate está localizada, você pode especificar o nome
completo da classe, por exemplo:
JAVA
[Link] todaysDate = [Link]();
[Link] 78/303
22/03/2025, 18:48 Programação Java para crianças
Mas essa sintaxe é difícil de ler, então usamos as import instruções acima da declaração de classe para
deixar o compilador saber a localização da classe, interface ou enumeração. Por exemplo:
JAVA
import [Link];
Agora você pode usar apenas o nome da classe sem precisar especificar o nome do pacote:
JAVA
LocalDate todaysDate = [Link]();
Os pacotes são armazenados em diretórios e subdiretórios no disco. Se você vir um nome de classe
completo, [Link] significa que essa classe foi criada originalmente no subdiretório time
do diretório java .
De agora em diante, usaremos pacotes e a declaração import em todos os capítulos deste livro. Se você
quiser colocar sua classe em um pacote, basta criar um subdiretório (por exemplo, pets ) e adicionar uma
package declaração no topo da definição de sua classe, por exemplo:
JAVA
package pets;
class Dog{
// your code goes here
}
Uma última coisa: Crianças preguiçosas usam os curingas em instruções import. Em vez de escrever uma
instrução import por classe, elas usariam um asterisco:
JAVA
import [Link].*;
Isso significa que as definições necessárias para meu programa estão localizadas no pacote [Link] .
Claro, escrever uma declaração import em vez de várias parece atraente, mas a legibilidade do programa
sofre. Pacotes podem ter dezenas de classes e é melhor declarar explicitamente quais classes seu programa
usa.
[Link] 79/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 80/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public interface Swimmable {
Uma classe que implementa também Swimmable pode usar o valor de . MAX_DEPTH
JAVA
public abstract class Animal{
// some code goes here
}
If a class is declared as abstract, you can’t create an instance of it. Typically, abstract classes have some non-
implemented methods that are also declared with the abstract keyword:
[Link] 81/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public abstract class Animal {
String animalClass;
String name;
The class Animal has two implemented methods: setName and sleep and one abstract method talk .
Since the abstract class can not be instantiated, the programmer has to create a descendant class and implement
the method talk there if he or she wants to create an instance of such a class, for example:
JAVA
public class Dog extends Animal{
public void talk(){
[Link]("Bark! Bark-bark!");
}
}
Strictly speaking, it’s not a must to implement the method talk in the class Dog , but in this case Dog remains
abstract and can’t be instantiated. Maybe the programmer wants to create a class Puppy that extends Dog and
implements the method talk there?
And again you might be wondering, "Why complicate a programmer’s life by declaring non-implemented
methods?" If you want to build a hierarchy of classes that extend from Animal you might want to declare an
unified method signature, so each class ( Dog , Parrot , Fish et al.) will have the same way of initiating the
talk.
[Link] 82/303
22/03/2025, 18:48 Programação Java para crianças
Interfaces can’t have instance methods, but they don’t enforce any class hierarchy. So you can have a class Dog
that extends any class, while implementing an interface Talkative that declares the method talk .
Let’s say I want to write a simple calculator in Java. In chapters 8 and 9 you’ll create a real calculator with the
graphical Users Interface (GUI), but for now I’ll show you how to program operations such as addition and
subtraction. The multiplication and division operations can be programmed similarly, so I won’t be
implementing these operations.
I want to keep these examples in the package called calc . You can create a subdirectory named calc in your
project and save your classes there. The other option is to right-click on the folder src in your IDEA project and
select the menu New | Package and enter the package name there:
First comes the version that doesn’t use anonymous classes - I’ll just use one method for each operation. The
code of the class Calculator is pretty simple. Note the first line that declares the package where the class
Calculator belongs.
[Link] 83/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package calc;
addTwoNumbers(3.55, 50.00);
subtractTwoNumbers(3.55, 50.00);
}
}
This class has two methods that manipulate numbers (one per operation), and its main method invokes each
method passing the same values as arguments. After performing the arithmetic operation each method prints the
result. Running this program produces the following output:
JAVA
3.55 + 50.0 = 53.55
3.55 - 50.0 = -46.45
Now let’s redesign this application. Instead of writing a separate method for each operation, I want to write a
generic method that can receive the code of the operation and two numbers to be operated upon. This method
will have three arguments: the arithmetic operation, the first, and the second number.
The operation is a behavior, so let’s declare an interface to represent it using a functional interface with a single
abstract method:
JAVA
package calc;
[Link] 84/303
22/03/2025, 18:48 Programação Java para crianças
I’ll write two implementations of the ArithmeticOperation interface using anonymous classes - one for
addition and one for subtraction. I will also write a method calculate that will take three arguments: the
object that implements ArithmeticOperation and two numbers.
JAVA
package calc;
return [Link](a,b);
}
The output of the CalculatorWithAnonymousClasses program will be the same as from Calculator .
What did we achieve by re-writing calculator this way? We separated the declaration of the behavior and its
implementation. The behavior is declared in the interface, and if more than one class needs to implement
ArithmeticOperation , we’ll reuse this interface. The anonymous classes allowed me to create a wrapper
object around the method performOperation , so this object could be passed as an argument to the method
calculate . In the next section I’ll rewrite this calculator again in a more elegant way with lambda
expressions.
[Link] 85/303
22/03/2025, 18:48 Programação Java para crianças
Access Levels
In many code samples I’ve been using the keyword public in declaration of member variables and
methods. This means that such a variable or a method can be accessed by any other code from the project.
In the next chapter I’ll explain how to control access levels in Java.
First, let me introduce a new term - a function. So far to implement any behavior you’d write a method that
could be invoked by specifying the class name and a method name (static methods) or by specifying the object
variable and a method name (non-static methods). This is a main idea of any object-oriented programming
language - the classes and objects are the first-class citizens. You can’t write a program without them.
But there are functional programming languages that don’t need to wrap behavior inside classes. They allow you
to implement behavior by writing functions, which are similar to methods in that they can have names, take
arguments, and return results. But functions don’t have to be placed inside classes and can live independently.
A lambda expression is a function without a name or anonymous function that you can assign to a variable, pass
as an argument to a method or return from a method. In earlier versions of Java you could pass a value to a
method only if this value was an object or a primitive. But now a function (a piece of code) becomes a value that
can be passed around. Now let’s see it in action.
[Link] 86/303
22/03/2025, 18:48 Programação Java para crianças
In the new version of calculator I’ll declare each arithmetic operation as a lambda expression. I will reuse the
same functional interface with the three-argument method calcuate , but will pass the lambda expression that
implements ArithmeticOperation as the first argument.
[Link] 87/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class CalculatorWithLambdas {
return [Link](a,b);
}
2. Make sure that the arguments of your lambda expression match the arguments of the abstract method.
3. Make sure that the return value of your lambda expression matches the return value of the abstract method.
Review the code of the CalculatorWithLambdas . Both lambdas addition and subtraction abide by
these rules.
You may wonder, "Why are there no data types specified for the lambda parameters first and second?" The
reason being that Java compiler is smart enough to guess their data types because it knows which abstract
method this lambda implements. An educated guess such as this is called type inference.
[Link] 88/303
22/03/2025, 18:48 Programação Java para crianças
Vamos começar definindo a interface funcional Talkative . Desta vez, vou mudar um pouco a assinatura do
método talk em comparação com a versão mostrada anteriormente neste capítulo. Faço isso para mostrar a
você como escrever uma expressão lambda que implementa um método que tem um argumento e retorna algum
valor.
JAVA
public interface Talkative {
public String talk(String petName);
}
Agora vamos escrever a classe Pet com um método speakup que receberá a implementação da
Talkative interface como o primeiro argumento e o nome do animal de estimação como um segundo. A classe
Pet pode ter muitos outros métodos úteis, mas eu gostaria de focar no speakup que pode receber um pedaço
de código definindo as regras de conversação e aplicar esse código.
JAVA
public class Pet {
A única outra classe que precisamos criar é PetMasterLambda aquela que criará instâncias de
Pet representando cães e papagaios, mas passando implementações diferentes da Talkative interface. Aí
vem:
[Link] 89/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class PetMasterLambda {
public static void main(String[] args) {
// dogs
Pet myDog = new Pet();
[Link]([Link](dogTalkRules, "Sammy"));
// parrots
Pet myParrot = new Pet();
[Link]([Link](parrotTalkRules, "Charlie"));
}
}
Definimos regras diferentes para papagaios e cães falantes como lambdas em variáveis parrotTalkRules e,
dogTalkRules consequentemente. Não que eu não tenha especificado o tipo de dado da variável name . É
mais um exemplo de tipagem inferida - a Talkative interface tem um único método abstrato com o argumento
do tipo String . O segundo argumento do método speakup será passado para o método talk . Execute este
programa e ele imprimirá o seguinte:
JAVA
I'm a dog. My name is Sammy
I'm a parrot. Don't call me Charlie
Usando expressões lambda, consegui eliminar a necessidade de criar uma classe separada para cada animal.
Claro, isso só é possível se a única diferença entre as classes Dog e Parrot fosse a implementação do
comportamento de falar.
Gostaria de chamar sua atenção para o fato de que minha classe Pet não tem estado - ela não define nenhuma
variável de classe. Isso significa que nem precisamos criar instâncias da classe Pet , mas poderíamos
simplesmente definir seu método speakup como static e chamá-lo assim:
JAVA
[Link](dogTalkRules, "Mary")
No Capítulo 9, mostrarei mais expressões lambda enquanto explico como processar eventos de GUI , como
clicar em um botão ou mover o mouse. Na Parte 2 da tarefa em que você está prestes a trabalhar, desafiarei você
a reescrever a classe Pet para que ela mantenha as regras de conversação em sua variável de classe.
[Link] 90/303
22/03/2025, 18:48 Programação Java para crianças
3. No pacote pets recriam as versões finais das classes e Dog interfaces Fish da seção
Interfaces. Swimmable Talkable
4. No pacote pets crie uma nova classe Pet com um construtor que receberá o nome do pet (do tipo String )
como argumento.
5. Altere as declarações das classes Dog e Fish assim cada uma delas se estende Pet ao implementar
Talkable as Swimable interfaces.
6. Crie a classe PetMaster na seção "Interfaces", mas dê nomes aos animais de estimação ao instanciar as
classes Dog e Fish .
7. Modifique as implementações dos métodos talk para swim que eles imprimam o nome do animal de
estimação como parte da saída em [Link] . Por exemplo, "Meu nome é Sammy. Bark-
Bark-Bark!"
Parte 2. Nesta parte, você fará um exercício para provar que entende os conceitos básicos das expressões
lambda.
JAVA
public interface Talkative {
public String talk(String petName);
}
3. Crie uma nova versão da classe Pet com o construtor que recebe as regras de conversação e o nome do
animal de estimação como argumentos. Seu método speakup não terá argumentos. É assim que o código
do novo Pet deve se parecer:
[Link] 91/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class Pet {
String name;
Talkative myTalkingRules;
return [Link](name);
}
}
4. Escreva uma nova versão da classe PetMasterLambda que definirá regras de conversação para cães e
papagaios. Ela deve criar duas instâncias de Pet (uma para um cão e uma para um papagaio) e invocar o
método speakup em cada instância. :toc-placement!: :imagesdir: .
[Link] 92/303
22/03/2025, 18:48 Programação Java para crianças
Finally, I’ll give you a very light introduction to parallel computing using multi-threading.
One of the main features of object-oriented languages is encapsulation - the ability to hide and protect data or
code. But who do you need to hide or protect the code from? This is not a protection from bad guys who are not
allowed to see your code. You hide and protect the code from misuse. For example, another programmer
extended your class and is trying to change the value of a variable in your class, which may result in bug.
Let’s consider an example from the real world. Think of a car – most people have no clue how many parts are
under the hood, and what actually happens when a driver pushes the brake pedal. If car designers would not hide
control of some of the under-the-hood operations, the driver would have to deal with hundreds of buttons,
switches and gauges on the car’s dashboard.
[Link] 93/303
22/03/2025, 18:48 Programação Java para crianças
When you design a class, hide methods and class member variables that should not be visible from outside.
Some of the methods of member variables are meant to be used internally and not to be exposed to other classes.
We’ll start learning about hiding and protecting data with the private access level. If a variable or a method
are declared private, they can be used only within the class where they were declared. The next code sample
represents the class Car and declares some of its members as private . Note that I’ve created this class in the
package vehicles .
[Link] 94/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package vehicles;
if (useRegularBrakes==true){
useRegularBrakes();
}else{
useAntiLockBrakes();
}
}
By looking at this code I can say that the class Car exposes only one public method brake , which internally
may invoke several other functions that a driver does not need to know about. For example, if the driver pushes
the brakes pedal too hard, the car’s computer may apply special anti-lock brakes implemented in private
methods.
[Link] 95/303
22/03/2025, 18:48 Programação Java para crianças
I took the next screen shot in IntelliJ IDEA while writing a class CarMaster that uses Car . IDEA helps me
with suggesting the Car class members that I can use in this context. Only the method brake is visible from
the class Car (other methods are from the class Object ).
The private access level is the most restrictive one. If you’re not sure when to use it, just declare all of your
call member variables and methods as private, and loosen this restriction if other classes need to use these
members.
[Link] 96/303
22/03/2025, 18:48 Programação Java para crianças
What do you think will happen if you simply remove the private keyword from one of the methods of the
class Car ? Will the CarMaster see it? No, it won’t because the absence of the access qualifier gives a
package access level to this member. Only classes that are located in the package vehicles can access it, and
CarMaster is not one of them.
The class members declared with the protected keyword can be accessed from other members of the same
class, from its descendants or classes located in the same package. Even if a descendant class is located in a
different package, it’ll be able to access protected methods of its ancestors.
Some software developers are creating libraries or frameworks of classes to be used by other developers. These
classes can be extended, and their creators may use the keyword protected trying to allow access to certain
member only descendant classes. But in the real world no one can predict what the developer may want to do
with their libraries, and the keyword protected may become an obstacle in achieving of their goals. I do not
use the keyword protected in my projects. As you gain more experience with Java, see for yourself if the
keyword protected brings some value to your programs.
6.2. Casting
In Java all classes are directly or indirectly inherited from the class Object , which is the root of the class
hierarchy. In Figure 2 you’ve seen a class Car that has number of methods that we’ve never declared - they
belong to the class Object , and the class Car extends Object even though we’ve never asked for it. So any
of your application classes have an ancestor - Object .
[Link] 97/303
22/03/2025, 18:48 Programação Java para crianças
When you declare a variable to represent an instance of your class, you can give it a type either of your class or
any of its ancestors. For example, both of the following declarations are correct:
JAVA
Car myCar = new Car();
O compilador Java pode converter (cast) um tipo de dado para outro, desde que eles tenham relação de herança.
Em particular, o compilador Java pode converter automaticamente o tipo para os ancestrais da classe. Isso é
chamado de upcasting . Mas se uma variável tiver o tipo de uma superclasse, ela não verá nenhum membro da
subclasse. A próxima captura de tela mostra que a variável myOtherCar não vê o método brake declarado na
classe Car .
Mas você pode dizer, "A variável não myOtherCar aponta para a instância da classe Car , que tem um método
público brake ?" Isso mesmo, mas como declarei essa variável do tipo, Object a variável
myOtherCar assume que é apenas um objeto geral. O programador pode fazer downcast do tipo geral para um
mais específico, mas isso tem que ser feito explicitamente colocando o tipo específico do objeto entre parênteses
antes da variável de tipo mais geral, por exemplo:
JAVA
Object myOtherCar = new Car();
[Link] 98/303
22/03/2025, 18:48 Programação Java para crianças
É como se você estivesse dizendo: "Eu sei que a variável myOtherCar é do tipo `Object , mas ela na verdade
aponta para a Car instância". Agora a variável myOtherCarAfterCasting verá o método brake declarado na
classe Car :
Por que precisamos de todas essas complicações? Não podemos simplesmente declarar sempre variáveis dos
tipos específicos? Às vezes não podemos. Por exemplo, o JDK vem com muitas outras classes que foram
escritas para trabalhar com os Object tipos de dados. As classes de coleta de dados foram escritas para serem
capazes de armazenar instâncias de quaisquer objetos.
Os criadores de coleções de dados não tinham ideia de que você poderia precisar armazenar instâncias de
Car ou Fish lá. Mas quando você usa o objeto de coleção de dados em seu programa, o tipo de dado é
conhecido. Na próxima seção, você verá um exemplo de um FishTank programa que armazena instâncias da
classe Fish em ArrayList e então as converte de volta para o tipo Fish :
JAVA
theFish = (Fish) [Link](i);
[Link] 99/303
22/03/2025, 18:48 Programação Java para crianças
Pacotes Java [Link] e [Link] incluem classes que são bem úteis quando um programa
precisa armazenar várias instâncias de alguns objetos na memória. Existem dezenas de classes de coleção em
Java, mas eu vou mostrar apenas algumas delas. Algumas das classes de coleção populares do pacote
[Link] são ArrayList , HashTable , HashMap , e List .
O pacote [Link] tem coleções úteis em programas que exigem acesso concorrente
(simultâneo) a alguns dados por diferentes partes de um programa (por vários threads ). Apresentarei brevemente
o conceito de multithreading mais adiante neste capítulo, mas a cobertura de coleções concorrentes não pertence
ao livro introdutório como este.
Por que usar arrays, então? Vamos sempre usar ArrayList ! Infelizmente, nada vem de graça, e você tem que
pagar o preço por ter a conveniência de arrays de tamanho dinâmico. O ArrayList funciona um pouco mais
devagar do que um array regular. Além disso, você só pode armazenar objetos lá, enquanto arrays permitem que
você armazene primitivos também. Para criar e preencher um, ArrayList você deve instanciá-lo primeiro e,
em seguida, criar instâncias dos objetos que você está planejando armazenar lá. Adicione cada objeto ao
ArrayList chamando seu método add . O próximo pequeno programa preencherá um ArrayList com
String objetos e, em seguida, imprimirá cada elemento desta coleção.
[Link] 100/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
JAVA
Friend #0 is Mary
Friend #1 is Ann
Friend #2 is David
Friend #3 is Roy
O método get extrai o elemento localizado na posição especificada no ArrayList . Como você pode
armazenar quaisquer objetos nesta coleção, o método get retorna cada elemento do Object tipo. O programa
tem que converter este objeto para um tipo de dados apropriado. Não fizemos isso no exemplo anterior apenas
porque armazenamos String objetos na coleção friends , e Java sabe como converter um Object para um
String automaticamente.
Vamos ver como você pode trabalhar com alguns outros objetos em ArrayList , por exemplo, instâncias da
classe Fish mostrada a seguir.
[Link] 101/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package pets;
// constructor
Note that the class fields color and weight are private variables. But this class also defines public
getters and setters - the methods that read or modify the fields. In this example the setters and getters don’t
contain any application logic, but they could. For example, you could encapsulate the logic that checks the
credentials of the users of this class so not everyone can modify the weight property. By Java naming
conventions the setter name starts with the prefix set followed by the capitalized letter of the corresponding
private variable. Accordingly, the getter starts with get .
IntelliJ IDEA can automatically generate setters and getters for the class. Just right-click on
NOTE
the class name and select the options Refactor | Encapsulate Fields.
The code to add (and extract) a particular Fish to the ArrayList collection may look similar to the program
FishTank that comes next.
[Link] 102/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package pets;
import [Link];
Fish theFish;
[Link](fish1);
[Link](fish2);
First, this program creates a couple of instances of the class Fish passing the values for the fields via
constructor. Note the letter f in the weight value of the first fish: 2.5f . In Java all decimal literals have the type
double unless you mark it with the suffix f for float .
Each instance is added to the collection fishTank . Then, the program gets the objects from this collection,
casts them to the class Fish and prints their values using getters. Here’s the output of the program FishTank :
JAVA
Got the Red fish that weighs 2.5 pounds.
Got the Green fish that weighs 5.0 pounds.
The ArrayList collection uses Java arrays internally and initially creates an array for 10 elements. But if you
keep adding more elements to ArrayList it internally will create another array of the larger size and copy all
existing elements there. Because of this additional memory allocations and data copying ArrayList
collections works a little slower than arrays, which allocate enough memory in advance.
[Link] 103/303
22/03/2025, 18:48 Programação Java para crianças
While the ArrayList collection only allows referencing its elements by index (e.g. [Link](i) ),
sometimes it would be easier to reference collection elements by names as key/value pairs. I’ll illustrate by
storing my friends' contact information in a HashTable collection that allows accessing objects by key names.
Let’s declare a simple class ContactDetail , which can store contact details of one person.
JAVA
public class ContactDetail {
String fullName;
String facebookID;
String phone;
String email;
}
The program HashTableDemo will create and populate two instances of ContactDetail , will add them to
the Hashtable collection by names (the keys), and then will print the phone number of the second contact.
JAVA
import [Link];
In this example I used the first name as the key in the method put that adds elements to a Hashtable . Hence
one contact can be referred by the key get("Jackie") , and the other one as get("Art") . The method get
returns the collection element as the Object type, so I had to cast it to ContactDetail to be able to see the
field phone .
[Link] 104/303
22/03/2025, 18:48 Programação Java para crianças
HashTable requires each key to be unique. Say you have another contact named Art and will create a new
instance of the ContactDetail object. If you’ll add it to the same collection under the same key -
[Link]("Art", friend3); it’ll replace the contact details of the first Art with the data of the second
one. This happens because Java Hashtable internally generates a hash key (the number) from your key and
uses it as an index to find the element when need [Link] same names will generate the same hash keys. So either
[Link] 105/303
22/03/2025, 18:48 Programação Java para crianças
give the second Art a nickname like ArtFromNYC or use another Java collection like ArrayList to store your
contacts. By the way, ArrayList even allows you to store duplicates (objects with the same values) while
Hashtable doesn’t.
I’m not going to cover other Java collections here, but if you’d like to do your own research, read about such
collections from the [Link] package as HashMap , HashSet , and LinkedList . There is also a class
Collections that has a bunch of useful static methods to operate on your data collections (e.g. sort , copy ,
binarySearch et al.).
JAVA
ArrayList friends = new ArrayList();
you can do it with a parameter so it can store only String objects like this:
JAVA
ArrayList<String> friends = new ArrayList<>();
The parameter(s) goes in the angle brackets right after the data type. Note the so called diamond operator <> on
the right. Since you already declared the required data type on the left, there is no need to repeat it on the right -
compiler will guess the type. It’s also an example of type inference introduced in the previous lesson about
lambda expressions. Now, if by mistake you’ll try to add an object of another type to friends the Java
compiler will complain.
I was able to specify a parameter for ArrayList only because it was created with this ability. If you’ll read the
online documentation ([Link] for ArrayList you’ll see that
it’s declared as follows:
JAVA
public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
Isso <E> significa que você tem permissão para especificar um tipo de parâmetro de elementos que serão
armazenados no ArrayList . No caso da friends coleção, o compilador Java veria que nesta coleção
<String> deveria estar o <E> . A documentação online
([Link] para a classe Hashtable parece ainda mais
assustadora:
[Link] 106/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, Serializable
Mas <K,V> significa simplesmente que você pode especificar dois parâmetros: K o tipo de dado chave e V o
valor.
Vamos escrever um programa que ilustra as vantagens de usar genéricos. Vou reutilizar o exemplo da seção
anterior chamado instâncias HashTableDemo armazenadas ContactDetail . Na verdade, vou criar duas
novas versões deste programa. A primeira será chamada HashTableBrokenDemo , e mostrarei como quebrar
este programa para que ele trave durante o tempo de execução se não usarmos genéricos. Depois disso, vou
reescrevê-lo como HashTableGenericsDemo , onde usarei genéricos para mostrar como evitar que os erros de
tempo de execução aconteçam. Aqui está o programa quebrado:
JAVA
import [Link];
}
}
JAVA
"Art Jones, ajones@[Link], ajones, 212-333-2121"
[Link] 107/303
22/03/2025, 18:48 Programação Java para crianças
O compilador Java não vê crime aqui - ele Hashtable pode armazenar quaisquer descendentes da classe
Object . Mas se você executar este programa, você obterá um erro na linha que tenta converter o elemento da
coleção para ContactDetail o tipo. É assim que minha tela do IntelliJ IDEA com o erro se parece:
O programa falhou na linha 24 com o erro ClassCastException . Os erros de tempo de execução são
chamados de exceções em Java, e explicarei o tratamento de erros no Capítulo 10. Mas meu ponto principal é
que este programa travou durante o tempo de execução apenas porque eu "esqueci" que apenas os objetos do
tipo ContactDetail devem ser armazenados na coleção friends .
JAVA
Hashtable<String, ContactDetail> friends = new Hashtable<>();
Agora estou explicitamente afirmando que minha intenção é usar os String objetos para chaves, e
ContactDetail objetos como valores. O programa HashTableGenericsDemo é mostrado a seguir - ele nem
compila!
[Link] 108/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class HashTableGenericsDemo {
public static void main(String[] args) {
O compilador vai reclamar sobre a linha, onde estou tentando chamar o método put com dois String objetos
como argumentos. O compilador Java vai gerar uma mensagem de erro de que não pode aplicar dois
String parâmetros a um Hashtable que foi declarado com parâmetros <String, ContactDetail> .
Outra coisa importante a ser notada é que não há necessidade de casting quando o programa obtém as
informações sobre o telefone de Jackie. Agora, a friends coleção sabe desde o começo que ela armazena não
apenas alguns Object tipos, mas as ContactDetail instâncias.
O que alcançamos? O programa HashTableBrokenDemo nos permitiu armazenar qualquer coisa na coleção,
mas travou durante o tempo de execução, mas HashTableGenericsDemo impediu que esse erro acontecesse.
Ter um erro do compilador é muito melhor do que ter surpresas durante o tempo de execução, não é? Além
disso, com genéricos eliminamos a necessidade de lançar objetos.
Tenho usado o tipo de dado parametrizado Hashtable que foi convenientemente oferecido pelos criadores do
Java, mas você pode definir suas próprias classes com parâmetros também. Criar suas próprias classes
parametrizadas é um dos tópicos mais avançados, e não vou abordá-lo neste livro. Confira o tutorial da Oracle
([Link] se estiver interessado.
[Link] 109/303
22/03/2025, 18:48 Programação Java para crianças
Na vida real, porém, podemos fazer várias coisas em paralelo, como comer, falar ao telefone, assistir TV e fazer
o dever de casa. Para fazer todas essas ações em paralelo, usamos vários "processadores": mãos, olhos e boca.
Hoje, apenas o computador da sua avó tem um único processador (também conhecido como Unidade Central de
Processamento ou CPU). Uma CPU realiza cálculos, envia comandos para o monitor, disco rígido ou unidade de
estado sólido, computadores remotos na Internet e assim por diante. Muito provavelmente seu computador tem
pelo menos duas CPUs e uma GPU (Unidade de Processamento Gráfico) para processar gráficos, se houver.
Mas mesmo um único processador pode executar várias ações de uma vez se um programa usar vários threads .
Uma classe Java pode iniciar vários threads de execução que se revezarão para obter fatias de tempo do tempo
do processador. Por exemplo, o programa faz uma pergunta ao usuário e espera pela resposta. Enquanto isso, a
CPU pode ser usada para executar alguma outra lógica de aplicativo em vez de ficar ociosa, como mostrado na
Figura 7.
[Link] 110/303
22/03/2025, 18:48 Programação Java para crianças
Um bom exemplo de um programa que cria múltiplos threads é um navegador da Web. Por exemplo, você pode
navegar na Internet enquanto baixa alguns arquivos, então um programa (o navegador) executa dois threads de
execução (navegação e download) em paralelo.
Existem diferentes maneiras de criar threads. Não explicarei detalhes de cada método porque é um tópico bem
avançado e não é adequado para este livro. Mas listarei apenas algumas das maneiras de criar threads e as
ilustrarei com um exemplo simples. Estes são os principais métodos de escrever código a ser executado em uma
thread separada:
Você pode herdar sua classe da classe Java Thread e substituir seu método run , que deve conter o código a
ser executado em paralelo.
[Link] 111/303
22/03/2025, 18:48 Programação Java para crianças
Você pode adicionar implements Runnable à declaração de uma classe e implementar o método run ,
que, novamente, deve conter o código a ser executado em paralelo.
Em vez de herdar sua classe da classe, Thread você pode criar uma nova instância do Thread objeto
Você pode adicionar implements Callable à declaração da sua classe e implementar o método call ,
que desempenha um papel semelhante ao método run .
A maneira mais fácil de implementar multithreading é usando expressões lambda que foram introduzidas no
Capítulo 5. Como um lembrete, você pode usar lambdas para implementar interfaces funcionais - aquelas que
têm apenas um método abstrato. A interface Runnable declara um único método abstrato run , o que a torna
uma candidata perfeita para ser implementada com lambdas.
Vamos aprender por exemplo. Primeiro, vou mostrar um programa bem simples que executa todo o código
sequencialmente em um thread principal, e então vou reescrevê-lo para ser executado em paralelo.
A classe SingleThreadedDemo executa dois loops sequencialmente. Primeiro, ela imprime cinco valores de i
em potência de 4, e então cinco valores de k.
JAVA
public class SingleThreadedDemo {
public static void main(String[] args) {
}
}
O primeiro loop simplesmente multiplica a variável i para si mesma quatro vezes. No segundo loop, eu
simplesmente concateno uma String, o valor de k e um ponto de exclamação. O segundo loop começará
somente após o primeiro loop ser concluído, e não importa quantas vezes você execute este programa, a saída no
console sempre será parecida com esta:
[Link] 112/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
The value of i in power of 4 is 0
The value of i in power of 4 is 1
The value of i in power of 4 is 32
The value of i in power of 4 is 243
The value of i in power of 4 is 1024
*** The value of k is 0!
*** The value of k is 1!
*** The value of k is 2!
*** The value of k is 3!
*** The value of k is 4!
Este foi um exemplo de execução de código sequencial em um único thread. Mas as ações que fazemos em cada
loop não dependem umas das outras e podem ser executadas em paralelo, certo?
Vamos mudar um pouco esse exemplo. A classe a seguir MultiThreadedDemo executa dois loops em paralelo.
Ela cria um thread separado para o primeiro loop e o inicia em um thread separado para que o thread principal,
que tem o segundo loop, não espere o primeiro terminar.
JAVA
public class MultiThreadedDemo {
public static void main(String[] args) {
[Link](); (4)
1. Começamos o programa criando uma nova instância da Thread classe usando seu construtor que recebe
um objeto que implementa Runnable a interface.
2. Writing a lambda expression is the easiest way to implement Runnable . Note that the lambda expression
doesn’t specify any parameter. Java compiler is smart enough to guess that since the constructor of Thread
expects an instance of Runnable then our lambda expression implements this interface. The for loop
automatically becomes an implementation of the method run . This is what we want to run in a separate
thread
[Link] 113/303
22/03/2025, 18:48 Programação Java para crianças
4. To start the execution of the thread, we need to call the method start , which is defined in the class
Thread and will internally invoke the method run , which is implemented as lambda. The method start
doesn’t wait for the completion of the method run so the next line in our main method is executed.
If you run the program MultiThreadedDemo several times, it may print the output differently each time
depending on how busy is the CPU is on your computer. I ran this program several times and selected the
console output that illustrates that the code was not executed sequentially, take a look:
JAVA
*** The value of k is 0!
*** The value of k is 1!
The value of i in power of 4 is 0
The value of i in power of 4 is 1
*** The value of k is 2!
*** The value of k is 3!
*** The value of k is 4!
The value of i in power of 4 is 32
The value of i in power of 4 is 243
The value of i in power of 4 is 1024
Note that the first two lines print the output from the second loop! This means that after calling the method
start on the thread myThread the program didn’t wait for the completion of the first loop, which ran in
parallel thread. Then the first loop had something to print. Then the second, etc. The entire console output is a
mix of two parallel number-crunching threads.
You may say, is it even a real-world example? Who needs to run such simple loops in parallel? I made this
example simple to get across the message that one program can do stuff in parallel.
For a more realistic scenario think of a game with fancy graphics that needs to update the images on the screen
and perform some complex algorithms. If such a program would sequentially do the screen updates and
algorithms, the game would run slow with noticeable delays in the graphics during times when the program does
number crunching. In Chapter 8 I’ll illustrate the effect of the "frozen" screen and how to deal with it using a
separate thread for screen updates.
3. In the package contacts create the class ContactDetail that looks like this:
[Link] 114/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class ContactDetail {
private String fullName;
private String facebookID;
private String phone;
private String email;
Note that I’m overriding the method toString that exists in the class Object .
4. In IntelliJ IDEA right-click on the class name and select the options Refactor | Encapsulate Fields to
generate public getters and setters for all fields.
5. In the package contacts write a program MyContacts that will declare and instantiate an ArrayList
called friends it should allow only the objects of type ContactDetail .
6. Create two or more instances of ContactDetail object and populate them with your friends' data using
setters.
7. Add all instances of ContactDetail to the friends collection by using the method add .
8. Write a for-each loop that will iterate through the collection friends and print all their contact information by
simply printing each object from the collection friends . Since the class ContactDetails has an
overriden method toString , you can simply print the objects as shown below - the method toString
will be invoked automatically:
JAVA
for (ContactDetail friend: friends){
[Link](friend);
}
9. The output of the program MyContacts should look similar to this one:
JAVA
Name: Jackie Allen, Facebook ID: jallen, phone: 212-545-5545, email: jallen@[Link]
Name: Art Jones, Facebook ID: ajones, phone: 212-333-2121, email: ajones@[Link]
[Link] 115/303
22/03/2025, 18:48 Programação Java para crianças
Java has an older library of GUI components called Swing ([Link] and the
new one called JavaFX ([Link] We’ll use only JavaFX in
this book. JavaFX is also a library that’s included with JDK, and you can write your GUI programs using
familiar Java language. On the other hand, JavaFX allows you to create and arrange GUI components in a
special FXML format, while writing application logic in Java.
In this chapter I’ll explain the basics of GUI programming with JavaFX. You’ll learn how to create GUI
containers and arrange GUI components inside them. In the next chapter you’ll learn how to write code that
reacts on user’s actions (a.k.a. events) like a click of a button or a mouse move.
By the end of this chapter you should be ready to work on the following assignment: "Create the GUI for a
calculator that will look similar to this one":
[Link] 116/303
22/03/2025, 18:48 Programação Java para crianças
With the help of the visual layout tool called Scene Builder, where you’ll be dragging and dropping
components on the window and saving the design in the FXML format in a file with extension .fxml. Then
the Java program will load this .fxml file and display your creation.
I’ll show you both ways, but let’s start with some basics of development with JavaFX. Let’s set the stage -
JavaFX uses theater terminology.
[Link] 117/303
22/03/2025, 18:48 Programação Java para crianças
IntelliJ IDEA will help you to get started quickly. Just create a new project (the menu File | New Project), select
JavaFX application as the project type and give it a name. In a second new project will be created with two Java
classes Main and Controller and a file named [Link] as shown below.
The Main class of a JavaFX application extends Application and is an entry point of your application.
JavaFX classes are located in the packages whose names start with javafx (e.g. [Link] and
[Link] ).The main method invokes the method launch from Application , which creates a stage
by calling its method start , which was was declared as abstract . Hence, we must override start in our
Main class. When the method start is invoked, it’ll receive a reference to the Stage object - this is where
your GUI components will live and perform.
Pretend that you’re a play director and need to set up one or more scenes (views) on stage. But if in a real scene
you’d expect to see some chairs, tables and other pieces of furniture, each JavaFX scene consists of GUI
containers and components. In JavaFX you’ll create components, add them to the scene and then add a scene to
the stage. When the stage is ready, open the curtain by calling the method show .
All GUI components are subclasses of the class [Link] , and when I’ll be using the word node
just think of a GUI component. Now you have a choice: create these nodes using Java classes or load the pre-
created design from the .fxml file as it was done in the code generated by IDEA.
The method start loads the file [Link], sets the title of the stage and creates a Scene 300 by 275
[Link] content of the generated [Link] looks like this:
[Link] 118/303
22/03/2025, 18:48 Programação Java para crianças
XML
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<GridPane fx:controller="[Link]"
xmlns:fx="[Link] alignment="center" hgap="10" vgap="10">
</GridPane>
FXML is a markup language based on XML (a popular data presentation format). The idea is to separate the
creation of the GUI in a declarative language (FXML) from the application logic (Java). If we didn’t use IDEA,
the FXML would be generated by the Scene Builder itself. In FXML the GUI is represented by tags in angle
brackets, e.g. <GridPane> . Each tag has a matching closing tag that starts with a forward slash, e.g.
</GridPane> and may have attributes (e.g. alignment="center" ). The <GridPane> tag corresponds to
the Java class GrindPane , which is one of the JavaFX layouts - I’ll explain them very shortly. Every FXML tag
has a corresponding Java class behind it.
The generated Java class Controller has just the pair of curly braces at this point, but in the next chapter
we’ll be writing the application logic there. Later on you’ll connect the generated FXML views with the Java
code of the Controller . Run the Main program and it’ll show an empty window shown next:
HBox
[Link] 119/303
22/03/2025, 18:48 Programação Java para crianças
VBox
FlowPane
GridPane
BorderPane
StackPane
TilePane
AnchorPane
The HBox class (the horizontal box) places controls in a row next to each other. The vertical box VBox places
controls vertically. The FlowPane places the nodes in a row and then wraps to the next row if there is no room
left in the current one.
The GridPane allows to arrange UI controls in rows and columns and assign constraints (properties) to each
cell.
The BorderPane splits the scene into five regions, which are called left , top , right , bottom , and
center .
The TilePane layout is similar to the FlowPane , but it places each GUI components in a cell of the same size
similarly to tiles on the wall. Say, you need to display several images in a tile layout. Adding the ImageView
components to the TilePane will shows them as tiles next to each other.
The StackPane layout works as a deck of playing cards - only one child node will be shown at a time covering
the other nodes.
The AnchorPane lets you to anchor nodes at left, top, right, and bottom of the scene. Imagine a music player
application with the buttons Rewind on the left and the Fast Forward on the right. For example, the AncorPane
allows you to force the Rewind button to always remain at 20 pixels from the left border of the window and 10
pixels from the bottom even when the window resizes. For that you can use the leftAnchor and
bottomAnchor properties. For example,
JAVA
[Link](rewindBtn, 20);
[Link](rewindBtn, 10);
Components that are located in a container are considered children of this container. Accordingly, a container is
called a parent of these components. If you’d be writing the code manually in Java, you’d be going through the
following steps with any layout:
[Link] 120/303
22/03/2025, 18:48 Programação Java para crianças
2. Create an instance of the selected layout class (e.g. HBox ). This instance will serve as a container and a
layout manager for all child nodes that you’ll add to it.
3. Add the child nodes to the container using either the method add() or addAll() .
4. If this layout instance needs to be used inside another layout (e.g. an HBox can be placed inside the
BorderPane ) add the instance created in Step 1 to the parent container by using the method add() .
In this chapter we’ll use only some of the JavaFX layouts, but for detailed coverage of layouts visit Oracle
tutorial at [Link]
It’s easier to create layouts and components using a visual tool, and this is what we’ll do next.
You can start the Scene Builder either independently or from IDEA. For example, if you right-click on the
[Link] file in your newly generated IDEA project it’ll show you a popup menu, which includes the item
Open in SceneBuilder. Select this item. The very first time IDEA will ask you to confirm the location of Scene
Builder application on your computer. Then it’ll open [Link] in Scene Builder. This is how it looks on my
computer:
[Link] 121/303
22/03/2025, 18:48 Programação Java para crianças
On the left panel you can select containers, controls, menus, shapes and drag and drop them onto the central
canvas area. Note the GridPanel layout shown at the bottom left - the arrangement of GUI components inside of
this scene will be controlled by GridLayout . Let me select the Button from the Controls section on the left and
drop it on the canvas in the middle. The Screen Builder’s window will look like this:
The right panel allows you to change the properties of this button. These little boxes with the digit one represent
so called row and column constraints - we’ll discuss them shortly.
The Scene Builder’s menu Preview | Show Preview in Window will show how your GUI will look during the
runtime. So far our one-button screen is not too fancy, and this is how it’s preview looks like:
Let’s save the changes in [Link] (menu File | Save) and open this file in the IDEA text editor. When IDEA
generated [Link] there was no content between <GridPanel> and `</GridPanel>`in the generated
[Link], but now there is:
[Link] 122/303
22/03/2025, 18:48 Programação Java para crianças
XML
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
I’ll go through the details of the GridPane layout in the next section, but please note that Scene Builder created
some tags to specify the constraints for the rows and columns of the grid. The Button component is placed
inside the grid in the cell located in the intersection of the column 1 and row 1.
GridPane divides the area into rows and columns and places GUI components (the nodes) into the grid cells.
With GridPane layout cells don’t have to have the same size - a node can span (be as wide or as tall as several
others). If the screen size changes, the content won’t be rearranged and will maintain the grid look.
Before placing the node into a particular cell you have to specify the grid constraints such as rowIndex and
columnIndex (the coordinate of the cell, which starts with 0,0). The rowSpans and columnSpan allow you
to make the cell as wide (or as tall) as several other cells. The GridPane documentation
([Link] describes lots of various constraints that
can define the behavior of each cell’s content if the windows gets resized. I’ll show you a basic example that
uses some of these constraints.
[Link] 123/303
22/03/2025, 18:48 Programação Java para crianças
I’ll start with creating a new IDEA JavaFX project (menus File | New Project | JavaFX Application) giving it the
name Signin . The project with classes Main , Controller and the file [Link] will be generated. Let’s
rename this FXML file into [Link]. IDEA will automatically change the corresponding line in the Main
class to load this file instead of [Link]:
JAVA
Parent root = [Link](getClass().getResource("[Link]"));
Rename the package from sample to signin (right-click menu, Refactor | Rename). Now open the file [Link]
in Scene Builder and start thinking about laying out the components of our Sign In scene. Let’s take another look
at the image of the Sign In window. I can clearly see that GUI components are placed in three rows. The first two
have a Label and TextField and the third one has a wide Button . I can also recognize two columns in the
layout of the Sign In window. The first column has two Label components and the left side of the Button .
The second column has two TextFiled components and the right side of the Button . We can also say that
the Button spans two columns. We’ve got a 2x3 grid!
Open the generated [Link] in Scene Builder. Since this file has already empty <GrigPane> tag, you’ll
see GridPane(0,0) as the root of the hierarchy in the bottom left corner as in Figure 4 above. So far this grid has
zero rows and zero columns. Right-click on the grid in the middle of the screen and add three rows and two
[Link] 124/303
22/03/2025, 18:48 Programação Java para crianças
columns to the grid by using the right-click menus GridPane | Add Row Below and Add Column After. When the
GridPane is selected The Scene Builder’s window may look similar to this:
Now let’s drag two Label controls and a Button from the Controls section on the left and drop them into the
appropriate cells in the first grid column. Change the text on these components to be UserID:, Password, and
Sign In. Then we could drag and drop two TextField objects in the top two cells in the second column.
Actually, it’s not a good idea to enter password in the clear text. I’ll use the TextField for the user ID, and the
PasswordField (it marks user’s input) for password.
[Link] 125/303
22/03/2025, 18:48 Programação Java para crianças
Note that the hierarchy of nodes is shown in the bottom left panel of Scene Builder. If you want to change the
properties of a component on a scene with a complex GUI layout it might be easier to select the GUI control in
the Hierarchy panel than in the design area in the middle. Now select the menu Preview | Show Preview in
Window and you’ll see the following window:
This window doesn’t look exactly as we wanted: there are some issues with alignments, there is no spacing
between the container and components, and the button Sign In doesn’t span. But on the bright side, the
GridPane controls the layout and if you’ll try to stretch this window, GUI components won’t change their
[Link] 126/303
22/03/2025, 18:48 Programação Java para crianças
relative positioning:
Let’s do a couple of more property changes before we’ll run this application from IDEA. In Scene Builder the
Properties panel is located on the right and has three sections: Properties, Layout, and Code, and you’ll find the
properties to be changed in one of these sections.
1. On the left panel of Scene Builder select the GridPane and on the right panel change alignment to be
TOP_LEFT .
2. Enter 10 for the padding on top, right, bottom and left for the GridPane . We need some spacing between
the borders of the scene and the grid.
3. Select the Button on the left and then change the column span to be 2 and the preferred width to be a large
number, say 300. This will make the button wide.
4. Select the first column of the grid row by clicking on the little 0 on top of the grid. Set the both preferred
and maximum width for this column to be 70.
[Link] 127/303
22/03/2025, 18:48 Programação Java para crianças
5. Select the second column of the grid row by clicking on the little 1 on top of the grid. Set the both preferred
and maximum width for this column to be 100.
After you do all these changes and save them, the file [Link] will look like this:
XML
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
In the <GridPane> section you see <rowConstraints> and <columnConstraints> tags defining the the
properties of the rows and columns. The <children> section contains the declaration of GUI components that
the user will see on the screen: <Label> , <Button> , <TextField> , and <PasswordField> . The
<Insets> section ensures that there is some space between the grid borders and its children.
This is a declarative way of creating GUI in FXML. No Java coding was required to create the GUI for this
application.
Finally, let’s set the size of the stage so it can accommodate all components from our scene. In IDEA, open the
class Main , and in the code set the size of the scene to be 200x150 pixels.
[Link] 128/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
[Link](new Scene(root, 200, 150));
Run the Main program and you’ll see the window that looks similar to the one in Figure 7 above. The work that
we’ve done in Scene Builder was a little tedious, but it didn’t require any knowledge of Java. This means that
this work can be given to a UI designer, while you’ll concentrate on programming the application logic in Java.
[Link] 129/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class GridPaneSample extends Application {
[Link]().addAll(userIdLbl, userIdTxt,
userPwdLbl, userPwdTxt);
After all your efforts in Scene Builder, this Java program shouldn’t be difficult for you to understand. As you see,
I use classes named similarly to FXML tags. FXML tags can have attributes (e.g. vgap="10" `), and in
Java you’d need to call the corresponding setter (e.g. `[Link](10) ). So the choice is
yours - FXML or Java. If you have visual personality use FXML, otherwise use Java.
[Link] 130/303
22/03/2025, 18:48 Programação Java para crianças
Separating the work of programmers and designers became popular in Web applications. Cascading Style Sheets
(CSS) is a special language for styling UI. Styles of GUI components are stored in separate .css files and are
loaded and applied to components by the application’s code. Sometimes this process is called skinning - you can
create an application that can "wear different skins" changing its look to the user’s liking. JavaFX has a default
skin, and if you’re interested in how to create custom skins, visit Oracle online tutorial Skinning JavaFX
applications with CSS ([Link]
Even if you won’t create your own CSS file, your JavaFX application applies default CSS style to the
components of your view. In Scene Builder you can see these styles. Just select any component and then go to
the menu View | Show CSS Analyzer. You’ll see a number of styles the start with the prefix fx- , which makes
JavaFX CSS a little different from a standard CSS syntax.
Covering CSS in detail would require a separate book, but I’ll show you a simple example of how the look of the
GUI can be changed without the need to modify the Java code.
You can either create so-called CSS selectors to style a specific GUI component, a type of components (e.g. all
buttons), or create a reusable style that can be applied programmatically to a selected component.
To style a specific component it has to have a unique id. If you program GUI in Java, set in your Java code using
the method setId() , for example:
JAVA
Button signInBtn = new Button ("Sign In");
[Link]("submitBtn");
XML
<Button id="submitBtn" text="Sign In">
For a button with an id submitBtn you can add the following section to the CSS file to make its background
color red:
[Link] 131/303
22/03/2025, 18:48 Programação Java para crianças
CSS
#submitBtn{
-fx-background-color: red;
}
You can find the names of the main CSS colors online ([Link] In CSS
the id type selectors start with the #-sign as in #submitBtn .
If you want to apply a style to several components of the same type, you need to define a type selector. For
example, to make the text of all Label components red, you can define the following CSS type selector:
XML
.label{
-fx-text-fill: red;
}
Note that CSS type selectors start with the dot. To create a CSS class selector that can be applied to any
component, define the selector with an arbitrary name and apply it programmatically to the components of your
choice. For example, you can specify the class selector .blueLable :
XML
.bluelabel{
-fx-text-fill: blue;
-fx-font-family:verdana;
-fx-font-style:italic;
}
This class selector defines the rules that will display text of the component in blue bold verdana font in italic
style. Typically, you’ll be loading the entire CSS file when the application starts so all styles are available for
use. If you use Java for GUI programming, you can apply a class selector to a specific button just like this:
JAVA
Label userPwdLbl = new Label("Password:");
[Link]().add("bluelabel");
In FXML assigning a CSS class selector is done by adding the attribute styleClass to the tag element:
XML
<Label text="Password:" styleClass="bluelabel" [Link]="1" />
You may ask, "How am I supposed to know which style properties are available for a given JavaFX
component?" All JavaFX styles are described in the online document titled "JavaFX CSS Reference Guide"
([Link]
Let’s learn how to apply all these styling techniques to the Sign In window from the previous section. Using
IDEA menu File | New create a new file [Link] in Signin project. Then add the following content to it:
[Link] 132/303
22/03/2025, 18:48 Programação Java para crianças
CSS
#submitBtn{
-fx-background-color: lightskyblue;
-fx-font-family:verdana;
-fx-font-size:20;
-fx-font-weight: bold;
-fx-stroke:navy;
-fx-font-style:italic;
-fx-border-radius: 20;
-fx-background-radius: 20;
-fx-padding: 5;
}
.label{
-fx-text-fill: red;
}
.bluelabel{
-fx-text-fill: blue;
-fx-font-family:verdana;
-fx-font-style:italic;
}
To apply this CSS file to our Sign In application add the attribute id="submitBtn" to the <Button> element
in [Link].
Finally, in [Link] load the [Link] and apply it to the scene. The new version of [Link] will
look like this:
[Link] 133/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = [Link](getClass().getResource("[Link]"));
[Link]("Sign In");
[Link](scene);
[Link]();
}
Run the Main application and you’ll see a differently styled Sign In window:
When the application starts loading our CSS file it sees that all labels must be red because of the type selector for
labels. But then the application notices a more specific style for the Label Password:
styleClass="bluelabel" , so it paints the text Password in blue.
[Link] 134/303
22/03/2025, 18:48 Programação Java para crianças
Each of these regions can contain either a single GUI component or a container that will have "children" -
components allocated in their own container, e.g. inside a GridPane . You’ll use BorderPane layout with a
nested GridPane while working on the calculator following instructions from the Project section at the end of
this chapter. Meanwhile, let’s create a very basic window illustrating how the BorderPane layout works.
Open Scene Builder and create a new FXML file by selecting the menu File | New. Then drag the BorderPane
from the left and drop in the middle. Click on the BorderPane and you’ll see a screen that can look as follows:
Now select Insert TOP at the bottom left, and then drag and drop a Label from the Controls section onto the
middle section of Screen Builder. Set the label’s title to "This is the Header". This text will be displayed at the
top.
Select Insert LEFT and then drag and drop VBox from the Containers area to the left side of the middle section
of the Screen Builder. The VBox is a container for arranging GUI components vertically, which is what we need
for creating a navigation menu. You’ll see an empty gray area on the left.
[Link] 135/303
22/03/2025, 18:48 Programação Java para crianças
Now select VBOX at the bottom left and add a couple of menu items to the empty VBox . Drag a Button from
the Controls section and drop it onto the VBox . Change its text to read "Menu 1", and make it a little wider so it
fits the VBox nicely. Add two more buttons labeled "Menu 2" and "Menu 3".
Our left navigation bar has a menu that’s implemented as buttons. In Chapter 10 while developing a Tic-Tac-Toe
game I’ll show you how to create real menus.
[Link] 136/303
22/03/2025, 18:48 Programação Java para crianças
Let’s add a footer to the window now. Select Insert BOTTOM at the bottom left and then drag the HBox from
the Containers area to the middle section. It’ll look like a gray area at the bottom. Adjust its height so the footer
doesn’t take too much real estate in our scene. Now add three Hyperlink components from the Contols section
to the footer and set their text to "Link 1", "Link 2", and "Link 3" correspondingly. The Scene Builder’s window
should look like this:
Select the menu Preview | Show Preview in Window will help you to see how the window will look during the
runtime:
[Link] 137/303
22/03/2025, 18:48 Programação Java para crianças
Of course, this window may need more work on styling controls and adjusting sizes and alignments, but as long
as you understand how to lay out a scene, they shouldn’t be too difficult. Creating and applying CSS styles can
make this windows a lot prettier.
Save the layout in a file [Link] using Scene Builder’s menu File | Save. While you’ve been dragging and
dropping components, Scene builder was working hard generating the corresponding FXML code in [Link].
If you open this file in any text editor, its content may look similar to this:
[Link] 138/303
22/03/2025, 18:48 Programação Java para crianças
XML
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link].*?>
Don’t be overwhelmed with the amount of tags and attributes in the above code. You can identify the regions of
the BorderPane layout. The <top> region contains a label, while the left and <bottom> regions have
containers with their own layouts. In this example I have not used the <center> and <right> regions.
Typically your program will be changing the content of the central area based on the user actions. For example,
if the user clicks on the "Menu 1" button in the left region, JavaFX will generate a clicked event and you’ll show
the content required for this selection in the central area.
You’ll learn how to process events in the next chapter. Now it’s time to practice in working with combined
layouts
[Link] 139/303
22/03/2025, 18:48 Programação Java para crianças
Most of the calculators have a display field on top and the buttons just below it. As you can see on Figure 1, the
grid with buttons has four columns and six rows. The default GridPane contains two columns and three rows.
You’ll need to right-click on the grid and use the menus GridPane | Add Row Above and Add Column After to
until you see a 4x6 grid as shown below.
Note that I set the Padding property to be 10 for all sides of the grid and the Hgap and Vgap to 5 (the gap
between the cells).
Save the layout in the file [Link]. Then drop a Button into the top left cell of the grid. Set the Margin
property to 5 for each side of this button. This is the distance between the button and cell borders. Drag the
button’s border to make it larger. This is what you should see:
[Link] 140/303
22/03/2025, 18:48 Programação Java para crianças
If you’re curious how this button looks in the [Link], open this file in any text editor and note the section
<children> that in my case looks like this:
XML
<children>
<Button mnemonicParsing="false" prefHeight="37.0" prefWidth="132.0" text="Button">
<[Link]>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</[Link]>
</Button>
</children>
There is no indication of the cell (0,0) because zeros are the default values for [Link] and
[Link] properties. Now you need to replicate this button in other cells. You can use multiple
Ctrl-C/Ctrl-V commands and then drag/drop the buttons into other cells. See how the content of the
[Link] changes as you add more buttons. I find it faster to copy/paste the generated code in the FXML
file than using Scene Builder for mass duplication.
Note that in Figure 7.1, the button with coordinates (0,5) spans two columns, and the button with coordinates
(3,4) spans two rows. For these buttons you’ll need to enter 2 as the row (or column) span, and select
MAX_VALUE as maximum width (or height). This is what you should see by now:
[Link] 141/303
22/03/2025, 18:48 Programação Java para crianças
Change the text of each button to look Figure 7.1, and the layout is done.
Then create a new JavaFX project Calculator in IDEA and replace the generated [Link] with
[Link] created by Scene Builder. Modify the generated class Main to use [Link]. Rename the
package from sample to mycalculator. Set the size of the scene to be large enough to accommodate your design.
This is how my class Main looks like:
JAVA
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = [Link](getClass().getResource("[Link]"));
[Link]("My JavaFX Calculator");
[Link](new Scene(root,650,600));
[Link]();
}
[Link] 142/303
22/03/2025, 18:48 Programação Java para crianças
Run the Main program from IDEA to ensure that your calculator looks as expected. Don’t allow the users to
resize your calculator by invoking the method setResizable on the stage object.
Then create a CSS file to add some cool styling to the calculator’s buttons. Save the CSS file in your IDEA
project and modify the code of the Main class to use your CSS file similarly to how it was done in the section
"Styling With CSS" above. Make your calculator look better than mine - it’s not too difficult.
After completing this assignment your buttons won’t work just yet. In the next chapter you’ll learn how to make
the buttons (or other components) to react to user actions, so you’ll be able to complete the calculator. In this
chapter my goal was to introduce you to basic rules of designing JavaFX GUI with the help of Scene Builder.
Watch this YouTube video ([Link] to see how easy it is to design more
complex views with Scene Builder. :toc-placement!: :imagesdir: .
[Link] 143/303
22/03/2025, 18:48 Programação Java para crianças
When IDEA creates a new JavaFX project it generates an empty class Controller , which is the right place for
the code that communicates with GUI components. In this chapter we’ll establish a link between GUI and the
controller. We’ll also add event handlers and will write code to modify the GUI. I’ll continue working with
FXML samples created in the previous chapter, but this time the GUI events will be handled by the code from
the controller class.
You’ll learn how data binding can automatically update the properties of a GUI component if a property of a
Java controller class changes. I’ll also show the difference between wrong and the right way of updating the GUI
to make the used interaction more responsive.
8.1. Events
JavaFX applications have to deal with various events. For example, a button click, the movement of the mouse
etc. When the event happens, the event object is represented by one of the subclasses of the class Event located
in the packages [Link] and [Link] . You need to decide what events are important to
your program and, as the programmers say, "listen to these events". You’ll always write event handlers (a.k.a.
event listeners) in Java, but there are different ways of assigning event handlers to GUI elements. If your GUI is
designed using FXML, you’ll need to specify the name of your controller class right in the FXML file. If your
GUI is designed with Java, using a separate controller class is not a must, but is a good idea if your code has to
process multiple events.
[Link] 144/303
22/03/2025, 18:48 Programação Java para crianças
You can create an instance of your controller class either with the new operator or inject it into Java code. I’ll
explain what injection means in a bit.
In Scene Builder you may have noticed the Controller bar in the bottom left corner. This is the place were you
can specify a Java class that will contain event handling code and may use other classes implementing
application logic. You can also open your .fxml file in the text editor and type in the name of the controller
class there. If you’ll look at any of the FXML files from Chapter 7, you’ll see that the name of the controller was
specified there when IDEA generated the project for us.
XML
<GridPane hgap="10" vgap="10"
xmlns="[Link] xmlns:fx="[Link]
fx:controller="[Link]">
[Link] 145/303
22/03/2025, 18:48 Programação Java para crianças
The hgap and vgap attributes specify the padding between the grid columns and rows. The xmlns attributes
specify so called namespaces required for proper parsing of FXML files. And the attribute fx:controller
specifies the full name of the class Controller , which in our project is located in the package signin .
When the file [Link] is loaded, FXMLLoader creates an instance of the Java class based on the FXML
content and then instantiates and injects the`[Link]` object into the GUI object. The word inject
describes the process when a runtime automatically instantiates a class B and makes it available in class A. For
us it means that there is no need to manually create an instance of the [Link] by using the new
operator.
JAVA
package signin;
import [Link];
The class Controller uses the class ActionEvent from package [Link] , and I want to warn you -
be careful when IDE will offer to insert an import statement for you. There is also an ActionEvent in the
package [Link] , which we don’t want in JavaFX applications.
We want the method signInClicked to be called on the controller if the user clicks on the button. For this to
happen, we can specify the name of this method as a handler of the onAction property in the <Button>
element in [Link] as shown on Figure 8-2.
[Link] 146/303
22/03/2025, 18:48 Programação Java para crianças
If you run the Main program and click the Sign In button three times, the console will print the hello message
three times as shown on Figure 8-3.
So there is a link between the GUI and the controller. If we had several buttons on the GUI, we could either map
each of them to a separate method in controller, or have one method for all buttons with the code recognizing
which button was clicked. The controller will invoke your event handler providing the ActionEvent object as
an argument. Its property target identifies the target of the event, which is a Sign In button in our case.
I ran our application in the debug mode just to show you that the target property on the ActionEvent
correctly recognizes the event target shown in Figure 8-4.
[Link] 147/303
22/03/2025, 18:48 Programação Java para crianças
The ActionEvent has another property called source , which has the same value as target in our
application. There are cases when source and target are different because an event travels through all
containers until it reaches the target. Then it bubles up through all the containers. This is an advanced topic, but I
still want to give you an illustration.
While handling button clicks, you don’t really care where exactly inside the button was the mouse pointer when
the user clicked on the button. So handing ActionEvent was sufficient. But there is another event called
MouseEvent , which gives you more details on the click event like the coordinate of the mouse pointer, or if
some of the keys were down during the click.
In [Link] you’re allowed to use onMouseClicked instead of onAction for the button. But if you do
so, the Button will be considered a container for a special skin class LabeledText with the text Sign In, and
if you click on the words Sign In the source of the event will be Button , and the target would be the class
LabeledSkin . Just for the illustration purposes, I’ve created an event handler signInMouseClicked and ran
it through a debugger. Now the source and target of the event are different.
[Link] 148/303
22/03/2025, 18:48 Programação Java para crianças
To read the values from GUI components we’ll need to give them unique id’s in the FXML file. We don’t need
to give id’s to all components - only to those that we want to process in the controller’s code. Take a look at the
<childrens> section of [Link] :
XML
<children>
<Label alignment="CENTER" text="User ID:" />
<Label text="Password:" styleClass="bluelabel" [Link]="1" />
<Button id="submitBtn" mnemonicParsing="false" prefWidth="300.0" text="Sign In"
[Link]="2" [Link]="2"
onAction="#signInClicked"/>
<TextField [Link]="1" fx:id="id" />
<PasswordField [Link]="1" [Link]="1" fx:id="pwd"/>
</children>
[Link] 149/303
22/03/2025, 18:48 Programação Java para crianças
Only the TextField and PasswordField have the attribute fx:id - this is how you can assign id’s in
FXML. The next step is to inject references to these GUI components into the variables in the Controller
class. The following code fragment shows how to inject component references into the id and pwd fields. I’ve
declared two Java variables in the Controller class with the names that match those from [Link] :
JAVA
@FXML private TextField id;
Java has so called annotations ([Link] (not covered in this book). They
start with the @ sign and can be placed in front of the variable, class, or a method declaration depending on how
the annotation was defined. Some annotations are used by Java compiler, and some by the JVM. The JavaFX
annotation @FXML instructs runtime to inject the references to the specifies GUI objects into the variables.
In other words, JavaFX runtime will read the first line as follows: "I need to get the object that I created after
loading [Link] file, and find the component with fx:id="id" inside this object. Finally, I need to
insert the reference to this component into the Java variable id ". The same applies to the variable pwd .
The rest is easy. Just use the injected values in your event handler. The code of our Controller is shown next.
Its method signInClicked checks the value entered in the User ID field in the GUI, and if it’s not equal to
"Yakov", then the code sets the background of the GUI component to the light pink color.
JAVA
public class Controller {
if (!"Yakov".equals(userID)){ (3)
[Link]("-fx-background-color:lightpink;"); (4)
} else{
[Link]("-fx-background-color:white;"); (5)
}
[Link] 150/303
22/03/2025, 18:48 Programação Java para crianças
3. Has the user not entered Yakov in the User ID field? We use the negation operator ! here.
4. Set the background color to lightpink if the entered user id is not Yakov. You can find major CSS color
names at [Link]
5. Set the background color to back to white if the entered user id is not Yakov.
If you run the Main program and enter the wrong user id, the window will look as follows:
You can provide event handling code to the convenience methods using anonymous inner classes, lambda
expressions, or method references ([Link] (not
covered in this book). Implementing event handlers as lambda expressions is easier than with anonymous inner
classes. Typically, you’ll be writing code to react if an event has happened. For example, if you have a button
represented by a variable myButton you can write an event handler for the click event:
[Link] 151/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
Button signInButton = new Button("Sign In");
[Link](evt ->
[Link]("The Sign In button was clicked.")
);
You’ve been introduced to lambda expressions in Chapter 5. The above code snippet means that lambda
expression gets the event object as an argument, but doesn’t really use its values but just prints the message that
the Sign In button was clicked.
What’s the type of evt argument? Java compiler will figure it out automatically. Since the method
setOnAction expects to get the ActionEvent object from the JVM, the compiler guesses that the type of
evt is ActionEvent so you don’t even need to write it in the program code. You’ve seen a similar example of
type inference in Chapter 5.
To bring all pieces of the puzzle together, I’ll show you another version of the Sign In application that will look
the same, but won’t use FXML - everything will be programmed in Java. The following class MainPureJava
and the file [Link] are all we need for programming the functionality of our Sign In window. There is not
need to use [Link] or [Link] in this case.
[Link] 152/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package signin;
import [Link];
import [Link];
import [Link];
import [Link].*;
[Link]().addAll(userIdLbl, userIdTxt,
userPwdLbl, userPwdTxt); (5)
[Link] 153/303
22/03/2025, 18:48 Programação Java para crianças
[Link](scene); (9)
[Link]();
}
1. This programs uses the GridPane layout with three rows and two columns. Since the Sign In button will
span two columns, I declared a final variable TWO_COLUMN_SPAN that will be used when the button will be
added to the grid.
4. To add the labels and text fields to the proper cells of the first two rows of the grid, I set the constraints on
the GridPane object.
5. The GUI components for the first two rows are instantiated, constraints are set so I add them as children to
the root of the scene graph - the GridPane .
6. Now I create the instance of the Sign In button and give it an id. This was explained in the "Styling with
CSS" section in Chapter 7.
7. This lambda expression implements the application logic to be invoked as a reaction to the ActionEvent .
8. We create a scene object and apply the CSS to it. This is probably the first time you see so called method
chaining. All these lines that starts with dots are methods chained together - all of them are sequentially
invoked on the scene object.
9. Finally, the scene is added to the stage and the curtain goes up.
Some programmers prefer working GUI designer tools where they can drag and drop components. Some prefer
writing Java code for UI. I like the declarative way of designing GUI components with FXML, because it’s just
more productive. The fact that FXML separates the screen design from the application logic is great because
[Link] 154/303
22/03/2025, 18:48 Programação Java para crianças
even a person who doesn’t know programming (e.g. a UI designer) can master Scene Builder and create nice
GUI layouts allowing programmers to take care of application logic.
Imagine that you’re developing a multi-player game that has a Java object receiving the moves of other gamers
from a central server. When a Java object receives a new move, you need to modify the content of the
corresponding GUI component of the game. With JavaFX you can simply bind a property of a Java class that
stores player’s moves (e.g. playersMove ) to the property of, say a Label component on the GUI. No more
coding is required. As soon as the playersMove value changes, the Label will be automatically updated.
JavaFX properties greatly simplify the synchronization of the data and the GUI.
Existing implementations of the Property interface add the change notification functionality to regular class
attributes. The interface Property declares the following methods: bind , unbind , bindBidirectional ,
unbindBidirctional , and isBound . You can bind to a JavaFX property only the value of an
ObservableValue type, which is explained in the sidebar.
[Link] 155/303
22/03/2025, 18:48 Programação Java para crianças
MVC stands for Mode View Controller. This design pattern recommends separating the code that stores
application data (Model) from the code implementing the user interface (View) and from the code that
controls the data exchange and implements application logic (Controller). As a matter of fact we’ve
almost implemented MVC in one of the versions of the Sign In application. The file [Link] was a
view, and the class Controller played a role of a controller. Since this example had just two variables
( id and pwd ) we didn’t create a special model class for them.
Observer design pattern is used to implement scenarios when one object, a.k.a. the observer needs to
watch changes in other object(s), the observables. For example, if a Twitter user (the observable) posts a
twit all of his followers (observers) will get notified. If a programming language or a library supports data
binding, implementing the observer design pattern becomes pretty easy, which you’ll see later in this
chapter.
If you’re interested in detailed coverage of design patterns, get the book "Head First Design Patterns"
published by O’Reilly Media.
Classes that implement Property interface are located in the package [Link] . For each
property type there are two classes: one that allows only reading property values and the other one for read and
writing (changing the values). For example, if you need a String property, use either
ReadOnlyStringWrapper or SimpleStringProperty . Similarly named classes exist for other data types
and some collections too.
As we always do in this book, let’s learn by coding. I’ll continue adding features to our Sign In application. This
time I’ll add a Label component with fx:id="errMsg" to the view in FXML file to display sign in error
messages, if any. In the controller class I’ll add the corresponding variable errMsg and will inject a reference to
the Label into this variable.
The next step is to declare a bindable property signinError in the class Controller that will get the value
of the error message if any. But since a regular String can’t be bindable, we’ll use the data type
SimpleStringProperty
Finally, I’ll bind the label to the variable to insure that an error message is immediately displayed on the screen
as soon as its value changes.
Let’s place an additional Label component at the bottom of the Sign In window. I’ll add another row to the
GridPane and place a Label there that will span two columns. This label will have fx:id="errMsg" and
initially won’t have any text - it’ll be invisible. The <children> section of the FXML file will look as follows:
[Link] 156/303
22/03/2025, 18:48 Programação Java para crianças
XML
<children>
<Label alignment="CENTER" text="User ID:" />
<TextField [Link]="1" fx:id="id" />
<Label text="Password:" styleClass="bluelabel" [Link]="1" />
<PasswordField [Link]="1" [Link]="1" fx:id="pwd"/>
<Button id="submitBtn" mnemonicParsing="false" prefWidth="300.0" text="Sign In"
[Link]="2" [Link]="2"
onAction="#signInClicked"/>
<Label alignment="CENTER" [Link]="3"
[Link]="2" prefWidth="300.0" fx:id="errMsg"/>
</children>
Injecting a reference of the new label into controller and declaring a property to store the error message will look
like this:
JAVA
@FXML private Label errMsg;
The next question is when and where do the binding? If I’d been creating an instance of the Controller with
the new operator I could have done it in the class constructor after the GUI component was created. But JavaFX
runtime instantiates the Controller for us, so how can we catch the moment when the GUI components are
ready?
In JavaFX if you’ll add to the controller the method initialize annotated with @FXML , FXMLLoader will
invoke it after all GUI components are constructed.
JAVA
@FXML public void initialize() {
[Link]().bind(signinError);
}
JavaFX properties are observables. So you can read the above code as follows: "I want the text property of the
label errMsg to be the observer (a.k.a. listener) to the property signinError (observable). So whenever
signinError changes, the text property of the label will get the latest value."
To complete the Sign In example with the binding, the event handler for the Sign In button should not only paint
the wrong ID in light pink, but also modify the value of the signinError property. The complete code of the
class BindableController is shown next.
[Link] 157/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class BindingController {
@FXML
private TextField id;
@FXML
private PasswordField pwd;
[Link]().bind(signinError);
}
} else{
[Link]("-fx-background-color: white;");
[Link]("");
}
Note that in the if statement I set the error message when the ID is wrong, and reset the signinError to an
empty string when the ID is correct. To test the program I’ve entered Alex as the user ID and clicked the button
Sign [Link] window looked like this:
[Link] 158/303
22/03/2025, 18:48 Programação Java para crianças
Enter the right user ID, click on Sign In again, and the binding mechanism will remove the error message from
the window.
Imagine a program with a GUI that’s constantly being updated based on some intensive calculations. It could be
a game with multiple moving shapes. It could be an application for a TV channel that may show a video stream,
commercials, viewers polls and more. It could be a business application that displays several pieces of constantly
changing information in different parts of the window like prices on eBay auction.
Updates of the GUI in JavaFX are done in so called application thread. The idea is to separate calculations from
the GUI updates. Say, the user clicked on the button Play on a JavaFX video streaming application like Netflix.
If the requests for the remote video and actual playing of the video (GUI updates) would be done in the same
application thread, the video would be choppy - it would be interrupted by running business logic that prepares
the GUI content. The screen would be "frozen" and the user wouldn’t be able to use any screen components.
[Link] 159/303
22/03/2025, 18:48 Programação Java para crianças
This code snippet has so-called try-catch block, which is required in some cases for error handling. The next
chapter explains the error processing subject in details. But at this point let’s just focus on the code located inside
the curly braces after the keyword try .
The method sleep of class Thread takes one argument - the sleeping time in milliseconds. There are 1000
milliseconds in one second, so the above code snippet will place the current thread to sleep for 10 seconds.
Remember, the controller class has an event handler for the Sign In button? It executes in the JavaFX application
thread. I’ll add the 10-second sleeping code to the application thread to emulate the process that would perform
the actual sign in. Actually, this is wrong - you should execute the application logic in a separate thread. But I do
this on purpose to demonstrate the frozen effect.
The following code fragment from the new controller class shows how the event handler signInClicked
invokes the method named wrongStartOfLongRunningProcess , which sleeps for 10 seconds and then
checks if the entered user ID is Yakov.
[Link] 160/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public void signInClicked(ActionEvent evt){
wrongStartOfLongRunningProcess(userID);
if (!"Yakov".equals(uID)){
[Link]("-fx-background-color: lightpink;");
} else{
[Link]("-fx-background-color: white;");
}
}
When the user clicks on the Sign In button, the application thread will become busy for 10 seconds, and only
then checks the user ID and set the background color of the TextField on the screen. If you’ll run the Sign In
sample with such event handler, the application window becomes frozen and unresponsive for 10 seconds. If the
user will try to reenter the ID, he’ll see a wait cursor. On MAC OS computers such a cursor looks as a spinning
wheel of death as shown on Figure 8-7.
[Link] 161/303
22/03/2025, 18:48 Programação Java para crianças
Ten seconds later the application thread wakes up, and the GUI becomes responsive again. Let’s fix this code
and create a separate thread emulating the long running process so that the application thread can continue
working with GUI. The following code listing shows the complete code of the class
ControllerLongRunningThread , which doesn’t freeze the window.
[Link] 162/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class ControllerLongRunningThread {
rightStartOfLongRunningProcess(userID);
2. The lambda expression places the current thread to sleep for 10 second, but it won’t be the application
thread, because we’ll create a separate worker thread for it (see the notes 5 and 6 below).
3. Quando o sleep termina, precisamos passar o controle de volta do worker para o thread do aplicativo para
atualizar a GUI. Para isso, o JavaFX tem um método especial runLater na classe Platform . O método
runLater colocará a solicitação para atualizar a GUI em uma fila de eventos especial do thread do
[Link] 163/303
22/03/2025, 18:48 Programação Java para crianças
aplicativo.
4. Fim da declaração da expressão lambda
5. Agora criamos a instância do thread de trabalho passando a expressão lambda para ele.
6. O método start da classe Thread inicia a execução do código lambda em um thread de trabalho
separado.
No capítulo sobre o jogo Ping-Pong, usaremos vários threads também. Um thread será responsável por exibir a
mesa de ping-pong, enquanto o outro calculará as coordenadas da bola e das raquetes.
Você pode aprender como usar linguagens de script e criar um arquivo [Link] no Windows ou
[Link] no MAC OS que terá o java [Link] comando dentro. Você pode até mesmo criar um ícone
que executará esse script. Mas e se todos na sua escola quiserem ter seu programa instalado em seus
computadores? Agora se torna uma tarefa demorada.
Mas a melhor maneira de preparar seu aplicativo JavaFX para distribuição é criar um arquivo self-contained
[Link] para Windows ou [Link] MAC OS. Este arquivo conterá tanto o Java runtime quanto o
código do seu aplicativo. Este processo é descrito em detalhes no tutorial da Oracle intitulado "Self-Contained
Application Packaging" ([Link] . Não vou
repetir este tutorial aqui, mas vou deixá-lo para você como um projeto de autoestudo.
Tenho certeza de que muitos de vocês querem saber se é possível usar JavaFX para escrever aplicativos para
smartphones. A Oracle não oferece as bibliotecas JavaFX para plataformas móveis, mas ainda é possível.
Para desenvolver aplicativos JavaFX para iOS, você precisa instalar e aprender por conta própria algum software
adicional, chamado RoboVM ([Link] , que é um SDK para converter bytecode Java em um
código de dispositivo nativo como se tivesse sido escrito na linguagem de programação C, o que o torna
implantável em dispositivos iOS.
[Link] 164/303
22/03/2025, 18:48 Programação Java para crianças
Pegue um livro sobre JavaFX 8 ou posterior e experimente você mesmo. Um dos melhores livros sobre o
assunto é "Pro JavaFX 8: A Definite Guide to Building Desktop, Mobile, and Embedded Java Clients" publicado
pela Apress.
1. Crie uma classe Java CalculatorController no mesmo projeto IDEA onde a GUI da calculadora está
localizada.
4. Modifique o arquivo [Link] e atribua o nome do método manipulador de cliques para cada
botão usando o atributo, onAction como fizemos no exemplo de Login.
5. Em cada método manipulador, adicione o código para reconhecer qual botão foi clicado. Você pode fazer o
rótulo do botão clicado consultando o ActionEvent objeto que será fornecido para cada método
manipulador de eventos. Por exemplo, se a variável evt representa o ActionEvent objeto, o código pode
ficar assim:
JAVA
Button clickedButton = (Button) [Link]();
String buttonLabel = [Link]();
6. Se o usuário clicar no botão de dígito, obtenha o valor atual do campo de exibição da calculadora, concatene
o rótulo do botão e atribua o novo valor de volta ao campo de exibição.
[Link] 165/303
22/03/2025, 18:48 Programação Java para crianças
7. Você precisa declarar uma variável, digamos valueOne no controlador para armazenar o valor atual do
campo de exibição quando o usuário clica no botão de operação. Por exemplo, se o usuário clicou no botão
com o rótulo + , - , / , ou * , é um sinal de que o usuário terminou de inserir o primeiro número.
Armazene-o na variável valueOne e limpe o campo de exibição para que o usuário possa começar a inserir
o segundo número.
8. Declare a variable, say operation , to remember the operation that the user wants to perform. For
example, if the user clicked on + , store + in the variable operation .
9. If the user clicks on the button = , get the value from valueOne and from the display field and perform the
operation according to the value in operation . Use the switch statement to perform different
operations.
10. After the operation is complete, assign the result to the display field by using the method setText of the
TextField component.
11. Store the calculated result in the variable valueOne so the user can continue performing other operations.
For example if the first operation was 2+3, the display shows 5, and the user can click on the buttons *
followed by 4 requesting multiplication of 5 by 4.
[Link] 166/303
22/03/2025, 18:48 Programação Java para crianças
Say you forgot to write one closing curly brace in your Java code. This will result in a compilation error that can
be fixed easily. But there are so called run-time errors, when your program stops working properly and prints
error messages.
For example, a Java class reads a file with the game scores. What’s going to happen if someone will delete this
file? Will the program crash with a scary error message, or will it stay alive displaying a user friendly message
like this one: Dear friend, for some reason I could not read the file [Link]. Please make sure that the file
exists? This is an example of a situation when Java compiler won’t be able to help - the Java syntax was written
properly.
You should make your programs ready for unexpected situations. you should foresee what might go wrong when
the program will be running, and what to do if something went wrong. In many programming languages the
programmer decides if he wants to add error processing code to a program. But in many cases Java forces you to
include error processing code, otherwise the programs will not even compile.
Runtime errors in Java are called exceptions, and error processing is called exception handling. You have to
place code that may produce errors in so-called try/catch block. It’s as if you’re saying to JVM the
following: Try to read the file with scores, but if something happens, catch the error and execute the code that
will deal with it:
JAVA
try{
[Link]();
}
catch (IOException ioe){
[Link](
"Dear friend,I could not read the file [Link]" +
[Link]());
}
The ioe in the above code fragment is a variable that represents the IOException object given to the catch
block by the Java runtime. You can give this variable any name you like. The getMessage will return the text
describing what happened during the file read.
We’ll learn how to work with files in Chapter 11, but at this point I’d like to introduce a new term I/O or
input/output. Read and write operations (from/to disk or other device) are also known as I/O operations, and the
class IOException is a class that contains information about input/output errors.
[Link] 167/303
22/03/2025, 18:48 Programação Java para crianças
In the Java world, a method throws an exception in case of a runtime error. Different exceptions will be thrown
for different type of errors. If the catch block exists in the program for this particular type of an error, it will be
caught and the program will jump into the catch block to execute the code located there. The program will
stay alive, and this exception is considered to be taken care of.
The print statement from the code above will be executed only in case of a file read error.
We know that dividing by zero is illegal, but I wrote a program TestStackTrace that divides by zero on
purpose just to show how the error and the stack trace could look like.
JAVA
1 class TestStackTrace{
2 TestStackTrace()
3 {
4 divideByZero();
5 }
6
7 int divideByZero()
8 {
9 return 25/0;
10 }
11
12 static void main(String[] args)
13 {
14 new TestStackTrace();
15 }
16 }
The output of this program shows the sequence of method calls that were made up to the moment when the run-
time error had happened. Start reading this output from the last line going up.
JAVA
Exception in thread "main"
[Link]: / by zero
at [Link]([Link])
at TestStackTrace.<init>([Link])
at [Link]([Link])
This means that the program started in the method main , then went to init , which is a constructor, and then
called the method divideByZero . The numbers 14, 4 and 9 show the program line numbers where these
methods were called. After that, an exception (an error) ArithmeticException was thrown – the line number
[Link] 168/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 169/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 170/303
22/03/2025, 18:48 Programação Java para crianças
Subclasses of the class Exception are called checked exceptions and you must process them in your code.
Subclasses of the class Error are fatal JVM errors and the running program can’t handle them.
How is a programmer supposed to know in advance if some Java method may throw an exception and that a
try/catch block should be used? Not to worry, if you call a method that may throw an exception, Java
compiler will print an error message similar to this one:
JAVA
"[Link]": unreported exception: [Link]; must be caught or declared to
be thrown at line 57
Of course you are welcome to read Java documentation that describes exceptions that may be thrown by any
particular method. The rest of this chapter will explain how to deal with these exceptions.
After one try block you may put several catch blocks, if you believe that more than one error may happen.
For example, when a program tries to read a file, the file may not be there, and you’ll get the
FileNotFoundException , or the file is there, but the code keeps reading the file after reaching the end of file
– this generates EOFException . The next code fragment will print messages in plain English if the program
can’t find a file with game scores or reached the end of the file. For any other read errors it’ll print the message
Problem reading file and a technical description of the error.
[Link] 171/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public void getScores(){
try{
[Link]();
[Link](“Scores loaded successfully”);
}catch(FileNotFoundException e){
[Link](“Can not find file Scores”);
}catch(EOFException e1){
[Link](“Reached end of file”);
}catch(IOException e2){
[Link](“Problem reading file “ +
[Link]());
}
}
If the method read fails, the program jumps over the line println and tries to land in the catch block that
matches the error. If it finds such block, the appropriate method println will be executed, but if the matching
catch block is not found, the method getScores will re-throw this exception to its caller.
If you write several catch blocks, you may need to place them in a particular order if these exceptions are
inherited from each other. For example, since the EOFException is a subclass of the IOException , you have
to put the catch block for the subclass first. If you would put the catch for IOException first, the program
would never reach the FileNotFound or EOFException , because the first catch would intercept them.
Some lazy programmers would write the method getScores just like this:
JAVA
public void getScores(){
try{
[Link]();
}catch(Exception e){
[Link](“Problem reading file ”+
[Link]());
}
}
This is an example of a bad style of Java coding. When you write a program, always remember that someone
else may read it, and you don’t want to be ashamed of your code.
Catch blocks receive an instance of the object Exception that contains a short explanation of a problem, and
its method getMessage will return this info. Sometimes, if the description of an error is not clear, try the
method toString instead:
JAVA
catch(Exception e){
[Link](“Problem reading file ”+ [Link]());
}
[Link] 172/303
22/03/2025, 18:48 Programação Java para crianças
If you need more detailed information about the exception, use the method printStackTrace . It will print the
sequence of method calls that lead to this exception similar to an example from the section Reading Stack Trace.
JAVA
class MySuperGame{
try{
// Since the getAllScores()declares exception,
// we handle it over here
[Link]();
}catch(IOException e){
[Link](
"Sorry, the list of scores is not available");
}
}
Imagine that the MySuperGame program invokes multiple methods that read or write files and get some data
from a remote server. We may want to process all possible exceptions in one place – the main method. In this
case there is no need to handle exceptions inside these methods (e.g. getAllScores ). We could rather declare
that these methods may throw exceptions. Since we are not even trying to catch exceptions in getAllScores ,
the IOException will be propagated from the getAllScores to its caller - the method main . Now the main
method has to handle this exception.
[Link] 173/303
22/03/2025, 18:48 Programação Java para crianças
The code inside the try block successfully ended and the program continues.
The code inside the try block runs into a return statement and the method is [Link] example, you
may read a file line by line, and if the line contains a certain text, you may want to stop reading the file. Just
write a return statement, and the method is exited, e.g.
JAVA
if ([Link]("Mary")){
return;
}
The code in the try block throws an exception and control goes to the matching catch block, which
either handles the error and the method execution continues, or it re-throws the exception to the caller of this
method.
If there is a piece of code that must be executed no matter what, put it under the keyword finally :
JAVA
try{
[Link]();
}catch(Exception e){
printStackTrace();
}finally{
// the code that must always be executed
// goes here, for example [Link]();
}
The code above has to close the file regardless of success or failure of the read operation. Usually, you can find
the code that releases some computer resources in the block finally , for example, disconnection from a
network or file closing.
If you are not planning to handle exceptions in the current method, they will be propagated to the caller. In this
case, you can use the finally even without a catch block:
JAVA
void myMethod() throws IOException{
try{
// your code that reads a file goes here
}
finally{
// your code that closes the file goes here
}
}
If the myMethod will throw an exception it will be handled in the calling method. But we still want to close the
file, and placing the code that closes a file into the finally section will guarantee that it will be done. So we
have the` finally` without the catch here.
[Link] 174/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
throw new IOException(“The file [Link] contains invalid characters”);
The constructor of any exception should get a message that describes the error as an argument. When you’ll be
invoking the getMessage method on the exception object in the catch block, it’ll print the message that was
given to the constructor in the code that has thrown the exception.
In the next section I’ll show you how create your own exception classes and throw them with the throw
keyword.
[Link] 175/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
class TooManyBikesException extends Exception{
// Constructor
TooManyBikesException (){
This class has only a constructor that takes the message describing this error and passes it to the superclass of
TooManyBikesException for reporting the same way as Java runtime reports any other exception. When
some catch block receives this exception it can extract the message describing what happened by calling the
method getMessage on the caught object TooManyBikesException .
Visualize a JavaFX GUI where the user selects several bicycles of some model and hits the button Place Order.
As you know from Chapter 8, this action will result in the call to the event handler method (e.g. placeOrder )
assigned to the onAction property of the button. The event handler can apply some business logic (e.g. call a
[Link] 176/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
@FXML private ComboBox model;
@FXML private TextField quantity;
try{
validateOrder(selectedModel, quantity);
} catch(TooManyBikesException bikesException){
[Link](
[Link]());
}
}
If the order won’t fit in the truck, the method validateOrder throws the exception, the catch block in
placeOrder intercepts it and displays an error message in a text field on the window. When you throw custom
exceptions, provide a user-friendly message that clearly describes the error.
[Link] 177/303
22/03/2025, 18:48 Programação Java para crianças
I’m not going to provide you with an explanation of how JavaFX ComboBox control works, because I want you
to do a little research as a part of the project assignment below.
In a perfect world, every program would work properly, but realistically you have to be ready for unexpected
situations. It helps that Java often forces you to write code that is prepared for these situations. You can also use
the Java exception handling mechanism to process situations specific to your application as illustrated using the
bike store example.
[Link] 178/303
22/03/2025, 18:48 Programação Java para crianças
Use a TextField control for entering the quantity, a Button for placing an order, and a Label to display
either order confirmation or an error message.
In the controller class use the code fragment from the section "Creating Custom Exceptions". :toc-placement!:
:imagesdir: .
[Link] 179/303
22/03/2025, 18:48 Programação Java para crianças
This game may go by different names around the world, but it comes down to placing X’s and O’s on the game
board. If you’re not familiar with this game, read its description in this Wikipedia article
([Link]
Every game implements a set of rules or a strategy that has to be applied depending on the player’s actions. Let’s
come up with a simple algorithm for the Tic-Tac-Toe game. Our version of this game will implement the
following rules:
Two players can play this game. One will play with the symbol X, and the other will use O.
The winner must have a full row, column, or diagonal of X’s or O’s.
After the winner is found or there are no empty squares left, the players may select the menu Actions | Play
to play again.
[Link] 180/303
22/03/2025, 18:48 Programação Java para crianças
The content of this chapter is based on the materials covered in Chapter 7 and 8. While developing the game
you’ll learn how to add menus, dynamically change styling of GUI components and apply an animation effect.
[Link] 181/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class TicTacToe extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = [Link](getClass().getResource("[Link]"));
[Link]("Tic-Tac-Toe");
[Link](new Scene(root, 300, 325));
[Link]();
}
Rename the generated package from sample into mygame. Inside the [Link] change the reference to
controller to be fx:controller="[Link]" . Now you’re ready to design the GUI for Tic-Tac-
Toe in Scene Builder.
[Link] 182/303
22/03/2025, 18:48 Programação Java para crianças
First of all, the <GridPane> is not a good candidate to serve as a root container for our game, which has to
have a menu on top. The <BorderPane> is a better choice when you need to have some GUI components to be
located on the top of the window. Our game will have a menu on top and a 3x3 grid of squares in the center of
the window.
Let’s delete the GridPane from the Hierarchy panel at the bottom left and drag-drop the BorderPane there.
The Scene Builder’s Window should look like this:
JavaFX menus are created as a hierarchy of nested components. A Menu container can contain one or more
MenuItem components and other Menu components. You can also create a MenuBar or a ContextMenu that
includes one or more Menu components. I’ll show you how to create a menu bar with two menus Actions and
Help for our Tic-Tac-Toe game.
A menu bar is usually located at the top of a window. In Scene Builder drop the MenuBar component from the
Controls panel onto Insert TOP line in the BorderPane at the bottom left panel. Press a little plus sign to
expand the MenuBar in the Hierarchy panel. You’ll see that it’ll have the default menus named File, Edit and
Help.
[Link] 183/303
22/03/2025, 18:48 Programação Java para crianças
We’re not going to edit anything in the TicTacToe game, so right-click on Edit and select Delete option. Rename
the menu File into Actions using the Properties panel of Scene [Link] Menu File was created with the
MenuItem Close - rename it into Quit.
Now we’ll add menu items to the menus Actions and Help. Drop a MenuItem component from the panel Menu
onto the menu Actions in the Hierarchy panel. Scene Builder will automatically create an Unspecified Action.
Rename it to Play. You can use drag and drop to change the order of the menu items.
Drop another MenuItem component onto the menu Help. Scene Builder by default creates two menu items:
About and Unspecified Action. Rename the latter to be How to Play. The Hierarchy panel should look as
follows:
[Link] 184/303
22/03/2025, 18:48 Programação Java para crianças
Figure 83. The menu bar with 2 menus and 4 menu items
Now drop a GridPane from the Containers panel onto the center of the BorderPane. By default, Scene Builder
creates a 2x3 grid. Right-click at the column tab "1" and add a column to change the grid dimensions to be 3x3.
Change the preferred height of each row to 100 by selecting each row and entering 100 in the Pref Height field
on the right panel named Layout: RowConstraints. This is what we’ve got so far:
[Link] 185/303
22/03/2025, 18:48 Programação Java para crianças
Figure 84. The menu bar on top and the grid in center
Save this layout in Scene Builder and run the TicTacToe class in IDEA. You’ll see a window with a menu on top.
The grid won’t be visible yet, because it has no content. Click on the menu Actions, and the window will look
like this:
[Link] 186/303
22/03/2025, 18:48 Programação Java para crianças
The grid has 9 cells and we want to add 9 buttons - each button will represent a square on the Tic-Tac-Toe board.
You can add the buttons to the grid in Scene Builder as we did in the Calculator in Chapter 7. But it’ll be faster
to do it manually by editing the content of the file [Link] in IDEA’s editor. Modify the content of this file
to look as follows:
[Link] 187/303
22/03/2025, 18:48 Programação Java para crianças
XML
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link]?>
<BorderPane xmlns="[Link]
xmlns:fx="[Link]
fx:controller="[Link]">
<top>
<MenuBar [Link]="CENTER">
<menus>
<Menu text="Actions">
<items>
<MenuItem text="Play" />
<MenuItem text="Quit" />
</items>
</Menu>
<Menu text="Help">
<items>
<MenuItem text="About" />
<MenuItem text="How to play" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<GridPane fx:id ="gameBoard" [Link]="CENTER">
<children>
<Button fx:id="b1" prefHeight="100.0" prefWidth="100.0" />
<Button fx:id="b2" prefHeight="100.0" prefWidth="100.0" [Link]="1" />
<Button fx:id="b3" prefHeight="100.0" prefWidth="100.0" [Link]="2" />
<Button fx:id="b4" prefHeight="100.0" prefWidth="100.0" [Link]="1" />
<Button fx:id="b5" prefHeight="100.0" prefWidth="100.0" [Link]="1"
[Link]="1" />
<Button fx:id="b6" prefHeight="100.0" prefWidth="100.0" [Link]="2"
[Link]="1" />
<Button fx:id="b7" prefHeight="100.0" prefWidth="100.0" [Link]="2" />
<Button fx:id="b8" prefHeight="100.0" prefWidth="100.0" [Link]="1"
[Link]="2" />
<Button fx:id="b9" prefHeight="100.0" prefWidth="100.0" [Link]="2"
[Link]="2" />
</children>
</GridPane>
</center>
</BorderPane>
Note that each button has an id. We’ll need them while processing button clicks in the controller class. Run the
TicTacToe class and the window will look pretty close to the final version of our Tic-Tac-Toe game.
[Link] 188/303
22/03/2025, 18:48 Programação Java para crianças
Do yo see this thin border around the top left square? It occurs because by default the firs grid cell has a focus,
which means that this particular GUI component is ready to receive input. But we don’t want to suggest the
player starting the game from the top left corner, do we? We want to remove this little border, and it’s time to
create a special style for a button that will not show the focus.
Let’s create a new file named [Link]. In IDEA, right click on the package name mygame and use the menu
File | New | File. It’ll create an empty file. Type the following in there:
CSS
.button{
-fx-focus-color: transparent;
-fx-background-insets: -1, 0, 1, 1;
}
From Chapter 7 you may remember that this means that every button in our application will have these
attributes. Web designers call the styles created for certain types of GUI element type selectors. Hence the
attributes defined in the .button section of CSS will apply only for buttons. If we wanted to style menus, we’d
need to add a section .menu to the CSS file. Labels would be styled in the .label section, and so on.
[Link] 189/303
22/03/2025, 18:48 Programação Java para crianças
When I did my search on line to figure out how to remove the focus border, the online documentation suggested
that adding the rule -fx-focus-color: transparent; would do the trick. But it didn’t. Every programmer
knows, that not everything works by the book. By doing a little more online research I figured out that adding -
fx-background-insets: -1, 0, 1, 1; is needed too.
Don’t be scared that not everything works as it should the first time around. Luckily, each programming
language has an online community of people who are willing to share their findings and answer the questions of
the rookies. One of the best resources for asking questions and getting help is the Web site StackOverflow
([Link]
Now we need to add a line to the main method of the TicTacToe class to load the file [Link] . We
did something like this in Chapter 7 while styling the Sign In application. We’ll also need to do small changes in
the main method to store the reference to a scene in a separate variable. We also want to set fix the size of the
game board by invoking setResizable(false); on the stage object. After these modifications, the class
TicTacToe will look like this:
JAVA
public class TicTacToe extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = [Link](getClass()
.getResource("[Link]"));
[Link]("TicTacToe");
Scene scene = new Scene(root, 300, 275);
[Link]().add(getClass()
.getResource("[Link]").toExternalForm());
[Link](false);
[Link](scene);
[Link]();
}
[Link] 190/303
22/03/2025, 18:48 Programação Java para crianças
The GUI is ready. The name of the Java class that will play the role of the controller was specified in the file
[Link] as fx:controller="[Link]" . Now let’s program the application logic in the
controller class.
When the player will click on the button, the event handler should place the appropriate label on the button. The
code of the class Controller will take care of this functionality:
[Link] 191/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class Controller {
private boolean isFirstPlayer = true;
The method buttonClickHandler will handle events generated when the player clicks on a button. Note that
we check if the button’s label is blank, then the program displays either X or O depending on which player
clicked on the button. To let the GUI know about this event handler we need to add the attribute
onAction="#buttonClickHandler" to each <Button> tag in the file [Link]. After this is done, run
the TicTacToe program again. Start clicking on empty squares, and the program will take turns in placing the
X’s and O’s on them.
[Link] 192/303
22/03/2025, 18:48 Programação Java para crianças
Great,the View communicates with the Controller! But the X’s and O’s look unproportionally small in these
large squares. Besides, the gray color does not look too exciting. It’s time to add some styling to our GUI
components.
[Link] 193/303
22/03/2025, 18:48 Programação Java para crianças
CSS
.button{
-fx-focus-color: transparent;
-fx-background-insets: -1, 0, 1, 1;
-fx-font-weight: bold;
-fx-font-size: 36;
-fx-text-fill: blue;
-fx-background-color: violet;
-fx-border-color:darkblue;
}
.menu-bar{
-fx-background-color: gold;
}
If you run the TicTacToe program now and start clicking on buttons, the game board will look like this:
[Link] 194/303
22/03/2025, 18:48 Programação Java para crianças
As you can see, my artistic abilities are limited, but if you spend some time learning CSS, you may come up
with a much fancier game board than mine.
All JavaFX components are pre-styled, and the combination of the styles is called theme. The default theme of
all JavaFX components is called caspian. By defining your own CSS rules you can override the defaults. Scene
Builder has a menu View | Show CSS analyzer, which allows you to see the default styles of your GUI
components. If you’re interesting in learning more about styling with Scene Builder, watch the video titled "In-
Depth Layout and Styling with the JavaFX Scene Builder" ([Link]
We’ll write a method find3InARow , which on every click will check each row, column, and diagonals on the
board to see if they have the same labels. The method find3InARow will be invoked from the method
buttonClickHandler . If the winning combination is found, the program will invoke the method
highlightWinningCombo to show the winning combination in a different style.
To compare the labels of the buttons we need to have references to their Button objects, which we’ll get using
the injection mechanism offered by the @FXML annotation as we did in Chapter 8. We’ll also need to have a
reference to the GridPane , which is a container for all buttons. You’ll see its use in the section "Handling the
Tic-Tac-Toe Menu Play".
Each button will have a matching variable in the controller annotated with @FXML . The grid will also have a
reference variable. We’ll just add the following member variables to the Controller class:
JAVA
@FXML Button b1;
@FXML Button b2;
@FXML Button b3;
@FXML Button b4;
@FXML Button b5;
@FXML Button b6;
@FXML Button b7;
@FXML Button b8;
@FXML Button b9;
Now let’s write the method find3InARow that will methodically compare the non-blank labels of the buttons in
each row, column, and both diagonals. If three labels are the same, the code should highlight the winning
combination. This is how the code in the method find3InARow will look:
[Link] 195/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
private boolean find3InARow(){
//Row 1
if (""!=[Link]() && [Link]() == [Link]()
&& [Link]() == [Link]()){
highlightWinningCombo(b1,b2,b3);
return true;
}
//Row 2
if (""!=[Link]() && [Link]() == [Link]()
&& [Link]() == [Link]()){
highlightWinningCombo(b4,b5,b6);
return true;
}
//Row 3
if (""!=[Link]() && [Link]() == [Link]()
&& [Link]() == [Link]()){
highlightWinningCombo(b7,b8,b9);
return true;
}
//Column 1
if (""!=[Link]() && [Link]() == [Link]()
&& [Link]() == [Link]()){
highlightWinningCombo(b1,b4,b7);
return true;
}
//Column 2
if (""!=[Link]() && [Link]() == [Link]()
&& [Link]() == [Link]()){
highlightWinningCombo(b2,b5,b8);
return true;
}
//Column 3
if (""!=[Link]() && [Link]() == [Link]()
&& [Link]() == [Link]()){
highlightWinningCombo(b3,b6,b9);
return true;
}
//Diagonal 1
if (""!=[Link]() && [Link]() == [Link]()
&& [Link]() == [Link]()){
highlightWinningCombo(b1,b5,b9);
return true;
}
//Diagonal 2
if (""!=[Link]() && [Link]() == [Link]()
&& [Link]() == [Link]()){
highlightWinningCombo(b3,b5,b7);
return true;
}
return false;
}
[Link] 196/303
22/03/2025, 18:48 Programação Java para crianças
If you’ll check the fx:id of each button in the file [Link], you’ll see that the first row is represented by
the buttons b1 , b2 , and b3 . The first column is represented by the buttons b1 , b4 , and b7 . One diagonal
consists of the buttons b1 , b5 , and b9 . It should be pretty easy to read and understand the code of the method
find3InARow , isn’t it? The method highlightWinningCombo will get the references to the three winning
buttons as the method arguments, and it has to change their styles.
I want to change the background of the winning buttons, but this time I won’t use just a single color, but a color
gradient. In computer graphics, color gradients refer to filling the area with different colors that are smoothly
transitioning from one color to another. The color transitioning can be linear or radial, and this Wikipedia article
([Link] gives you some examples of both.
We’ll use radial gradients in our game. With gradients you can use more than two colors. I’ll use three colors in
the gradient for the winning squares. The background color will transition from white to light yellow, and then to
lawn green. I’ll use red for the text of the label on the winning square.
To dynamically change the style of a GUI component you can call the method setStyle and specify the color
as an argument, for example:
[Link]("-fx-text-fill: red;");
But embedding CSS rules in your Java program is not a good idea. What if you decide to change the styling (e.g.
to change the color from red to pink)? You don’t want to search for all the places in your Java code where this
style was used. Besides, changing the styles in the code would require to recompile your Java program. It’s much
better to keep the style definitions in the CSS file.
So far we’ve been using CSS type selectors that can change the style of the specified component types. But CSS
allows you to define and name a style that’s not intended for a specific component type and can be applied by
name to various components. In CSS such styles are called class selectors. Let’s add a style selector called
.winning-square to the file [Link] .
CSS
.winning-square {
-fx-text-fill: red;
-fx-background-color: radial-gradient( radius 100%, white, lightyellow, lawngreen);
}
[Link] 197/303
22/03/2025, 18:48 Programação Java para crianças
The style selector .winning-square includes two style rules: one for setting the button’s text color to red, and
another to set the button’s background color to radial gradient. Our Java program has to get a reference to the
existing styles of the button and add a .winning-square , which will override both the text and the
background color of the [Link] method highlightWinningCombo will look like this:
JAVA
private void highlightWinningCombo(Button first, Button second, Button third){
[Link]().add("winning-square");
[Link]().add("winning-square");
[Link]().add("winning-square");
}
Try playing the game after adding the methods find3InARow and highlightWinningCombo to the class
Controller . The winning combination will look as follows:
[Link] 198/303
22/03/2025, 18:48 Programação Java para crianças
To use the effect or animation you need to pick one from the package [Link] or
[Link] respectively. I’ll show you how to apply a fade transition the FadeTransition to our
winning buttons. Each winning button will keep fading and coming back to its original state. We’ll add the
method applyFadeTransition to the Controller class:
JAVA
private void applyFadeTransition(Button winningButton) {
[Link](1.0);
[Link](0.1);
[Link](10);
[Link](true);
[Link]();
}
This code creates an instance of the animation class FadeTransition that will span 1000 milliseconds (1
second) and assigns this animation to the winning button. Then the code sets the fading parameters to change the
opacity of the button from 1.0 to 0.1 (changing to 0.0 would make the button completely transparent).
Setting the style count to 10 plays the animation 10 times. Because of setAutoReverse(true) , the animation
will proceed forward on the first cycle, then reverses on the second cycle, and so on. The method play starts
the animation. Adding the following three lines to the method highlightWinningCombo will play the
animation on the winningButton component.
JAVA
applyFadeTransition(first);
applyFadeTransition(second);
applyFadeTransition(third);
The screen shot shown on Figure 10-12 should give you an idea of how the end of the animation cycle will look
like.
[Link] 199/303
22/03/2025, 18:48 Programação Java para crianças
Compare this image with Figure 10-11, or better run the code that comes with the book to see the animation in
action.
[Link] 200/303
22/03/2025, 18:48 Programação Java para crianças
The good news is that clicks on menu items are processes the same way as clicks on buttons. In the file
[Link] we’ll assign onAction event handler for the menu Play:
HTML
<MenuItem text="Play" onAction="#menuClickHandler"/>
When the user clicks on the menu Play, the controller needs to reset buttons' labels to blank and remove styling
from the winning buttons. We’ll do this by getting a hold of all children of our GridPane and invoking the
method forEach passing a short lambda expression to it. This is what the method menuClickHandler will
look like:
JAVA
public void menuClickHandler(ActionEvent evt){
if ("Play".equals(menuLabel)){ (1)
ObservableList<Node> buttons = (2)
[Link]();
[Link](btn -> {
((Button) btn).setText(""); (3)
[Link]().remove("winning-square"); (4)
});
1. This code processes just the clicks on the menu Play, but I included the if statement to check the menu label
in case you decided to implement other menus too.
2. We’re getting references to all children of the grid (the buttons) in one shot. The method getChildren
returns a JavaFX collection of type ObservableList located in the package [Link] .
3. Each Java collection implements the method forEach , which gets a lambda expression to set the label of
each button to an empty string.
4. Then we’re getting the reference to the styles of the button and remove the style winning-square if
exists.
5. Finally, the code sets the variable isFirstPlayer to true so the next game will place an X as the first
label.
[Link] 201/303
22/03/2025, 18:48 Programação Java para crianças
Write a method goComputer that should try to find if there are any two buttons with O’s in each row, column
or a diagonal. If found, the program should place a O to the winning position. If not found, the computer should
place a O next to another O. If no O’s are found, the computer should try to place an O in the middle of the
board. If the middle square is occupied, place a O on the first blank button.
The method goComputer should be called from the method buttonClickHandler right after the line that
invokes the method find3InARow .
[Link] 202/303
22/03/2025, 18:48 Programação Java para crianças
In this chapter you’ll learn how to save data on disks and read them back into memory using Java
Input/Output(I/O) streams.A program can open an output stream with a file on disk and write the important data
there. Similarly, you can open an input stream and read the data from a file.
For example, if a player wins a game and you want to save the score, you can save it in a file called [Link]
using an output stream. If you want to save the player’s preferences (e.g. colors or fonts) you can save them in a
file, and read and apply them when the user runs your program again.
A program reads or writes data from/to a stream serially byte after byte, character after character, etc. Since your
program may use different data types like String , int , double , you should use an appropriate Java stream,
for example a byte stream, a character stream, or a data stream.
In this chapter I’ll show you how to use I/O streams with files located in your computer. In the next chapter
you’ll learn about I/O streams that can work with remote data located in other computers connected into a
network.
All classes that can work with file streams are located in packages [Link] and [Link] . Classes from the
[Link] implement blocking I/O: When bytes are being read/written, they become unavailable for other
threads of execution. This may not be an issue with small files like a history of game scores, but may become an
issue with large files that contain a gigabyte or more. The package [Link] offers a set of classes with
improved performance as well as some useful utility classes.
I’ll start with explaining the basics of working with streams of bytes using classes from the [Link] package,
and then give you some examples of working with classes from [Link] .
Java supports several types of streams, but no matter what type you are going to use, the following three steps
should be done in your program:
[Link] 203/303
22/03/2025, 18:48 Programação Java para crianças
• Open a stream that points at some data store e.g. a local or remote file.
In the real world people use different types of pipes for carrying different content (e.g. gas, oil, milkshakes).
Similarly, Java programmers use different classes depending on the type of data they need to carry over a stream.
Some streams are used for carrying text, some for bytes, et al.
The [Link] package includes the classes FileInputStream and FileOutputStream that allow you to
read and write files one byte at a time. If your program has to work only with text files, you could use the classes
Reader and Writer , which are specifically meant for reading character streams.
After selecting, say FileInputStream you’d be invoking one of its methods to read the file data. For example
the online documentation ([Link] of the class
FileInputStream includes the method read having the following signature:
JAVA
public int read() throws IOException
This should tell you that the method read returns an integer value and may throw the IOException , which is
an error that may happen if the file is corrupted or deleted, a device failure happened et al. Hence, you must
enclose the invocation of the method read into a try-catch block as explained in Chapter 9. To get a specific
reason for this exception you’ll call the method getMessage on the exception object.
Each byte in a file is represented by a code, which is a positive integer number. The method read returns the
value of this code.
The next example shows how to use the class FileInputStream to read the bytes from a file named [Link].
This little program won’t interpret the meaning of each byte - it’ll just print their code values.
I’ll start with creating a new Java project Chapter11 in IDEA. Then I’ll create a new empty file [Link] in the
root folder of the project (right-click on the project name and select the menu New | File). Finally, I’ll type the
following text in [Link]:
[Link] 204/303
22/03/2025, 18:48 Programação Java para crianças
Then I’ll create a new Java class MyByteReader that will read and print the content of the file [Link]. But let’s
pretend that we don’t know that the content of this file is text - I want to read it byte by byte and print each byte’s
code (not a letter) separated by a space character. The class MyByteReader will look like this:
JAVA
import [Link];
import [Link];
int byteValue;
1. First we open the file for reading (using a default character set) by creating an instance of the class
FileInputStream passing the file name [Link] as a parameter. In Chapter 9 you’ve learned the
syntax of the try-catch blocks, but here I used a special syntax called try-with-resources. When there are
some program resources that have to be opened and closed (e.g. FileInputStream ), just instantiate them
in parentheses right after the try keyword and Java will close them for you automatically. This spares you
from writing a finally block containing the code for closing resources.
2. This line starts a while loop that calls the method read() , which reads one byte, assigns its value to the
variable byteCode , and compares it with -1 (the end of file indicator).
3. If the value in the current byte is not equal to -1 , we print it followed by a space character. The loop ends
when it reads the -1 byte.
4. If an IOException occurs, catch it and print the reason for this error.
Running this program prints the following numbers that represent encoding of the text "This is a test file":
JAVA
84 104 105 115 32 105 115 32 97 32 116 101 115 116 32 102 105 108 101
[Link] 205/303
22/03/2025, 18:48 Programação Java para crianças
Writing bytes into a file works similarly, but you’d use the class FileOutputStream and its method write()
as shown in the program MyByteWriter below.
JAVA
import [Link];
import [Link];
1. The program MyByteWriter populates an array someData with integer codes that may represent some
characters
[Link] 206/303
22/03/2025, 18:48 Programação Java para crianças
The class BufferedInputStream works as a middleman between FileInputStream and the file itself. It
reads a big chunk of bytes from a file into memory (a buffer) in one shot, and the FileInputStream object
then reads single bytes from there, which are fast memory-to-memory operations. BufferedOutputStream
works similarly with the class FileOutputStream .
The main idea here is to minimize disk access. Buffered streams are not changing the type of the original streams
— they just make reading more efficient. A program performs stream chaining (or stream piping) to connect
streams, just as pipes are connected in plumbing.
A próxima listagem de código mostra uma classe MyBufferedByteReader , que é uma versão ligeiramente
modificada de MyByteReader . Acabei de anexar "outro fragmento ao pipe" - o BufferedInputStream do
[Link] pacote.
[Link] 207/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
import [Link];
import [Link];
int byteValue;
1. Aqui usamos a sintaxe try-with-resources novamente. Desta vez, criamos uma instância de
FileInputReader e então e instância de BufferedInputReader fornecendo o
FileInputReader como argumento. É assim que nos conectamos a fragmentos do pipe que usa o arquivo
[Link] como fonte de dados.
O programa MyBufferedByteReader produz a mesma saída que MyByteReader , mas funcionará um pouco
mais rápido.
Cada JVM tem um conjunto de caracteres padrão, que pode ser alterado durante a inicialização da JVM. Você
também pode descobrir qual é o caractere padrão na sua instalação Java invocando o método
defaultCharset na classe Charset , e eu mostrarei como fazer isso na seção "Lendo Arquivos de Texto".
[Link] 208/303
22/03/2025, 18:48 Programação Java para crianças
As classes Java FileReader e FileWriter o pacote [Link] foram criados especificamente para trabalhar
com arquivos de texto, mas funcionam apenas com codificação de caracteres padrão e não lidam com a
localização corretamente.
Para eficiência, a leitura pode ser canalizada com BufferedReader ou BufferedWriter , que lê ou escreve
de/para os caracteres de buffering de fluxo. Mostrarei exemplos de trabalho com arquivos de texto na próxima
seção.
No Mac OS ou Linux, os discos não são nomeados com letras como c: ou d: . Por exemplo, o caminho para os
arquivos do usuário começa no diretório Users . Além disso, uma barra invertida não é usada como símbolo
separador lá. Um caminho completo para um arquivo [Link] do usuário mary pode ser parecido com
este:
/Users/mary/mystuff/games/[Link]
Então, antes mesmo de abrir um arquivo, você pode criar uma instância do objeto Path , que não abre nem lê
um arquivo, mas representa a localização do arquivo no disco.
Há uma classe especial Paths (sim, no plural) que inclui uma série de métodos estáticos e, em particular, pode
construir o Path objeto para você. Por exemplo, você pode invocar o método get passando o nome do arquivo
como argumento:
JAVA
Path path = [Link]("[Link]");
Como especificamos apenas o nome do arquivo sem um diretório, o programa procurará o arquivo no diretório
atual, que no IDEA é o diretório do seu projeto (por exemplo, Chapter11 ). Fora do IDE, o diretório atual é
aquele de onde o programa foi iniciado.
[Link] 209/303
22/03/2025, 18:48 Programação Java para crianças
Mas se criássemos um diretório data na raiz do nosso projeto e movêssemos o arquivo [Link] para lá, então o
caminho relativo para o arquivo começando da raiz do projeto ficaria como "data/[Link]" no Mac OS ou
"data\\[Link]" no Windows. Duas barras invertidas em uma string Java correspondem a uma barra
invertida no sistema operacional Windows.
Mas seu projeto IDEA também está localizado em algum diretório no disco, por exemplo, chapter11 , que é um
subdiretório de PracticalJava . O arquivo pode ser representado pelo caminho absoluto , que pode se parecer
com isto:
c:\practicalJava\capítulo11\dados\[Link]
ou
/Users/mary/practicalJava/chapter11/data/[Link]
JAVA
byte[] myFileBytes = [Link]([Link]("[Link]");
Se o arquivo contiver texto, você pode ler o arquivo em uma String variável como esta:
JAVA
String myFileText = new String([Link]([Link]("[Link]")));
Se você quiser ler um arquivo de texto em uma coleção, onde cada elemento contém uma linha do arquivo, use o
método readAllLines .
JAVA
List<String> myFileLines = [Link]([Link]("[Link]"));
Both readAllBytes and readAllLines do not use buffers, but for small files is not important. For more
efficient reading you can ask the class Files to create a buffered stream. For example, the program
MyTextFileReader uses the method newBufferedReader for more efficient reading. Here I used the same
file [Link] located in the root directory of our IDEA project Chapter11.
[Link] 210/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package niosamples;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try {
if ( [Link](path)){ (2)
[Link]("The file size is " + [Link](path));
}
String currentLine;
[Link](currentLine);
}
} catch (IOException ioe) {
[Link]("Can't read file: " +
[Link]());
}
[Link]( (5)
"Your default character encoding is " + [Link]());
}
}
1. The program starts with creating a Path object from [Link] and printing its absolute path.
2. Then it checks if the file represented by the path exists and prints its size in bytes.
3. Here we’re opening the buffered reader capable of reading text encoded with a character set UTF-8 .
5. Print the default character set being used for those who are interested.
[Link] 211/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
The absolute path is /Users/yfain11/IdeaProjects/jfk/Chapter11/[Link]
The file size is 19
This is a test file
Your default character encoding is UTF-8
Now experiment to see if the IOException is thrown if the file is not found where it is expected to be. Just
move the file [Link] into a different directory and re-run MyTextFileReader . Now the console output looks
different:
JAVA
Can't read file: [Link]
Your default character encoding is UTF-8
This output was produced by the catch section from MyTextFileReader where the code invoked the
getMessage method on the IOException object.
JAVA
Path path = [Link]("data/[Link]");
[Link](path, [Link](),
[Link]);
When your program opens a file for writing, you need to consider different options. For example, you may want
to append text to an existing file, hence the above code snippet passes the argument
[Link] to method write . If you want to create a file from scratch every time you
run the program, use the option [Link] .
The following program MyTextFileWriter writes the text into a file [Link] in the directory data .
[Link] 212/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package niosamples;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try {
if ( [Link](path)){ (4)
[Link](path, [Link](),
[Link]);
} else {
[Link](path, [Link](),
[Link]);
}
1. For illustration purposes I want the program to print its current directory, which is stored in a special Java
variable [Link] .
2. Then I populate a string with the content "My game score is 28000" and concatenate the current date and
time followed by \n , which is the end of line marker.
4. Check if the file [Link] already exists, append the new content to it. If the file doesn’t exists – create it
and write the content there.
[Link] 213/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
The current directory is /Users/yfain11/IdeaProjects/jfk/Chapter11
The game score was saved at /Users/yfain11/IdeaProjects/jfk/Chapter11/data/[Link]
After running MyTextFileWriter twice I opened the file [Link]. Here’s what I found there:
JAVA
My game score is 28000 2015-01-11T09:07:49.352
My game score is 28000 2015-01-11T09:10:11.049
Cada vez que o programa salvava a mesma pontuação de 28000 anexando a data e hora do sistema. Claro, você
poderia calcular e escrever a pontuação real de um jogo. Esta é uma maneira simples de imprimir a data e hora
locais. A parte da hora vai depois da letra "T" e mostra horas, minutos, segundos e nanossegundos. No pacote
Java, [Link] você pode encontrar várias classes e métodos que fornecem formatação de data e hora para
impressão bonita. Leia o tutorial da Oracle sobre como trabalhar com a API de data e hora
([Link] se estiver interessado.
Para escrever arquivos pequenos como [Link] você não precisa usar fluxos bufferizados. Para arquivos
grandes, porém, use BufferedWriter, por exemplo:
JAVA
String myScore = "My game score is 28000 " +
[Link]() + "\n";
BufferedWrited writer = [Link](path, [Link]);
[Link](myScore)
[Link] 214/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package niosamples;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
[Link](myScore);
if ([Link](path)) {
return [Link](path,
[Link]);
} else {
return [Link](path,
[Link]);
}
}
}
Nesta classe, movi o código que verifica se o arquivo existe para um método separado getBufferedWriter .
Fiz isso para ilustrar o chamado padrão de design factory . Uma factory pode construir objetos diferentes, certo?
O método getBufferedWriter também constrói instâncias diferentes de a BufferedReader dependendo da
existência do arquivo referenciado por path . No jargão dos programadores, os métodos que criam e retornam
instâncias de objetos diferentes, com base em algum parâmetro, são chamados de factories.
[Link] 215/303
22/03/2025, 18:48 Programação Java para crianças
Na primeira lição deste livro, você executou o programa HelloWorld em uma janela de comando:
JAVA
java HelloWorld
Mas você tem permissão para adicionar argumentos de linha de comando logo após o nome do programa, por
exemplo,
JAVA
java HelloWorld Mary Smith
Neste caso, o programa HelloWorld receberia dois parâmetros de linha de comando: Mary e Smith. Se você se
lembra, sempre escrevemos o método main com um String array como argumento:
JAVA
public static void main(String[] args) {}
A JVM passa o String array para o método principal, e se você iniciar um programa sem nenhum argumento
de linha de comando, esse array permanece vazio. Caso contrário, esse array terá exatamente tantos elementos
quanto o número de argumentos de linha de comando passados para o programa.
Vamos ver como podemos usar esses argumentos de linha de comando em uma classe muito simples que irá
apenas imprimi-los:
[Link] 216/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public class PrintArguments {
Este programa faz um loop pelo array args e imprime os argumentos recebidos da linha de comando, se houver.
Execute este programa a partir da janela Command (ou Terminal) como segue:
JAVA
java PrintArguments Mary Smith 123.5
JAVA
I've got Mary
I've got Smith
I've got 123
A JVM colocou Mary no elemento da matriz args[0] , Smith em args[1] e 123 em args[2] .
Argumentos de linha de comando estão sempre sendo passados para um programa como strings. É
responsabilidade de um programa converter os dados para o tipo de dados apropriado, por exemplo:
JAVA
int myScore = [Link](args[2]);
É sempre uma boa ideia verificar se a linha de comando contém o número correto de argumentos. Verifique isso
logo no começo do método main . Se o programa não receber os argumentos esperados, ele deve imprimir uma
breve mensagem sobre isso e parar imediatamente usando um método especial exit da classe System :
[Link] 217/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
public static void main(String[] args) {
if ([Link] != 3){
[Link](
"Please provide arguments, for example:");
[Link]("java PrintArguments Mary Smith 123");
Você pode testar seus programas que recebem argumentos de linha de comando sem sair do IntelliJ IDEA. Basta
abrir o menu Run, selecionar Edit Configurations e inserir os valores no campo Program arguments como
mostrado abaixo:
Agora vamos escrever um programa para copiar arquivos. Para fazer esse programa funcionar com quaisquer
arquivos, os nomes dos arquivos originais e de destino precisam ser passados para esse programa como
argumentos de linha de comando.
[Link] 218/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
import [Link];
import [Link];
import [Link];
A cópia do arquivo é feita chamando o método copy na classe Files . Este programa funcionará bem enquanto
o arquivo de destino não existir. Você pode verificar a existência do arquivo no programa usando o método
exists da classe Files como foi feito na classe MyTextFileReader anteriormente.
Por que você precisaria dessa funcionalidade? Digamos que você esteja trabalhando em um jogo de tabuleiro e
queira salvar o estado atual do jogo para que o jogador possa continuar jogando amanhã, mesmo que o
computador precise ser reiniciado. O programa precisa salvar o estado do jogo em um arquivo e, quando o
jogador iniciar o jogo novamente, o programa deve carregar o estado salvo e recriar a situação no tabuleiro. Criar
uma classe Java com campos como nome do jogador, nível, pontuação e vidas pode ser uma boa maneira de
representar um estado do jogo.
[Link] 219/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
class GameState {
String playerName;
int level;
int score;
int remainingLives;
Quando o usuário seleciona a opção de menu Save Game State , o programa tem que criar uma instância do
objeto GameState , atribuir os valores aos seus campos e salvar esses valores em um arquivo. Mas em qual
formato salvar esses valores? Criar uma String variável e concatenar todos esses valores nela, separando os
valores com vírgulas? É muito trabalho. Além disso, você precisaria lembrar a ordem desses valores
concatenados para que, quando precisar lê-los, saiba a quais campos do objeto GameState atribuí-los.
Felizmente, Java simplifica muito esse processo. Você pode criar uma instância do objeto Java, preenchê-la com
os valores e, então, serializar essa instância em um monte de bytes em um formato especial que lembra a
estrutura da classe GameState . Assim, quando você precisa recriar a instância do GameState para esses bytes,
você pode desserializar o objeto de uma só vez com todos os valores de seus campos.
Um objeto Java pode ser serializado se implementar Serializabe interface. É uma interface muito simples de
implementar, pois não declara nenhum método abstrato. Basta adicionar implements Serializable à
declaração de classe para tornar uma classe serializável. A classe a seguir GameState representará o estado do
jogo.
[Link] 220/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
[Link] = playerName;
[Link]=level;
[Link]=score;
[Link] = remainingLives;
}
return "PlayerName: " + playerName + ", level:" + level + ", score: " + score +
", remainingLives: " + remainingLives;
}
}
1. A GameState classe tem quatro campos que descrevem o estado atual do jogo.
2. O construtor da classe preenche esses campos com os valores passados como argumentos.
3. Sobrescrevemos o método toString para poder imprimir o conteúdo dos campos. O método toString é
declarado na classe Object - o ancestral de todas as classes Java. Por exemplo, se você escrever
[Link](myObject) , Java encontra e invoca o toString`method on the object
`myObject . Você verá isso em ação na classe GameStateManager abaixo.
Objetos Java são serializados em um fluxo de E/S do tipo ObjectOutputStream . Você precisará criar uma
instância de OutputStream , canalizá-la com ObjectOutputStream e invocar um método writeObject .
Para desserializar (ler de volta) um objeto Java, você precisa criar uma instância de InputStream , canalizá-la
com ObjectInputStream e invocar um método readObject .
Crie uma instância da classe GameState e preencha seus campos com alguns dados.
[Link] 221/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
[Link](gameState); (7)
[Link] 222/303
22/03/2025, 18:48 Programação Java para crianças
return loadedGameState;
}
}
1. O programa começa com a criação e o preenchimento do objeto de estado do jogo. Neste exemplo, usei
valores codificados, mas em um jogo real eles devem ser retirados das variáveis que refletem o status real do
jogo.
2. O nome do arquivo serializado é [Link] e ele será representado pelo Path objeto.
4. Após a serialização ser concluída, nós a desserializamos de volta para outra instância do objeto de estado do
jogo. A variável deserializedGameState aponta para essa nova instância.
5. O método saveGameState é responsável por serializar o objeto. Ele recebe dois parâmetros - o caminho
para o arquivo e a referência ao objeto que deve ser serializado.
7. É necessária apenas uma linha de código para serializar o GameState objeto no arquivo usando o método
write .
9. Leva apenas uma linha de código para desserializar o arquivo em um GameState objeto usando o método
read . Neste exemplo, o mesmo programa serializa e desserializa o estado do jogo, mas pode não ser o
caso. Você pode enviar o objeto serializado para outro computador na rede, e outro programa pode
desserializar o GameState . Portanto, é importante que a declaração do GameState esteja disponível em
ambos os computadores. A exceção ClassNotFoundException será lançada se a declaração da classe
GameState não estiver disponível.
Execute o programa GameStateManager e você verá que ele cria um novo arquivo [Link] . Abra
esse arquivo em um editor de texto e você verá algumas coisas sem sentido. O Java serializa objetos em seu
formato interno, que não é para ser lido por pessoas. A saída do console ficará assim:
[Link] 223/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
The GameStateObject is serialized
Deserialized the game state
Deserialized game state object; PlayerName: Mary, level:0, score: 28000, remainingLives: 3
Se você colocar o ponto de interrupção logo após a invocação do loadGameState método, poderá ver duas
instâncias diferentes do GameState objeto, conforme mostrado abaixo:
Observe como o IDEA mostra convenientemente os valores das variáveis não apenas na visualização do
depurador na parte inferior, mas no código-fonte do programa em fonte acinzentada.
Para concluir este projeto, você precisa entender como comparar objetos. Embora comparar dois números seja
fácil, objetos Java podem incluir vários campos e você precisa decidir quais campos do objeto devem ser
comparados para colocar os objetos em uma determinada ordem. Nesta tarefa, você ordenará os objetos
Score para que os objetos com maior valor do campo score venham primeiro. Em outras palavras, você
precisará classificar os objetos Score na ordem decrescente do campo score .
1. Crie uma classe serializável Score para representar uma pontuação de jogo.
[Link] 224/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
import [Link];
2. Create a class ScoreManager with the method main . Inside main declare and instantiate a collection of
scores: List<Score> scores . Create the Path object to point at the file [Link] .
JAVA
List<Score> scores = new ArrayList<>();
The class ArrayList is one of the Java collections that implements the List interface, so declaring this
variable of type List is valid.
4. Write the code in the method saveScore to serialize the collection scores into a file [Link] . Use
the code from the class GameStateManager as an example, but this time you’ll need to serialize not one
object instance, but a collection of objects, for example:
JAVA
try (ObjectOutputStream whereToWrite = new ObjectOutputStream(
[Link](path, [Link]))){
[Link](gameScores);
[Link] 225/303
22/03/2025, 18:48 Programação Java para crianças
5. Write the code in the method loadScores to deserialize the data from the file [Link] :
JAVA
List<Score> loadedScores= null;
loadedScores=
(List<Score>) [Link]();
return loadedScores;
6. Starting from this step all coding should be done in the main method of ScoreManager . If the file
[Link] already exists, load the collection of score. If [Link] doesn’t exist, create a new collection.
JAVA
if ([Link](path)) {
scores = loadScores(path);
} else {
scores = new ArrayList<>();
}
7. Create an instance of the Score class, populate its fields name , score , and dateTime . Assign a
random number generated by the class [Link] to the score field. Assign the current date
and time to the field dateTime Use the method nextInt to generate a number between 0 and 50000.
Add the hew score to the scores collection.
JAVA
Random numberGenerator = new Random();
[Link](myScore);
8. Print all the scores and invoke the method saveScore to serialize all scores into the file.
JAVA
[Link]("All scores:");
[Link](s -> [Link](s));
saveScores(path, scores);
[Link] 226/303
22/03/2025, 18:48 Programação Java para crianças
9. Sort and print the collection to show the highest score on top. Use the class Comarator to specify that
sorting should be done by the field score . For sorting in the descendant order invoke the method
reverseOrder . Use the Stream API.
JAVA
[Link]("Sorted scores (highest on top):");
Comparator<Score> byScoreDescending =
[Link]([Link](s -> [Link]));
[Link]()
.sorted(byScoreDescending)
.forEach(s -> [Link](s));
10. Run the program ScoreManager and observe that all scores are printed in descending order. :toc-
placement!: :imagesdir: .
[Link] 227/303
22/03/2025, 18:48 Programação Java para crianças
Say, you want to find a book about Harry Potter in the online bookstore. Usually you’d need to enter Harry
Potter in the search field of that bookstore Web site and press the button to start the search, but the browser sends
a request with a lot more data than a dozen of characters you’ve entered. According to HTTP protocol, every
request should include a request header, which defines the method of sending data, identifies the browser that
sends it, requests to keep the connection open (or not), and has other attributes.
Similarly, a server should run a program that receives and understands the HTTP request, finds all books that
have Harry Potter in the title, and sends a response back to you, adding a response header to the data. Both
request and response headers can add several hundred bytes to the actual data being sent.
Some other popular networking protocols are TCP/IP, FTP, WebSocket. In this chapter you’ll learn how to write
Java programs that can connect to remote servers and download data using HTTP protocol.
This URL tells me that the host (the server) [Link] has the file called [Link] located
in the folder games. The port number plays the same role as an apartment number in a building.
The server [Link] can run many programs, which serve users' requests, but we want to enter this server
through "the door" number 80. As a matter of fact, the port number 80 is a default port number for all Web
servers that use HTTP. That’s why if you skip the port number, your Web browser will try to connect to the Web
server via the port 80.
[Link] 228/303
22/03/2025, 18:48 Programação Java para crianças
If a URL starts with https, the s stands for "secure". All requests and responses are automatically encrypted by
the browser and the server for additional security. If the user enters a URL that starts with https and has no port
number, the Web browser sends an HTTPS request to the server’s port 443.
There is no file name here. What does video stand for in this URL? It’s not a file, and it’s not a folder on the host
either. It’s just an ID that represents some resources at [Link]. There is a program running at [Link] that
understands what this ID means and redirects the request to the application that serves the Web page with videos
that may look like this:
Often the content that corresponds to a resource ID is not stored in a file, but is generated on the fly by a server-
side program and can change daily, hourly, every minute or every second. Most likely by the time you enter
[Link] in your browser the content will be different.
[Link] 229/303
22/03/2025, 18:48 Programação Java para crianças
When you’re entering a domain name in the browser, your Internet service provider uses special software to find
the IP address that corresponds to the entered domain name. If found, your browser receives the requested Web
page, which is a document in HTML format. If not found, you’ll get an error message that your search didn’t
match any documents.
You can say,"But entering [Link] shows a lot of content even without providing any document name!" This
happens because Web sites creators configure their servers to serve a certain HTML file if the user doesn’t
specify any. Often they name the file with the home page content [Link], but it can be any other file too.
Most people connected to the Internet are getting dynamic (temporary) IP addresses assigned to their computers,
which can change without notice.
In particular, Java has a class [Link] that helps your program to connect to a remote computer on the
Internet and get access to a resource there, provided that it’s not protected from public access.
Let’s see how you can start writing a program that creates an instance of the URL object that points at some
remote resource, e.g. [Link]:
JAVA
try{
URL myUrl = new URL("[Link]
[Link] 230/303
22/03/2025, 18:48 Programação Java para crianças
The MalformedURLException is thrown if you made a typo in the code, e.g. you’ve typed htp instead of http
or some spaces sneaked into the URL. If the MalformedURLException is thrown, it does not indicate that the
remote server is down; just check "the spelling" of your URL.
Creation of the URL object does not establish a connection with the remote computer. If your program needs to
read a remote file, you still need to open a stream on that file. Usually a program performs the following steps to
read a file from the Internet via HTTP connection:
2. Create an instance of the URLConnection to open a connection using the URL object from Step 1.
3. Get a reference to the input stream of this object by calling the method getInputStream from
URLConnection .
While writing code for reading streams over the network, you’ll have to handle possible I/O exceptions the same
way you did while reading the local files in Chapter 11. The following program WebSiteReader reads and
prints the code of [Link] page.
[Link] 231/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try
{
url = new URL("[Link] ); (1)
String currentLine;
[Link](currentLine);
}
} catch(MalformedURLException ex){
[Link] ("Check the spelling of the URL" + [Link]());
}
catch(IOException ioe){
[Link]("Can't read from the Internet: "+
[Link]());
}
}
}
2. Then it gets a reference to an instance of the URLConnection object to open a connection with the stream.
4. The while loop reads the line from BufferedReader and if it’s not null , it prints the line on the
console.
[Link] 232/303
22/03/2025, 18:48 Programação Java para crianças
Make sure your computer is connected to the Internet before you run the WebSiteReader program. Actually, I
was writing this program while sitting on the plane without the Internet connection. This is what the program
printed up in the sky:
HTML
Can't read from the Internet: [Link]: [Link]
When my computer got the Internet connection the output was different. Here’s a fragment of what you can
expect to see on the console after running WebSiteReader :
JAVASCRIPT
<!doctype html><html itemscope="" itemtype="[Link] lang="fr"><head><meta
content="/logos/doodles/2015/110th-anniversary-of-first-publication-of-becassine-
[Link]" itemprop="image"><title>Google</title><script>(function()
{[Link]=
{kEI:'5OzPVMyJM4ukygPRz4CoBQ',kEXPI:'4011559,4013606,4020347,4020562,4021598,4022545,4023678,40
24599,4024626,4025090,4027899,4027921,4028062,4028128,4028367,4028508,4028634,4028706,4028717,8
300111,8500393,8500852,8501081,8501084,10200083,10200903,10200904',authuser:0,kSID:'5OzPVMyJM4u
kygPRz4CoBQ'};[Link]='us';})();(function(){[Link]=
[];[Link]=0;[Link]=function(a){for(var b;a&&(![Link]||!
(b=[Link]("eid")));)a=[Link];return b
This is a mix of HTML and JavaScript code. The class WebSiteReader explicitly creates the object
URLConnection . Strictly speaking, you could achieve the same result by using only the class URL :
JAVA
URL url = new URL("[Link]
InputStream in = [Link]();
BufferedReader buff= new BufferedReader(new InputStreamReader(in));
The reason you may want use the URLConnection class is that it could give you some additional control over
the I/O process. For example, by calling its method setDoOutput with the argument true you enable
WebSiteReader to write to the remote URL . In this case you’d need to get a reference to an OutputStream
object by calling getOutputStream method on the URLConnection object. If you wanted to write a program
that can send data to the server, you’d need to learn server-side programming, which this book doesn’t cover.
[Link] 233/303
22/03/2025, 18:48 Programação Java para crianças
A classe a seguir FileDownload cria o URLConnection objeto e obtém seu InputStream . Esta classe
também cria um OutputStream para o arquivo local. A URL e o nome do arquivo local são fornecidos ao
FileDownload programa como argumentos de linha de comando (explicados no Capítulo 11). O
FileDownload conecta-se à URL fornecida, baixa seu conteúdo e o salva no arquivo local.
[Link] 234/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
class FileDownload{
URLConnection fileStream=null;
try{
URL remoteFile=new URL(args[0]); (2)
fileStream=[Link](); (3)
int data;
while((data=[Link]())!=-1){ (7)
[Link](data); (8)
}
[Link] 235/303
22/03/2025, 18:48 Programação Java para crianças
1. Este programa começa verificando se dois argumentos de linha de comando foram fornecidos. Se não, ele
imprime a mensagem mostrando a maneira correta de iniciar FileDownload e sai do programa invocando
o método exit no System objeto.
2. Em seguida, o programa cria uma instância do URL objeto usando a URL fornecida como o primeiro
argumento da linha de comando.
4. Criar um Path objeto apontando para um arquivo local onde os dados baixados serão salvos.
Preparei uma imagem para você que está localizada em [Link] . É uma foto que tirei na
cidade de Nova York há algum tempo. Execute este programa com os dois argumentos de linha de comando a
seguir:
HTML
[Link] [Link]
JAVA
Downloading from [Link] Please wait...
Finished downloading the file. It's located at
/Users/yfain11/IdeaProjects/jfk/Chapter12/[Link]
O FileDowload programa baixou a foto e a salvou no arquivo [Link] . Este programa não tem conhecimento
de que tipo de dados ele baixou - ele estava simplesmente lendo e gravando os dados byte após byte. Neste caso,
era uma imagem, mas o mesmo programa pode ser usado para baixar áudio e outros arquivos que tenham acesso
aberto ao público.
Se você abrir o arquivo baixado com um programa que possa mostrar imagens, verá a seguinte foto:
[Link] 236/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 237/303
22/03/2025, 18:48 Programação Java para crianças
Neste capítulo, mostrei como baixar um arquivo usando HTTP. Desenvolvedores Java profissionais usam várias
técnicas, tecnologias e protocolos para trabalhar com conteúdo remoto. Se você estiver interessado em explorar
esses tópicos avançados por conta própria, o Tutorial Java EE ([Link] é um bom
começo. Talvez um dia eu escreva um livro sobre programação do lado do servidor para crianças.
[Link] 238/303
22/03/2025, 18:48 Programação Java para crianças
2. Clique com o botão direito no botão azul "Free MP3", e você verá um menu pop-up do navegador.
Selecione o item de menu que permite copiar o endereço do link. O link será copiado na área de
transferência do seu computador. Selecionei um link para um arquivo de música que se parecia com este:
HTML
[Link]
3. No IDEA, selecione o menu Run | Edit Configuration e cole este link no campo Program arguments para o
FileDownload programa. Este link será o primeiro argumento da linha de comando.
4. Mova o cursor para o final do campo Program arguments e adicione um espaço seguido pelo nome do
arquivo local, onde você quer salvar a música. Eu digitei song1.mp3 . Então pressione o botão OK.
5. Execute o programa FileDownload . O arquivo MP3 será baixado para o arquivo local song1.mp3. Aqui
está a saída do console que obtive:
HTML
Downloading from
[Link] Please
wait...
Finished downloading the file. It's located at
/Users/yfain11/IdeaProjects/jfk/Chapter12/song1.mp3
[Link] 239/303
22/03/2025, 18:48 Programação Java para crianças
7. Feche o IDEA e repita o mesmo exercício na linha de comando. Você precisará abrir uma janela de
Comando (ou Terminal), alterar o diretório para onde o arquivo [Link] está localizado. Por
padrão, o IDEA armazena classes compiladas no diretório out/production . Meu projeto IDEA foi nomeado
Chapter12, e é aqui que suas classes compiladas estavam localizadas no meu computador:
HTML
/Users/yfain11/IdeaProjects/jfk/Chapter12/out/production/Chapter12
8. Execute o FileDownload programa fornecendo a URL e o nome do arquivo local como argumentos de
linha de comando. Ele deve baixar o arquivo da mesma forma que fez no IDEA IDE.
[Link] 240/303
22/03/2025, 18:48 Programação Java para crianças
Ping-Pong é o jogo perfeito para ilustrar as capacidades de desenho e animação do JavaFX. Neste jogo, você terá
outra chance de trabalhar com manipuladores de eventos e aprenderá como mover (animar) formas pelo palco.
13.1. A Estratégia
Vamos criar algumas regras para o nosso jogo de pingue-pongue:
1. Este jogo terá dois jogadores chamados Kid e Computer. A mesa deve ser pintada de verde, e a raquete
esquerda deve ser pintada de azul - ela será controlada pelo Computer. A raquete direita deve ser amarela -
ela será controlada pelo Kid. Inicialmente a bola vermelha deve estar localizada no centro da mesa.
2. Um novo jogo começa quando um jogador pressiona a tecla N no teclado, pressionar Q encerrará o jogo e a
tecla S sacará a bola. Somente a criança pode sacar a bola.
3. Os movimentos da pá do Kid devem ser controlados pelas teclas de seta para cima e para baixo. Pressionar a
tecla uma vez deve mover a pá verticalmente pelo número predefinido de pixels para cima ou para baixo. A
pá não deve cruzar as bordas da mesa.
4. O Kid pode mover a raquete direita e pressionar a tecla S. Isso deve sacar a bola da posição onde a raquete
direita está localizada. A bola pode se mover em um ângulo, o que significa que suas coordenadas x e y
devem mudar durante o movimento. Se a bola cruzar as bordas superior ou inferior da mesa, o Kid perde um
ponto.
5. Enquanto a bola se move para a esquerda, o computador deve mover a raquete esquerda na direção do
movimento da bola.
6. Se a bola tocar a raquete esquerda, ela deve quicar e começar a se mover para a direita. Quando o
Computador quica a bola, ela pode se mover apenas horizontalmente para a direita.
7. Se a bola tocar na raquete do Kid na metade superior da mesa, a bola deve estar se movendo na direção para
cima e para a esquerda. Se a bola estiver localizada na parte inferior da mesa, ela deve se mover na direção
para baixo e para a esquerda. O jogo dura até que um dos jogadores atinja a pontuação de 21. Como o
computador não pode sacar a bola, o Kid deve marcar um ponto se a bola cruzar a borda esquerda da mesa.
[Link] 241/303
22/03/2025, 18:48 Programação Java para crianças
Se a bola cruzar as bordas superior ou inferior da mesa, o ponto é dado ao computador. O computador
também pode ganhar o ponto se quicar a bola e ela cruzar a borda direita da mesa. Essas regras não são as
mesmas de um jogo de pingue-pongue real, mas são boas o suficiente para o nosso jogo.
8. O placar do jogo deve ser exibido no canto inferior esquerdo da tabela.
A princípio, parece ser uma tarefa muito desafiadora. Na programação, muitas vezes temos que dividir o
problema complicado em um conjunto de tarefas menores e mais simples. A capacidade de fazer isso é chamada
de pensamento analítico , e ajuda não apenas na programação, mas em todos os lugares da sua vida. Não fique
frustrado se não conseguir atingir uma grande meta, divida-a em um conjunto de tarefas menores e alcance-as
uma de cada vez!
Vamos começar a quebrar nossa tarefa complexa. Tente visualizar uma mesa de pingue-pongue. Você consegue
escrever um programa que desenhe um retângulo verde? Esse é nosso primeiro objetivo a atingir. Então
adicionaremos a raquete. Então veremos como desenhar a bola. Aprender a mover a bola será a próxima tarefa.
Escrever os manipuladores de eventos do teclado não deve ser muito difícil.
Agora vamos implementar cada passo da estratégia do jogo, um passo de cada vez.
Vamos começar criando um novo projeto JavaFX no IntelliJ IDEA. Selecione JavaFX como um tipo de projeto.
Pressione Next e insira PingPong como um nome de projeto na próxima janela pop-up. Pressione o botão Finish
e o IDEA gerará um novo projeto para você. Renomeie (clique com o botão direito do mouse | Refactor |
Rename) o arquivo [Link] para [Link] , a Main classe para PingPong , e Controller para
PingPongController . Altere o nome do pacote de sample para pong da mesma forma.
[Link] 242/303
22/03/2025, 18:48 Programação Java para crianças
Agora vamos desenhar a mesa de pingue-pongue no Scene Builder. Clique com o botão direito no arquivo
[Link] e abra-o no Scene Builder. Como você viu no Capítulo 7, o FXML gerado usa o
<GridBag> como um contêiner padrão. Você verá um vazio GridBag no painel Hierarchy. O lado esquerdo
dos painéis do Scene Builder terá a seguinte aparência:
[Link] 243/303
22/03/2025, 18:48 Programação Java para crianças
Não vou usar nenhum layout no jogo PingPong. O jogo consistirá em uma série de formas que manterei no
Group contêiner. Ainda não o usamos - ele Group é usado apenas para manter vários componentes filhos
juntos. Agrupar componentes em um contêiner pode ser útil se você precisar atribuir um manipulador de eventos
a todos os componentes filhos ou redimensioná-los automaticamente como um grupo.
No Scene Builder, exclua o GridBag contêiner e arraste/solte o Group da seção Miscellaneous para o painel
Hierarchy. Em seguida, arraste/solte a Rectangle do painel Shapes para o Group . Redimensione-o e escolha
uma cor verde agradável na propriedade Fill no lado direito. Você escolherá uma cor de uma paleta suspensa, e o
código de cor correspondente será inserido automaticamente como uma fill propriedade do Rectangle . Seu
Scene Builder deve ficar assim:
Abra o arquivo [Link] e você verá a tag <Rectangle> dentro do <Group> gerado pelo Scene Builder.
Defina a largura do Rectangle para 400, e a altura para 250. Deve ficar assim:
[Link] 244/303
22/03/2025, 18:48 Programação Java para crianças
XML
<?xml version="1.0" encoding="UTF-8"?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link].*?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
<?import [Link]?>
O archHeight e arcWidth foram gerados automaticamente caso você precise criar cantos arredondados no
retângulo. As propriedades stroke e strokeType definem a aparência e o posicionamento da borda do
retângulo. Cada retângulo tem as propriedades x e y que definem as coordenadas do seu canto superior
esquerdo dentro do contêiner. Por padrão, os valores de x e y são zeros, então este retângulo será desenhado a
partir do canto superior esquerdo do Group contêiner.
Se você estiver interessado em aprender como diferentes propriedades alteram a aparência do retângulo, visite a
documentação online ([Link] para esta classe.
Tenha em mente que algumas das propriedades são definidas na classe Shape , a ancestral da Rectangle .
[Link] 245/303
22/03/2025, 18:48 Programação Java para crianças
Há algumas coisas que não gosto aqui. Primeiro, os cantos do retângulo são arredondados só um pouquinho. Isso
é causado pelas propriedades archHeight e arcWidth , que são diâmetros verticais e horizontais dos arcos de
canto. Vou excluí-los da tabela retângulo em [Link] .
Segundo, a janela tem um título Hello World definido pelo código gerado automaticamente no IntelliJ IDEA. É
fácil mudar na classe PingPong , mas eu nem quero ver uma barra de título!
Esta também é uma correção fácil no JavaFX. Definir o estilo do palco para UNDECORATED removerá o título e
as bordas padrão da janela. Mas se eu remover a barra de título, perderei a capacidade de fechar a janela clicando
no círculo (ou uma pequena cruz no Windows). Um pouco mais tarde, escreveremos o código para fechar a
janela pressionando a tecla Q no teclado. Neste ponto, o código da PingPong classe se parece com isto:
[Link] 246/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package pong;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Override
public void start(Stage primaryStage) throws Exception{
This class was generated by IDEA, but I’ve removed the Hello World title, set the size of the scene to 400 by
250 pixels, and added the line [Link]([Link]); . Running the
PingPong class will display the following green rectangle:
[Link] 247/303
22/03/2025, 18:48 Programação Java para crianças
Now let’s open [Link] in Scene Builder again and add the paddles and the ball on top of the table. For
paddles, I’ll drag/drop two Rectangle objects from the Shapes section onto the Group container. Our paddles
will have a size of 10 by 50 pixels. The left paddle will be blue, and the right one will be yellow. Then I
drag/drop, resize and color the Circle to set its radius to 9 pixels, and then will paint it red. My Scene Builder
will look like this:
[Link] 248/303
22/03/2025, 18:48 Programação Java para crianças
Now back to IDEA. Since our shapes will need to communicate with the controller class, we need to assign an
fx:id to each of them. Let’s assign the fx:id="theGroup" to the Group container. Our green Rectangle
will get fx:id="table" .
The computer will play with the left paddle, and I’ll give it fx:id="compPaddle" . The Kid will play with the
right paddle that will go by fx:id="kidPaddle" . The ball will get fx:id="ball" . Now The Group
container in my file [Link] will look like this:
XML
<Group fx:id="theGroup" xmlns="[Link] xmlns:fx="[Link]
<children>
<Rectangle fx:id="table" fill="#31b287" height="250" stroke="BLACK" strokeType="INSIDE"
width="400" />
<Rectangle fx:id="compPaddle" arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE"
height="50.0" layoutX="24.0" layoutY="98.0" stroke="BLACK" strokeType="INSIDE" width="10.0" />
<Rectangle fx:id="kidPaddle" arcHeight="5.0" arcWidth="5.0" fill="#f0ff1f" height="50.0"
layoutX="365.0" layoutY="98.0" stroke="BLACK" strokeType="INSIDE" width="10.0" />
<Circle fx:id="ball" fill="#ff1f35" layoutX="191.0" layoutY="123.0" radius="9.0"
stroke="BLACK" strokeType="INSIDE" />
</children>
</Group>
Running the PingPong program will display the following ping-pong table:
[Link] 249/303
22/03/2025, 18:48 Programação Java para crianças
The GUI drawing is complete, now we need to take care of the user interactions, which will be done in the class
PingPongController . In [Link] we need to assign this class as the fx:controller to the Group
(see Chapter 8 for a refresher):
XML
<Group fx:id="theGroup" fx:controller="[Link]"
xmlns="[Link] xmlns:fx="[Link]
Dear Scene Builder and FXML, you’ve been very helpful. Now I’m happily going back to Java programming.
For processing keyboard events JavaFX components have special event handler properties onKeyPressed ,
onKeyReleased , and onKeyTyped . The first two properties allow you to program different actions for the
downward and upward key motions, if needed.
The onKeyTyped is used to assign a handler to the event when the key code is sent to the system output. This
event is not generated ([Link] for the keys that
don’t produce character output. We’ll use onKeyReleased - this is when the the user lifts his finger up.
[Link] 250/303
22/03/2025, 18:48 Programação Java para crianças
IDEA can help you find out which event handlers can be used with a particular component.
NOTE Just click CTRL-Space inside this component’s FXML tag and start typing with the letters
on and you’ll see all applicable event handlers.
When the user releases a key, the onKeyReleased method handler receives the KeyEvent object as an
argument. The method getCode from the class KeyEvent returns the KeyCode object that represents the key
pressed. For example, if you press the button Q, the getCode will return Q . If you press the arrow up, the
getCode will return UP .
But the same key can result in displaying more than one character (e.g. Q or q) The method getText of
KeyEvent returns a String that represents the character typed by the user.
To enable our GUI to react on keyboard events right after the program starts, we need to set the focus on the
GUI. This was not required when we clicked on the GUI components with the mouse, but now we won’t even
touch the screen.
To set the focus to the Group container we’ll need to do two things:
1. Enable the Group to receive the focus by useing the attribute focusTraversable="true" in
[Link].
2. Right after the stage is displayed in the PingPong class, we’ll call the method requestFocus on the
Group container. The method start in PingPong will look like this (I’ve added just the last line to the
code generated by IDEA):
JAVA
public void start(Stage primaryStage) throws Exception{
[Link]();
[Link]();
}
[Link] 251/303
22/03/2025, 18:48 Programação Java para crianças
comment in each class briefly describes what was added in this version of the controller. To see any of these
controllers in action, just specify its name as fx:controller in the file [Link] and run the
PingPong program.
In InelliJ IDEA you can easily compare two files to see the difference. Press CTRL or CMD
button and click on the names of two files you’d like to compare (e.g.
NOTE PingPongController_v1 and PingPongController_v2 ). Then select the menu View |
Compare Two Files, and you’ll see the source code of these files next to each other with
highlighted differences.
Let’s add to the PingPongControler a method handler for the key-released events. The first very simple
version of the PingPongControler is shown next. The goal is to see that the controller receives the keyboard
events and can recognize the keys pressed by the player.
JAVA
package pong;
import [Link];
import [Link];
The event handler method just extracts the key code from the KeyEvent object provided by the Java runtime
and prints it. For example, after running the PingPong class and pressing the up and down arrows, n, q, and s
keys, the console output should look like this:
HTML
You pressed UP
You pressed DOWN
You pressed N
You pressed Q
You pressed S
The KeyCode in PingPongController is not a class or an interface, but a special Java construct called
enum described next.
[Link] 252/303
22/03/2025, 18:48 Programação Java para crianças
Our controller class declares a variable of type KeyCode , which is neither a class nor an interface. It’s a special
Java data type enum used for declaring a bunch of pre-defined constants that never change. For example, you
can declare a new enum type day-of-the-week:
JAVA
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
The following class GreetTheDay illustrates the use of the enum Day :
JAVA
public class GreetTheDay {
greet([Link]);
}
The method greet expects to receive one of the Day values as an argument. Our main method wants to greet
Saturday, and if you run the program GreetTheDay it’ll print Hello Weekend!.
[Link] 253/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package pong;
import [Link];
import [Link];
import [Link];
switch (keyCode){
case UP:
process_key_Up();
break;
case DOWN:
process_key_Down();
break;
case N:
process_key_N();
break;
case Q:
[Link](); // Terminate the app
break;
case S:
process_key_S();
break;
}
}
The switch statement checks the value of enum KeyCode and calls the corresponding method which just
prints a hard-coded message. We’ll implement them shortly, but the Q-key in the above PingPongController
is fully functional. When the user presses the Q-key, the program invokes the method exit on the class
[Link] 254/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
final int PADDLE_MOVEMENT_INCREMENT = 6;
Pressing the key once will change the vertical position of the paddle by 7 pixels. Seven is not a magical number,
and you can use any other integer here.
The new version of the controller will use the @FXML annotations to inject the references to the GUI
components. To update the position of the kid’s paddle on the GUI we’ll use data binding explained in Chapter
8. We’ll also add the method initialize that is invoked by the Java runtime once when the controller object
is created. Finally, we’ll write the code in the methods process_key_Down and process_key_Up to move
the kid’s paddle vertically.
In JavaFX the x and y coordinates of the top left corner of the stage have zero values. x-coordinate increases
from left to right, and the y-coordinate increases from top to bottom. The following image shows how x and y
coordinates change if a ping-pong table has the width of 400 pixels and the height of 250:
[Link] 255/303
22/03/2025, 18:48 Programação Java para crianças
No nosso jogo, as pás podem se mover apenas para cima ou para baixo, então, dependendo da tecla pressionada,
mudaremos o valor da propriedade layoutY da pá direita, o que a moverá no palco de acordo. Veja como ela
PingPongController ficará agora:
[Link] 256/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package pong;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
DoubleProperty currentKidPaddleY =
new SimpleDoubleProperty(); (1)
[Link]([Link]()); (4)
[Link]().bind(currentKidPaddleY);
switch (keyCode){
case UP:
process_key_Up();
break;
case DOWN:
process_key_Down();
break;
case N:
process_key_N();
break;
case Q:
[Link](); // Terminate the application
[Link] 257/303
22/03/2025, 18:48 Programação Java para crianças
break;
case S:
process_key_S();
break;
}
}
if ([Link]()< allowedPaddleBottomY) {
[Link]([Link]() + PADDLE_MOVEMENT_INCREMENT);
}
}
2. O Kid estará movendo a raquete para cima e para baixo, mas não queremos permitir que a raquete saia dos
limites da mesa. A variável allowedPaddleTopY armazenará a coordenada y máxima permitida para o
topo da raquete, e allowedPaddleBottomY terá a coordenada y máxima permitida para a parte inferior da
raquete.
3. Usando a @FXML tag, injetamos as referências aos componentes da GUI definidos em [Link] nas
variáveis do controlador.
4. O método initialize no controlador é chamado apenas uma vez e é o lugar certo para inicializar
variáveis importantes. Primeiro, inicializamos a propriedade currentKidPaddleY , com o valor da
layoutY propriedade da raquete direita (o componente kidPaddle tem um atributo layoutY="98.0" no
arquivo [Link] ). Então, vinculamos currentKidPaddleY à layoutY propriedade do componente
GUI kidPaddle.
[Link] 258/303
22/03/2025, 18:48 Programação Java para crianças
A bola é representada pela forma Circle . Da matemática escolar, você deve lembrar que um círculo é
representado pelas coordenadas do centro e do raio. No JavaFX, as propriedades correspondentes da classe
Circle são chamadas centerX , centerY , e radius . Quando o Circle é colocado em um layout, seu
centro obtém as propriedades correspondentes layoutX e layoutY . Ao alterar as coordenadas do centro,
podemos mover a bola pelo palco. Nossa bola é definida no arquivo [Link] assim:
XML
<Circle fx:id="ball" fill="#ff1f35" layoutX="191.0" layoutY="123.0" radius="9.0" stroke="BLACK"
strokeType="INSIDE" />
Mas por que a tag acima não <Circle> inclui centerX and centerY ? Na verdade, podemos e iremos
substituir os atributos layoutX and layoutY por centerX and centerY porque usamos o Group contêiner
que não faz parte de nenhum outro layout (por exemplo, BorderPane or GridPane ). O JavaFX permite que
você crie cenas complexas que podem alterar dinamicamente os tamanhos e reposicionar seus componentes
filhos. Portanto, as coordenadas x e y de um componente em relação a um layout podem não ser as mesmas que
as coordenadas na cena. Por exemplo, a coordenada x real de um componente pode ser calculada adicionando a
coordenada x de um contêiner dentro de uma cena e a coordenada x do componente dentro de um contêiner.
XML
<Circle fx:id="ball" fill="#ff1f35" centerX="191.0" centerY="123.0" radius="9.0" stroke="BLACK"
strokeType="INSIDE" />
[Link] 259/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
DoubleProperty ballCenterX = new SimpleDoubleProperty();
DoubleProperty ballCenterY = new SimpleDoubleProperty();
No método, initialize definiremos os valores iniciais dessas propriedades para as coordenadas centrais da
bola. Também vincularemos as propriedades acima ao centro do Circle , então alterar ballCenterX e
ballCenterY mudará automaticamente a localização da bola na cena:
JAVA
[Link]([Link]());
[Link]([Link]());
[Link]().bind(ballCenterX);
[Link]().bind(ballCenterY);
Vamos colocar a bola na posição atual da raquete da criança. No método, process_key_S ajustaremos a
centerY coordenada da bola. Nosso controlador tem a variável currentKidPaddleY que lembra a
coordenada y atual do topo da raquete da criança. Então, se adicionarmos à currentKidPaddleY metade da
altura da raquete, obteremos a coordenada y do centro da raquete. A centerX coordenada será a mesma da
layoutX raquete da criança. A nova versão do método process_key_S ficará assim:
JAVA
private void process_key_S() {
[Link]([Link]() + [Link]()/2);
[Link]([Link]());
}
Executei o PingPong aplicativo, movi a raquete para cima clicando na tecla de seta várias vezes e, em seguida,
pressionei a tecla S. A bola obedientemente se moveu para a posição atual da raquete direita:
[Link] 260/303
22/03/2025, 18:48 Programação Java para crianças
Each frame is represented by a class KeyFrame . Each snapshot is represented by the class KeyValue . Let’s
write a method moveTheBall that will move the ball horizontally all the way to the left until the centerX will
become equal to zero. If we change only the centerX property of the Circle , it’ll be moving horizontally.
[Link] 261/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
Timeline timeline;
[Link]().add(keyFrame); (4)
[Link](); // (5)
}
1. First we create an instance of the Timeline object and invoke the setCycleCount requesting that the
animation will be done only once. In this example we could have declared the variable timeline inside
the method, but keeping this variable on the class level will allow me to programatically stop the animation
that I’ll demonstrate in the next version of the method moveTheBall .
2. Then we’ll create the KeyValue object to specify which changing value to display in frames. In this case
we want the animation to change the x-coordinate of the ball center from its current value ballCenterX to
zero.
3. We want the KeyFrame to reach the target (change the centerX specified in KeyValue from the current
value to zero) over a period of 1000 milliseconds. The smaller the number, the faster the ball will move. The
number of frames will be automatically calculated based on the duration and the target position of the ball.
4. Adding the our KeyFrame object to the timeline completes the preparations.
Now if you’ll invoke the method moveTheBall from process_key_S the ball will move to the left and stop
there. Here’s what I’ve got after starting the game and pressing the S-key:
[Link] 262/303
22/03/2025, 18:48 Programação Java para crianças
Our ball is not smart enough to notice that there was a left paddle on its way and went right through it. We’ll take
care of the GUI component collisions a bit later.
Depending on the provided duration, the Timeline object will calculate how many snapshots (key frames) to
create while the KeyValue is changing to reach the target. The Timeline class has several overloaded
constructors ([Link] and one of
them allows you to specify the frames per second for the animation.
Na versão a seguir do método, moveTheBall escreveremos o código para avançar a bola nos incrementos
especificados. Também usaremos construtores diferentes de TimeLine e KeyFrame :
[Link] 263/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
final int BALL_MOVEMENT_INCREMENT = 5;
} else {
[Link](); (4)
}
}
);
1. O primeiro argumento do construtor é o Duration objeto, mas dessa vez ele tem um significado diferente
do que na versão anterior do moveTheBall . O valor 10 significa executar o código do manipulador de
eventos (a expressão lambda) a cada 10 milissegundos.
2. A expressão lambda começa com a verificação se o valor atual da coordenada x do centro da bola é maior
que o valor em BALL_MOVEMENT_INCREMENT para garantir que a bola não cruzará a borda esquerda e
permanecerá nas coordenadas 0. Para tornar nosso jogo mais realista, deixaremos a bola sair da mesa na
próxima versão do moveTheBall .
5. Crie o Timeline usando nosso KeyFrame e reproduza. Neste caso, solicitei reproduzir a animação
indefinidamente porque não quero calcular quantos movimentos seriam necessários para atingir a posição
alvo. Vou parar a animação manualmente de qualquer maneira, conforme explicado na etapa 4.
[Link] 264/303
22/03/2025, 18:48 Programação Java para crianças
Se o usuário moveu a raquete para a metade superior da mesa, a bola deve estar se movendo horizontalmente ou
para baixo. Se a bola for sacada da metade inferior, a bola pode se mover horizontalmente ou para cima. Para
saber a coordenada y do centro da mesa, declararemos a double variável centerTableY e definiremos seu
valor no método initialize assim:
JAVA
centerTableY = [Link]()/2;
Conforme a bola se move, o valor modificado da coordenada y do centro da bola será atribuído à propriedade
ballCenterY . A versão a seguir do método moveTheBall implementa os serviços aleatórios de bola.
JAVA
private void moveTheBall(){
[Link]([Link]() - BALL_MOVEMENT_INCREMENT);
if (isServingFromTop) { (4)
[Link]([Link]() + randomYincrement);
} else {
[Link]([Link]() + randomYincrement);
}
} else {
[Link]();
});
[Link]();
[Link] 265/303
22/03/2025, 18:48 Programação Java para crianças
1. Criamos uma instância da classe [Link] . Esta classe tem métodos para gerar números
aleatórios de diferentes tipos. Invocar o método nextInt gera um número inteiro aleatório no intervalo
entre zero e o valor do argumento do método. Decidi usar o valor de BALL_MOVEMENT_INCREMENT como
um limite superior. Este número aleatório será usado como um incremento para a coordenada y da bola em
movimento.
3. Na versão anterior do método moveTheBall , mantínhamos a bola na mesa quando ela atingia a borda
esquerda da mesa. Agora, deixaremos a bola cair da mesa. Este -20 é apenas um número arbitrário -
paramos o movimento da bola depois que ela se moveu 20 pixels além da borda esquerda da mesa. Na
versão final do jogo, habilitaremos o movimento para a raquete esquerda e, às vezes, ela fará a bola quicar
de volta.
[Link] 266/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
DoubleProperty currentComputerPaddleY = new SimpleDoubleProperty();
double initialComputerPaddleY;
JAVA
initialComputerPaddleY = [Link]();
[Link](initialComputerPaddleY);
[Link]().bind(currentComputerPaddleY);
A nova versão do método moveTheBall iniciará o movimento da raquete do Computador na direção correta
assim que a bola for sacada.
[Link] 267/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
private void moveTheBall(){
[Link]([Link]() - BALL_MOVEMENT_INCREMENT);
if (isServingFromTop) {
[Link]([Link]() + randomYincrement);
} else {
[Link]([Link]() - randomYincrement);
} else {
[Link]();
[Link](initialComputerPaddleY); (3)
}
});
[Link]();
}
1. Se a bola foi sacada de cima, mova a raquete do computador um pixel para baixo em cada quadro.
2. Se a bola foi sacada da metade inferior da mesa, mova a raquete do computador um pixel para cima em cada
quadro.
3. Quando a bola parar de se mover, retorne a raquete do computador para a posição inicial no meio do lado
esquerdo da mesa.
[Link] 268/303
22/03/2025, 18:48 Programação Java para crianças
Cada componente JavaFX GUI é uma subclasse de a Node , que tem uma propriedade especial
boundsInParent . É um retângulo invisível que encapsula o componente quando ele é colocado dentro de um
layout. Então nossa bola e pás estão dentro desses retângulos invisíveis também. Quando a bola ou pás estão
sendo movidas, as coordenadas de suas boundsInParent propriedades estão sendo recalculadas. Se esses
retângulos invisíveis da bola e da pá se cruzam, podemos dizer que houve um contato. O método
checkForBallPaddleContact retorna true se houve um contato, e false se não.
JAVA
private boolean checkForBallPaddleContact(){
if ([Link]([Link]())){
return true;
} else {
return false;
}
}
Devemos chamar esse método de cada quadro na linha do tempo que iniciamos no método moveTheBall .
Após essa verificação de contato com o método, moveTheBall ele ficará assim:
[Link] 269/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
private void moveTheBall(){
[Link]([Link]() - BALL_MOVEMENT_INCREMENT);
if (isServingFromTop) {
[Link]([Link]() + randomYincrement);
} else {
[Link]([Link]() - randomYincrement);
[Link]([Link]() - 1);
}
if (checkForBallPaddleContact()){
[Link](); (1)
[Link](initialComputerPaddleY);
bounceTheBall(); (2)
};
} else {
[Link]();
[Link](initialComputerPaddleY);
}
});
[Link]();
}
1. Se houver contato entre a bola e a raquete, precisamos parar de jogar a raquete atual timeline e colocar a
raquete do computador na posição inicial.
De acordo com o passo 6 da nossa estratégia de jogo, o computador só pode sacar a bola horizontalmente, então
escrever o bounceTheBall método parece algo bem simples de se fazer. Já escrevemos uma versão do
moveTheBall método que envia a bola horizontalmente da direita para a esquerda, então reverter a direção do
[Link] 270/303
22/03/2025, 18:48 Programação Java para crianças
No jargão do programador, reescrever um código existente e funcional é chamado de refatoração . Então, vamos
refatorar o método checkForBallPaddleContact fornecendo o paddle como um argumento. Aqui está a
versão refatorada que pode ser usada para ambos os paddles:
JAVA
private boolean checkForBallPaddleContact(Rectangle paddle){
if ([Link]([Link]())){
return true;
} else {
return false;
}
}
JAVA
checkForBallPaddleContact(compPaddle);
Para verificar o contato da bola com a raquete da criança, você escreveria esta linha:
JAVA
checkForBallPaddleContact(kidPaddle);
Agora vamos escrever o método bounceTheBall , que deve ser muito semelhante a moveTheBall . A bola
deve se mover da esquerda para a direita, se você estiver diminuindo a coordenada x em moveTheBall ,
precisará diminuí-la agora. Se você estiver parando o jogo onde a coordenada da bola era menor que -20, agora
ela precisa ser maior que a largura da mesa mais 20. Eu poderia refatorar o método moveTheBall para
introduzir esses valores como argumentos de métodos, mas vamos mantê-lo como um pequeno projeto para
você. Contanto que você entenda como o código funciona, você deve ser capaz de fazê-lo sozinho. Aqui está o
código do método bounceTheBall :
[Link] 271/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
private void bounceTheBall() {
[Link](ballCenterX);
if ([Link]() < theBallOffTheTableX) {
if (checkForBallPaddleContact(kidPaddle)){ (3)
[Link]();
moveTheBall();
};
} else {
[Link]();
}
});
[Link]();
1. A bola deve parar seu movimento quando sua coordenada x estiver 20 pixels à direita da mesa.
2. Avance a bola para a direita até que sua coordenada x atinja o valor de theBallOffTheTableX .
3. Enquanto o Computador quica a bola, a Criança pode pressionar as teclas de seta para cima e para baixo
para parar a bola. Se a bola entrar em contato com a raquete da Criança, chamamos o
moveTheBall método para iniciar o movimento aleatório para a esquerda novamente.
A funcionalidade básica do jogo é implementada além de exibir a pontuação do jogo e começar o novo jogo
quando um dos jogadores obtém 21 pontos. Vou deixar essa parte para você implementar por conta própria.
[Link] 272/303
22/03/2025, 18:48 Programação Java para crianças
JAVA
package pong;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
double centerTableY;
double allowedPaddleTopY;
double allowedPaddleBottomY;
Timeline timeline;
@FXML
Rectangle table;
@FXML Rectangle compPaddle;
@FXML Rectangle kidPaddle;
@FXML Circle ball;
[Link]([Link]());
[Link]().bind(currentKidPaddleY);
[Link]([Link]());
[Link]([Link]());
[Link] 273/303
22/03/2025, 18:48 Programação Java para crianças
[Link]().bind(ballCenterX);
[Link]().bind(ballCenterY);
initialComputerPaddleY = [Link]();
[Link](initialComputerPaddleY);
[Link]().bind(currentComputerPaddleY);
allowedPaddleTopY = PADDLE_MOVEMENT_INCREMENT;
allowedPaddleBottomY = [Link]() - [Link]() -
PADDLE_MOVEMENT_INCREMENT;
centerTableY = [Link]()/2;
}
public void keyReleasedHandler(KeyEvent event){
switch (keyCode){
case UP:
process_key_Up();
break;
case DOWN:
process_key_Down();
break;
case N:
process_key_N();
break;
case Q:
[Link](); // Terminate the application
break;
case S:
process_key_S();
break;
}
}
if ([Link]()< allowedPaddleBottomY) {
[Link]([Link]() + PADDLE_MOVEMENT_INCREMENT);
}
}
[Link] 274/303
22/03/2025, 18:48 Programação Java para crianças
[Link]([Link]() + [Link]()/2);
[Link]([Link]());
moveTheBall();
}
[Link]([Link]() - BALL_MOVEMENT_INCREMENT);
if (isServingFromTop) {
[Link]([Link]() + randomYincrement);
} else {
[Link]([Link]() - randomYincrement);
[Link]([Link]() - 1);
}
if (checkForBallPaddleContact(compPaddle)){
[Link]();
[Link](initialComputerPaddleY);
bounceTheBall();
};
} else {
[Link]();
[Link](initialComputerPaddleY);
}
});
[Link]();
}
if ([Link]([Link]())){
[Link] 275/303
22/03/2025, 18:48 Programação Java para crianças
return true;
} else {
return false;
}
}
[Link]([Link]() + BALL_MOVEMENT_INCREMENT);
if (checkForBallPaddleContact(kidPaddle)){
[Link]();
moveTheBall();
};
} else {
[Link]();
}
});
[Link]();
}
}
Se o Kid sacasse a bola horizontalmente, ele ou ela marcaria um ponto quando a bola saísse da mesa e sua
coordenada x fosse menor que zero. Mas como a bola é sacada em uma direção aleatória, ela pode sair da mesa
cruzando as bordas superior ou inferior da mesa. Nesse caso, o Kid perde o ponto. Quando o método
moveTheBall para de reproduzir a linha do tempo, a coordenada x da bola é definitivamente menor que zero,
então você precisa verificar a coordenada y da bola.
Se a coordenada y da bola tiver um valor entre zero e a altura da mesa, você pode assumir que a bola cruzou a
borda esquerda da mesa e o Kid marcou um ponto. Caso contrário, a bola cruzou as bordas superior ou inferior
da mesa e o Kid deve perder o ponto.
[Link] 276/303
22/03/2025, 18:48 Programação Java para crianças
O computador marca um ponto se quicar a bola e ela cruzar a borda direita da mesa.
Você precisa declarar duas variáveis de classe para acompanhar as pontuações do computador e da criança:
JAVA
int computerScore;
int kidScore;
Você também precisará escrever um método updateScore e invocá-lo toda vez que a linha do tempo parar de
tocar (em ambos os métodos: moveTheBall e bounceTheBall ). O método updateScore pode se parecer
com isto:
JAVA
private void updateScore(){
O código que vem com o livro tem esta versão do método updateScore implementada. Seu objetivo é exibir a
pontuação em uma fonte agradável no canto inferior esquerdo da tabela. Você pode aprender como trabalhar com
as Text classes Font e estudando o tutorial da Oracle "Working with Text in JavaFX Applications"
([Link] .
Não se esqueça de implementar a funcionalidade Start New Game. Você precisará escrever um método
newGame , onde você deve zerar as pontuações e colocar as raquetes e a bola nas posições iniciais. :toc-
placement!: :imagesdir: .
[Link] 277/303
22/03/2025, 18:48 Programação Java para crianças
Muitos anos atrás, os programadores simplesmente criavam cópias de backup de seus códigos de vez em
quando. Depois de algum tempo, seus discos rígidos teriam várias pastas nomeadas como TicTacToe_Feb_1 ,
TicTacToe_Feb_5 , TicTacToe_Feb_20 e assim por diante. Mas os programadores geralmente trabalham em
equipes, e se Joe e Mary estiverem trabalhando no mesmo aplicativo? Como você pode ter certeza de que os
computadores de Joe e Mary têm a cópia de trabalho do aplicativo com a capacidade de manter o histórico de
alterações de código e retornar a uma versão de trabalho se necessário?
Os programadores usam um software especial chamado Version Control Systems (VCS) que permite manter o
controle de diferentes versões do código-fonte armazenado em repositórios de código-fonte comuns localizados
nos servidores da empresa. Há também instalações especiais de hospedagem na web, onde Joe e Mary podem
manter com segurança o código do aplicativo.
Os desenvolvedores de software fazem alterações em suas cópias locais do código do aplicativo e as testam.
Quando a versão local do aplicativo funciona bem, eles confirmam (salvam) as últimas alterações de código no
repositório de código-fonte. Se Mary tiver confirmado suas alterações, Joe pode verificar o código mais recente
do repositório compartilhado em seu computador. As alterações de Mary serão mescladas com as de Joe em seu
computador.
Agora Joe tem o código mais recente de Mary, mas ela não tem as últimas alterações de código de Joe. Quando
Joe decide fazer commit do seu código mais recente no repositório compartilhado, Mary pode fazer o check-out
deles no computador dela.
Neste capítulo, apresentarei a você um VCS popular chamado Git e ao recurso de hospedagem de código
chamado GitHub. VCS são usados por programadores que escrevem código em qualquer linguagem, não apenas
em Java. Na verdade, você pode controlar qualquer arquivo usando o Git e armazená-lo no GitHub ou em outros
hosts. Se seu computador for perdido ou roubado, você sempre poderá recuperar o código puxando -o do
GitHub.
Eu estava usando o Git como um VCS e o GitHub como um repositório compartilhado dos rascunhos de todos
os capítulos deste livro, e você pode encontrá-los no GitHub em [Link]
([Link] .
[Link] 278/303
22/03/2025, 18:48 Programação Java para crianças
Entender como um VCS funciona é muito importante - é por isso que incluí este pequeno tutorial do Git no livro
sobre Java.
Se Pete, o novo programador, se juntar à equipe, ele precisaria verificar o código mais recente do repositório
central e começar a fazer suas modificações de código em seu computador. Existem muitos VCS centralizados, e
alguns dos mais populares são CVS, SVN e Perforce.
VCS distribuídos armazenam a versão mais recente do código, bem como todos os arquivos históricos no
computador de cada programador. VCS distribuídos populares são Git, Mercurial e Bazaar. Tecnicamente, se
você trabalha sozinho, pode instalar o Git no seu computador e ter seu VCS privado sem usar nenhum servidor
remoto como um repositório compartilhado. Mas, novamente, ter uma cópia extra dos arquivos do seu projeto
em um servidor remoto é sempre uma boa ideia.
Os programadores geralmente trabalham em equipes, então o diagrama a seguir mostra três computadores: um
repositório compartilhado à direita e dois repositórios locais (de Mary e Joe) à esquerda.
[Link] 279/303
22/03/2025, 18:48 Programação Java para crianças
A qualquer momento, cada repositório local armazena o histórico de todas as atualizações feitas por seu
proprietário, bem como atualizações históricas que o proprietário extraiu do repositório compartilhado. Vamos
ver como criar um repositório de código-fonte do seu computador que é gerenciado pelo Git.
Existem várias ferramentas GUI ([Link] para trabalhar com repositórios Git, mas
usaremos uma janela Command ou Terminal para executar todos os comandos. Após a instalação ser concluída,
insira o comando git --version e você verá qual versão do Git usará.
[Link] 280/303
22/03/2025, 18:48 Programação Java para crianças
HTML
git config --global [Link] ”Yakov Fain"
git config --global [Link] "yakovfain@[Link]"
Se você quiser usar diferentes nomes de usuário e e-mails para diferentes projetos,
OBSERVAÇÃO
execute os comandos acima no diretório do projeto sem a opção --global .
Mais tarde, quando você abrir uma conta no GitHub, precisará usar o mesmo e-mail que usou com o comando
config acima. O Git está pronto para gerenciar seus projetos. Agora, vamos criar um repositório Git para um
projeto simples e aprender como trabalhar com ele.
O comando git init criou um diretório oculto chamado .git , que é um repositório Git para meu projeto gitIntro .
Este diretório contém um banco de dados Git (também conhecido como index) que armazenará todas as
alterações que farei em minhas classes Java durante a vida deste projeto.
Você pode começar a usar o Git com seus projetos antigos quando quiser. Basta abrir o diretório de qualquer
projeto existente e executar o comando git init para criar um novo repositório local. Claro, ele não saberá sobre
suas modificações de código anteriores, mas a partir de agora você pode começar a rastreá-las.
Normalmente, meu trabalho com projetos controlados pelo Git consiste nas seguintes atividades:
[Link] 281/303
22/03/2025, 18:48 Programação Java para crianças
3. Altere o status de todos ou alguns dos arquivos modificados para rastreáveis executando o comando add .
4. Envie todos os arquivos modificados ou alguns selecionados para o repositório Git local.
6. Repita.
Observe que a primeira declaração indica que eu trabalho com o branch de código chamado master . Explicarei
como e por que você pode precisar criar branches de código separados um pouco mais tarde, mas por enquanto
não tenho outros branches. Os arquivos não rastreados são exibidos em vermelho, o que significa que eles são
novos no Git ou foram modificados após o último commit no repositório. As alterações feitas nos arquivos não
rastreados não são armazenadas no banco de dados do Git.
[Link] 282/303
22/03/2025, 18:48 Programação Java para crianças
Da mesma forma, você tem muitos arquivos nas pastas do seu projeto, mas pode querer adicionar apenas os
selecionados ao repositório git, por exemplo git add [Link] . Chamamos os arquivos modificados que devem
ser salvos no banco de dados Git trackable . Os arquivos modificados que serão ignorados pelo Git são
chamados untracked .
Se você quiser saber quais opções existem para qualquer comando do Git, basta
OBSERVAÇÃO digitar git --help seguido de um nome de comando, por exemplo, git --help add . Para
sair do modo de ajuda, basta digitar a letra q na janela Command.
Você também pode adicionar todos os arquivos novos ou modificados de uma só vez executando o comando git
add --all . Após executar esse comando, você obterá a seguinte saída:
[Link] 283/303
22/03/2025, 18:48 Programação Java para crianças
Agora todos os meus arquivos Java são exibidos em verde, o que significa que esses arquivos se tornaram
rastreáveis e estão prontos para serem confirmados no banco de dados Git.
OBSERVAÇÃO
Você não deve armazenar classes Java compiladas ou JARs nos repositórios de código-fonte. Você pode
informar ao Git quais arquivos ignorar criando um arquivo de texto chamado .gitignore no diretório do
seu projeto. Em seguida, abra-o com um editor de texto simples e adicione os tipos de arquivos que o Git
deve ignorar. Por exemplo, se você adicionar as duas linhas a seguir ao seu arquivo .gitigore , as classes
compiladas e os JARS não serão incluídos no seu banco de dados Git:
HTML
*.class
*.jar
HTML
git commit -m "initial commit of the classes Fish, Pet, and PetMaster".
[Link] 284/303
22/03/2025, 18:48 Programação Java para crianças
A opção -m permite escrever uma mensagem curta entre aspas duplas descrevendo o commit.
As "63 inserções" significam que um total de 63 linhas foram inseridas no banco de dados Git.
Se você executar o comando git commit sem nenhuma opção, o Git abrirá um editor de texto onde você deve
digitar uma descrição detalhada das alterações que estão sendo confirmadas. Salvar esse arquivo armazenará
essa descrição no banco de dados do Git.
Digite o comando git status novamente, e você verá a mensagem "nada para confirmar". Não é de se espantar,
acabei de confirmar três arquivos e ainda não os modifiquei novamente.
Agora, deixe-me fazer uma pequena alteração no arquivo [Link] . Atualmente, ele tem o seguinte
conteúdo:
JAVA
public class PetMaster {
String petReaction;
Pet myPet = new Pet();
[Link]();
[Link](petReaction);
[Link]();
}
}
Vou apenas modificar o comentário no topo deste arquivo. Vou mudar o texto para "Criado por Yakov em
28/03/15." Executar o comando git status novamente produzirá uma saída diferente:
[Link] 285/303
22/03/2025, 18:48 Programação Java para crianças
O Git notou que o arquivo [Link] foi alterado, mas até que eu emita o comando add para este arquivo
(ou todos os arquivos), o Git não rastreará as alterações em [Link] . Na configuração da loja de
brinquedos, é uma situação em que um brinquedo é exibido na prateleira, você notou, mas ainda não o adicionou
ao seu carrinho de compras. Os dois comandos a seguir salvarão minha última alteração no banco de dados do
Git:
HTML
git add [Link]
git commit -m "Modified the opening comment in [Link]"
Depois de confirmar todas as alterações, o git status nos informará novamente que não há nada para confirmar e
que o diretório de trabalho está limpo.
Para resumir, temos três classes Java localizadas no diretório de trabalho gitIntro , e o histórico de modificações
e commits é armazenado no diretório .git . Gostaria de lembrar que todo o trabalho que fizemos até agora foi
salvo apenas no repositório de código local.
Vou mostrar como desfazer o último commit e remover as alterações de código em [Link] . Quando
você estiver tentando repetir todos esses comandos, abra o arquivo [Link] e observe o texto do
comentário de abertura, porque ele vai mudar logo após o comando reset :
HTML
git reset HEAD
O comando reset desfará o último commit e abrirá um editor de texto contendo a descrição deste commit
revertido, que pode ter a seguinte aparência:
[Link] 286/303
22/03/2025, 18:48 Programação Java para crianças
HTML
Revert "modified the opening comment in [Link]"
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# modified: [Link]
#
Você pode alterar este texto para descrever melhor o que foi feito por este comando reset . O Git armazenará a
mensagem salva em seus arquivos de histórico. A sequência de dígitos e letras de 40 caracteres é um código
exclusivo associado a cada commit.
OBSERVAÇÃO Se você quiser ver o histórico de todos os commits, use o comando git log .
Até agora, trabalhamos com o branch padrão chamado master , e agora explicarei para que servem os branches.
Vamos ver como Mary pode criar um branch de código separado e adicionar um novo método surface à classe
Fish , que atualmente se parece com isto:
JAVA
public class Fish extends Pet {
int currentDepth=0;
currentDepth=currentDepth + howDeep;
[Link]("Diving for " +
howDeep + " feet");
[Link]("I'm at " + currentDepth +
" feet below sea level");
return currentDepth;
}
}
[Link] 287/303
22/03/2025, 18:48 Programação Java para crianças
Mary executará todos os comandos de ramificação no mesmo diretório gitIntro . Primeiro, ela criará sua própria
ramificação chamada mary :
HTML
git branch mary
A nova ramificação mary será criada no banco de dados Git, mas Mary permanecerá na ramificação master até
que ela mude para a nova ramificação executando o comando checkout :
HTML
git checkout mary
O comando git status é nosso amigo. Mary o usa frequentemente para garantir que ela esteja trabalhando no
branch apropriado:
Você também pode imprimir os nomes de todos os branches que existem no seu repositório Git executando o
comando git branch . O branch atual será mostrado em verde e marcado com um asterisco.
JAVA
public void surface(){
[Link]("Going up " + currentDepth + " feet.");
}
Usando a sequência usual de comandos status , add e commit Mary confirma as alterações no branch mary :
[Link] 288/303
22/03/2025, 18:48 Programação Java para crianças
A qualquer momento, o diretório de trabalho terá apenas uma cópia de cada arquivo com o conteúdo que
corresponde ao branch atual. Portanto, a classe Fish do branch mary tem o método surface . Agora Mary
volta para o branch master executando git checkout master e abre o arquivo [Link] - o método surface não
está lá! O Git moveu perfeitamente a versão mais antiga do [Link] de seu banco de dados de volta para o
diretório de trabalho. Aconteceu muito rápido, porque no VCS distribuído o repositório de código completo está
localizado no computador do programador e não há necessidade de fazer nenhuma comunicação pela rede.
Mary testou a nova versão da classe Fish e está pronta para incluí-la no branch master . Usando a terminologia
VCS, ela quer mesclar o código localizado no branch mary no código no branch master . Do branch master ,
Mary executa o seguinte comando merge :
HTML
git merge mary
[Link] 289/303
22/03/2025, 18:48 Programação Java para crianças
Neste caso, o Git conseguiu mesclar automaticamente duas versões do arquivo [Link] . Mas às vezes as
alterações entram em conflito umas com as outras e é necessária uma edição manual para resolver os conflitos.
Vou ilustrar isso criando mudanças conflitantes de propósito. Primeiro, vou adicionar três pontos de exclamação
no método surface no branch master :
JAVA
[Link]("Diving for " + howDeep + " feet!!!");
Vou submeter as alterações para o branch master , depois mudar para o branch mary e adicionar os pontos de
interrogação lá no mesmo lugar onde as exclamações foram colocadas em master . Então no branch mary essa
linha ficará assim:
JAVA
[Link]("Diving for " + howDeep + " feet???");
Agora, vou voltar para o branch master e tentar fazer uma mesclagem. Claramente, o Git não pode assumir a
responsabilidade de escolher uma versão em vez da outra. Temos um conflito:
Se você abrir o arquivo [Link] , encontrará algum código duplicado marcado com tags especiais:
JAVA
public void surface(){
[Link]("Going up " +
<<<<<<< HEAD
currentDepth + " feet!!!");
=======
currentDepth + " feet???");
>>>>>>> mary
}
[Link] 290/303
22/03/2025, 18:48 Programação Java para crianças
A seção de código conflitante marcada como HEAD corresponde à versão no branch master , e a outra é de mary
. Agora você precisa editar manualmente o arquivo [Link] para manter a versão da linha de código conflitante
que você gosta. Confirme as alterações no branch master e o conflito será resolvido.
Você pode encontrar explicações mais detalhadas de todos os recursos do Git no livro
OBSERVAÇÃO
gratuito intitulado Pro Git ([Link] publicado pela Apress.
O GitHub ([Link] é um serviço de hospedagem de repositório Git baseado na Web, onde você pode
criar um repositório de código compartilhado gratuitamente, desde que não se importe em manter seu código
aberto ao público. Pessoas ou organizações que desejam criar repositórios privados no GitHub podem comprar
uma conta paga. Mas não temos nada a esconder. Além disso, os programadores que têm seu código publicado
no GitHub são tratados com respeito adicional.
Após criar uma conta gratuita, você verá um botão verde intitulado "+ Novo repositório". Clique nele e insira o
nome e a descrição do seu projeto. Como nosso objetivo é publicar os arquivos do diretório local gitIntro , usarei
o mesmo nome para meu repositório GitHub. A captura de tela a seguir mostra como inseri o nome do
repositório e sua descrição:
[Link] 291/303
22/03/2025, 18:48 Programação Java para crianças
Pressione o botão intitulado "Criar Repositório" e um repositório vazio estará pronto. O GitHub mostrará a
seguinte página com instruções curtas sobre como fazer upload do seu código lá.
[Link] 292/303
22/03/2025, 18:48 Programação Java para crianças
Observe a URL HTTPS deste repositório no topo. Ela é usada para clonagem, que é descrita mais adiante.
HTML
git remote add origin [Link] (1)
git push -u origin master (2)
1. Quando um repositório remoto é criado, ele recebe um nome, que por padrão é origin . Então o primeiro
comando adiciona uma URL da origin recém-criada à configuração do seu projeto Git. O nome origin serve
como um nome de alias para essa longa URL do GitHub.
2. O comando push do Git carrega o código local para o repositório remoto. Então você confirma as alterações
para um repositório Git local e as envia para o remoto. Consequentemente, o segundo comando carregou
meu repositório gerenciado pelo Git para o GitHub. A opção -u significa upstream. Você a usará com o
primeiro push para vincular seu repositório local ao remoto. Os comandos push subsequentes serão emitidos
sem a opção -u .
[Link] 293/303
22/03/2025, 18:48 Programação Java para crianças
Após executar esses comandos, o código e o banco de dados Git do meu diretório local gitIntro são publicados
no GitHub. Agora, se você ou qualquer outra pessoa visitar a URL [Link]
([Link] , eles verão uma página da Web semelhante a esta:
[Link] 294/303
22/03/2025, 18:48 Programação Java para crianças
Se você trabalhar sozinho no projeto, não usará tanto o comando pull , porque ninguém mais está enviando as
alterações de código para lá. Você estará executando repetidamente a seguinte sequência de comandos git:
Mas assim que outra pessoa entrar no projeto, você precisará executar o comando pull periodicamente para
garantir que você tenha a versão mais recente do código que inclui todas as alterações feitas por outros membros
da equipe, que são chamados de colaboradores , por exemplo, nossos amigos Mary e Joe são colaboradores.
Para adicionar um colaborador ao seu projeto do GitHub, você precisa visitar seu repositório de projeto
compartilhado no GitHub (por exemplo, [Link] ), clicar no ícone Setting à direita e
usar o link Collaborators na próxima página da Web. Claro, esse novo colaborador deve estar registrado no
GitHub e ter um ID. Esse processo é descrito passo a passo na documentação do GitHub
([Link] .
14.5.4. Clonagem
[Link] 295/303
22/03/2025, 18:48 Programação Java para crianças
Digamos que Peter se junte ao projeto existente e Joe e Mary querem que ele instale o código mais recente. Peter
também usará Git e GitHub, então ele precisa instalar o Git em seu computador, mas Peter não precisa criar uma
nova pasta e executar o comando git init lá. O Git tem um comando clone que pode pegar o código existente de
um repositório compartilhado e criar sua cópia no computador de Peter. O comando clone baixa o código do
projeto mais recente, incluindo todo o banco de dados Git com todo o histórico de alterações feitas por Joe e
Mary no passado. Você pode fazer a clonagem clicando no botão "Clonar na área de trabalho" no GitHub ou
executando git clone na janela de comando.
Enquanto escrevia este livro, armazenei todos os seus exemplos de código no GitHub em
[Link] ([Link] . Você pode clonar meu
repositório Git do GitHub e começar a usar, melhorar ou adicionar novos exemplos de código. Basta visitar a
página da Web acima e copiar a URL da caixa HTTPS clone URL no lado direito:
Você pode ver apenas uma parte desta URL, mas quando você copiá-la para a área de transferência, ela ficará
assim:
HTML
[Link]
Agora abra a janela de comando (ou terminal) e execute o comando clone usando a URL acima como parâmetro:
[Link] 296/303
22/03/2025, 18:48 Programação Java para crianças
HTML
git clone [Link]
Em alguns segundos você encontrará no seu computador o diretório Java4Kids_code com todos os exemplos de
código e a pasta .git dentro. Foi assim que eu fiz no meu computador Mac:
Na verdade, você pode clonar qualquer repositório de código aberto do GitHub no seu computador e trabalhar
com o código sem nem mesmo notificar o autor do código. Mas criar um clone não significa que você pode
enviar suas alterações de código de volta para o repositório do GitHub do autor sem sua aprovação. O GitHub
tem procedimentos especiais para isso, chamados Forking e Pull Requests.
Digamos que você queira ser um colaborador dos meus exemplos de código para este livro. Em vez da clonagem
explicada na seção anterior, basta ir para a página do GitHub do meu projeto e clicar no botão Fork no topo da
página:
[Link] 297/303
22/03/2025, 18:48 Programação Java para crianças
Isso criará um novo repositório na sua conta do GitHub e copiará meu código para lá. Então você pode clonar
este projeto do seu repositório e trabalhar com ele. Quando você tiver melhorado meu código ou corrigido um
bug, envie-o para seu projeto bifurcado. Então visite minha página do GitHub e pressione o botão Pull Request
lá:
Você poderá criar um pull request e descrever a alteração de código que você já implementou e confirmou no
repositório bifurcado. Na verdade, eu tenho um pull request no momento em que escrevo isso. Vamos clicar
neste pequeno círculo com o dígito 1 e ver o que está lá:
[Link] 298/303
22/03/2025, 18:48 Programação Java para crianças
[Link] 299/303
22/03/2025, 18:48 Programação Java para crianças
Nem todo pull request pode ser mesclado automaticamente, especialmente se várias alterações de código foram
feitas. Nesse caso, você precisaria fazer um merge manual diretamente no GitHub. Eu sempre deixo um
comentário de agradecimento para as pessoas que ajudaram a melhorar meu código.
[Link] 300/303
22/03/2025, 18:48 Programação Java para crianças
O IDEA pedirá que você faça login no GitHub. Use o e-mail e a senha que você usou ao criar sua conta no
GitHub. Então o IDEA pedirá seu próprio banco de dados de senhas - deixe em branco. Agora o IDEA está
pronto para clonar qualquer repositório público, desde que você saiba a URL do clone, que é
[Link] no nosso caso. Você deve digitar essa URL na próxima janela que
pode ser semelhante a esta:
O campo com o nome do diretório do projeto será preenchido automaticamente, mas você pode alterá-lo se
quiser. Pressione o botão Clone e o IDEA clonará todos os projetos no diretório especificado e perguntará se
você deseja abrir um projeto. Selecionar Yes abrirá um dos projetos do IDEA (por exemplo, Chapter7). Você
também verá um aviso sobre raiz VCS não registrada, que você pode ignorar, pois não estará enviando
diretamente nenhuma alteração de código para meu repositório GitHub.
Se você abrir o diretório do projeto com o File Manager (ou Finder), verá que há outras pastas que contêm
amostras de código para todos os capítulos. Você pode abrir qualquer um desses projetos no IDEA selecionando
o menu File | Open. Observe que esse diretório do projeto tem uma pasta chamada .git , que contém o banco de
dados Git com o histórico de todos os commits que fiz enquanto escrevia amostras de código para este livro.
[Link] 301/303
22/03/2025, 18:48 Programação Java para crianças
Se você observar algum erro de compilação, abra o menu Arquivo | Estrutura do Projeto e certifique-se de que o
nível de linguagem do projeto esteja definido como "8 - Lambdas, anotações de tipo etc."
O IntelliJ IDEA oferece suporte total ao Git, então você pode executar todos os comandos do Git sem precisar
usar a janela Command. Você pode encontrar a descrição do suporte ao Git na documentação do IDEA
([Link] .
[Link] 302/303
22/03/2025, 18:48 Programação Java para crianças
Epílogo
Este livro acabou. Espero que você tenha gostado de lê-lo tanto quanto eu gostei de escrevê-lo. Seu processo de
estudo de Java está longe de terminar. Se você gostou deste livro e quer continuar sua jornada, considere ler meu
outro livro de Java para adultos, chamado "Java 24-Hour Trainer", 2ª edição, Wiley. Esse livro vem com vídeos
que ilustram os materiais abordados em cada capítulo. Eu também explico a programação do lado do servidor
em Java lá. Talvez um dia eu escreva um livro de Java mais avançado para crianças também. Obrigado por ler
meu livro e boa sorte!
[Link] 303/303