Comentários
O JavaFX é uma biblioteca muito boa que a linguagem Java conta para a construção de aplicações gráficas.
Fonte: Shutterstock.
Deseja ouvir este material?
Áudio disponível no material digital.
Caro estudante, bem-vindo à terceira seção da terceira unidade dos estudos sobre Linguagem Orientada a Objetos. Qual desenvolvedor nunca quis construir interfaces gráficas para suas aplicações? A maioria dos desenvolvedores de hoje em dia já desejou isso. Às vezes, construir uma aplicação que é executada apenas no terminal não basta diante do que se pretende fazer. Os jogos são bons exemplos disso, pois é muito complicado e pouco atrativo jogar jogos via linha de comando. A linguagem Java conta com uma biblioteca muito boa para a construção de aplicações gráficas, o JavaFX, e nesta seção você terá a oportunidade de aprender a construir aplicações com essa biblioteca.
Como forma de contextualizar a sua aprendizagem, lembre-se de que você está desenvolvendo um simulador completo de um robô. O seu gestor revisou mais uma vez o seu código e lhe passou mais uma lista de tarefas que deve ser desenvolvida. Ele percebeu que, no seu código, não existe nenhuma interface gráfica que mostre o seu robô andando pela sala, logo, pediu a você que desenvolva a GUI para o robô por meio da biblioteca JavaFX.
Diante desse desafio que lhe foi dado, como você criará essa interface gráfica? O que é GUI? O que é a biblioteca JavaFX? Como criar uma aplicação com JavaFX? Esta seção irá guiá-lo até as respostas para essas questões levantadas.
Muito bem, agora que você foi apresentado à sua nova situação-problema, estude o conteúdo desta seção e compreenda como construir aplicações gráficas com JavaFX. Ao aprender o conteúdo, um novo leque de oportunidades em termos de construção de aplicações de pequeno e grande porte se abrirá para você. E aí, vamos juntos compreender como utilizar essa biblioteca e, então, resolver esse desafio?
Bom estudo!
A linguagem Java possui um suporte muito bom para a criação de Interfaces Gráficas de Usuário ou, em inglês, Graphical User Interface (GUI), e existem várias formas de se fazer a criação de interfaces gráficas em Java. Ao longo da evolução dessa linguagem, diversas bibliotecas gráficas foram criadas, como: Abstract Window Toolkit (AWT), Swing, Standard Widget Toolkit (SWT), Apache Pivot, SwingX, JGoodies, QtJambi e JavaFX. Este livro irá lhe mostrar como criar aplicações gráficas utilizando o JavaFX; a partir da versão do Java 8, a API do JavaFX é distribuída nativamente, ou seja, basta se ter a versão 8 ou superior que o JavaFX funcionará naturalmente, sem a necessidade de qualquer instalação.
Muitos alunos gostam de aprender mais de uma tecnologia/API, e existem muitos materiais na internet, como vídeos e tutoriais, a respeito das APIs Swing e AWT, que são boas bibliotecas, mas que serão descontinuadas na versão do Java 9. Diante disso, o mais aconselhável é estudar tecnologias mais novas, como o JavaFX.
Antes de iniciarmos a codificação de aplicações com interfaces gráficas, é importante que você compreenda a lógica de como organizar uma tela utilizando JavaFX. Dessa maneira, observe a Figura 3.8, em que temos, inicialmente, uma janela (classe Stage). Essa janela é a parte mais externa da interface gráfica, em que ficam os botões de maximizar, minimizar, fechar e o título da janela. Dentro dessa janela, temos uma cena (classe Scene) em que são definidas as dimensões da tela e colocamos os componentes que desejamos criar na interface gráfica. Por fim, no interior da cena, temos os nós (que herdam da classe Node), que nada mais são do que todos os componentes que desejamos colocar na tela. Dentro de alguns nós, podemos ter outros nós. Veremos mais sobre isso adiante.
Outro ponto muito importante é entender a organização hierárquica das classes que descendem a classe Node. A Figura 3.9 nos mostra uma pequena parte das classes que descendem de Node. Como exemplos de classe que herdam de Node, podemos destacar ImageView, Parent e Shape. A classe Shape possui diversas subclasses, como Rectangle, Circle, Ellipse, etc., e a classe Parent também possui diversas subclasses, como Group, Region e WebView. Neste momento, esperamos que você tenha apenas uma noção dessa organização; quando os exemplos do livro começarem a aparecer, não hesite em consultar esta figura novamente para compreender a aplicação.
Antes de começarmos a implementação, apresentaremos, brevemente, alguns dos componentes que estão disponíveis no JavaFX. O Quadro 3.12 apresenta uma síntese de alguns componentes que estão no pacote javafx.scene.control.
Nome do Componente |
Classe do Componente |
Descrição do Componente | Aspecto Visual do Componente |
---|---|---|---|
Botão | Button | Simples botão de controle. | ![]() |
Rótulo | Label | Campo que permite exibir um texto não editável. | ![]() |
Campo de Texto | TextField | Campo que permite a inserção de texto em uma única linha. | ![]() |
Área de Texto | TextArea | Campo que permite a inserção de texto com múltiplas linhas. | ![]() |
Botão de Opção | RadioButton | Seleção de opções mutuamente excludentes. | ![]() |
Caixa de Seleção | CheckBox | Seleção de opções não mutuamente excludentes. | ![]() |
Caixa de Combinação | ComboBox | Seleção de opções mutuamente excludentes em forma de lista. | ![]() |
A seguir, encontraremos exemplos dos quatro primeiros componentes, que são: botão (Button), rótulo (Label), campo de texto (TextField) e área de texto (TextArea). Veremos, então, que a utilização desses componentes é bem simples. Os componentes botão de opção (RadioButton), caixa de seleção (CheckBox) e caixa de combinação (ComboBox) não serão mostrados neste livro, porém são bem simples e você pode encontrar exemplos de como utilizá-los na internet.
A fim de construirmos uma tela gráfica, precisamos definir onde ficará cada um dos componentes na tela. Assim, será necessário especificar as coordenadas (x, y) de todos os componentes colocados na tela. No entanto, isso costuma dar muito trabalho, logo, é uma boa estratégia utilizar algum gerenciador de layout, que organiza de forma automática os componentes na tela conforme alguma estratégia. A biblioteca JavaFX possui diversas classes que realizam o gerenciamento de layout, mas neste livro, utilizaremos:
Vamos, agora, criar o nosso primeiro código que faz uso de interfaces gráficas (GUI).
Alguns IDEs, como o Netbeans, geram automaticamente a aplicação base (hello world). Dessa forma, se você estiver no Netbeans, execute os passos descritos na Figura 3.10. Após executá-los, o Código 3.23 será gerado (foram feitas poucas modificações nos nomes das variáveis).
Caso você esteja trabalhando em outro IDE, veja se ele dá suporte à criação de aplicação de exemplo em JavaFX. Se o seu IDE não tem essa opção disponível, tudo bem! Basta digitar o código abaixo.
Lembre-se de que a única restrição é utilizar o Java 8 (JDK 1.8) ou superior.
Nota: se você estiver utilizando a versão do OpenJDK, é possível que tenha alguns problemas e que seja preciso configurar manualmente o JavaFX.
Analise o Código 3.23 que foi gerado a partir dos passos da Figura 3.10.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class AppHelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage janela) {
Button btn = new Button();
btn.setText("Imprime 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane gerenciadorLayout = new StackPane();
gerenciadorLayout.getChildren().add(btn);
Scene cena = new Scene(gerenciadorLayout, 300, 100);
janela.setTitle("Aplicação Hello World!");
janela.setScene(cena);
janela.show();
}
}
No Código 3.23, nas linhas de 1 a 7, temos um conjunto de importações de classes da biblioteca do JavaFX. Essas importações carregam as classes que permitem a criação da aplicação gráfica, abstraindo, assim, os detalhes de implementação de diversos componentes, como o botão (Button), o gerenciador de layout (StackPane), a cena (Scene), entre outros. Em seguida, na linha 8, temos a criação da classe AppHelloWorld, que herda da classe Application. Já nas linhas 9 a 11, temos o método main, que é responsável por lançar a aplicação por meio da invocação do método launch, que é um método estático disponível na classe Application. Ao herdar da classe Application, você deve, obrigatoriamente, implementar o método abstrato start (nas linhas 12 a 28), que é chamado automaticamente pelo JavaFX, além disso, é o local onde definimos os elementos presentes na interface gráfica e invocamos a nossa lógica de negócio. Nas linhas 14 e 15, criamos um botão e, então, definimos um texto para ele. Já nas linhas 16 a 21, criamos um evento que executará uma ação toda vez que clicarmos no botão. A ação executada, neste caso, será imprimir a mensagem “Hello World!”. Na linha 22, por sua vez, foi criado um objeto do tipo StackPane, que nada mais é do que um gerenciador de layout. Já na linha 23, o botão foi adicionado ao gerenciador de layout, e na linha 24, uma cena com o gerenciador de layout utilizado foi criada e as dimensões da janela foram especificadas. Nas linhas 25 e 26, foi definido um título para a janela da aplicação e, então, a cena foi colocada dentro da janela. Por fim, na linha 27, pedimos para que a janela gráfica seja mostrada no monitor.
Diante disso, reveja a Figura 3.8 e tente compreender como ocorreu a lógica de adicionarmos um componente sobre o outro. Por exemplo: a cena foi adicionada sobre a janela, o gerenciador de layout foi adicionado na cena e, por fim, o botão foi adicionado sobre o gerenciador de layout.
Após analisar o Código 3.23, mande executá-lo. Clique no botão “Imprime ‘Hello World’” e veja a saída impressa no terminal. Ao executar a aplicação, uma tela semelhante à mostrada na Figura 3.11 deverá aparecer. Em seguida, faça alguns testes redimensionando as dimensões da janela e, por fim, clique nos botões maximizar, minimizar e fechar; perceba que essas funcionalidades testadas são propriedades inerentes à janela criada com o JavaFX, mesmo você não tendo implementado o código para realizar isso.
Pronto, você criou o seu primeiro código que utiliza interfaces gráficas em Java.
Neste próximo exemplo, vamos adaptar um pouco esse código de hello world para transformá-lo em uma aplicação que calcula o Fibonacci de um número lido da tela e exibe o resultado. Dessa maneira, analise o Código 3.24 mostrado a seguir.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class AppFibonacci extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage janela) {
Label lbl = new Label("Calcula Fibonacci");
lbl.setTextFill(Color.DARKGREEN);
lbl.setFont(Font.font("Serif", 25));
TextField numField = new TextField();
ImageView imgBtn = new ImageView(new Image(getClass()
.getResourceAsStream("recursos/icones/mission.png")));
Button btn = new Button("Calcular", imgBtn);
TextArea textArea = new TextArea();
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
try {
int num=Integer.parseInt(numField.getText());
if (num >= 1 && num <= 42) {
String resultado = String.format(
"Fibonacci(%d) = %d\n",
num, fibonacci(num));
textArea.appendText(resultado);
} else if (num < 1) {
String msg = String.format(
"O número deve ser >= 1\n");
textArea.appendText(msg);
} else if (num > 42) {
String msg = String.format(
"Número muito grande\n");
textArea.appendText(msg);
}
} catch (Exception ex) {
String msg = String.format(
"Digite um número inteiro\n");
textArea.appendText(msg);
}
}
});
VBox vbox = new VBox(lbl, numField, btn, textArea);
vbox.setPadding(new Insets(10, 10, 10, 10));
vbox.setSpacing(10);
vbox.setAlignment(Pos.TOP_CENTER);
vbox.setStyle("-fx-background-color: #BBDDFF;");
Scene cena = new Scene(vbox, 400, 300);
janela.setTitle("Aplicação Calcula Fibonacci");
janela.setScene(cena);
janela.show();
}
public long fibonacci(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
}
No Código 3.24, nas linhas 1 a 14, temos as importações das classes do JavaFX que permitem a utilização dos componentes gráficos; já nas linhas 16 a 18, temos o método main; na linha 21, temos a declaração de um rótulo (label) que irá aparecer no topo da janela; nas linhas 22 e 23, definimos a cor desse rótulo e a fonte utilizada seguida do tamanho da fonte; na linha 24, criamos um campo de texto que irá receber o número digitado para calcularmos o Fibonacci; nas linhas 25 e 26, carregamos uma imagem de um ícone para deixar a aplicação com aspecto mais agradável (repare que, para o carregamento da imagem, foi preciso passar o caminho relativo do local em que ela se encontra, assim, nesse exemplo, a imagem está na pasta “recursos” e na subpasta “icones”); na linha 27, criamos um botão com um ícone carregado; na linha 28, criamos uma área de texto em que será exibido o resultado do cálculo; já nas linhas 29 a 54, definimos um evento que será disparado caso o usuário clique no botão. A lógica desse trecho é basicamente pegar o número digitado no campo de texto, convertê-lo em um número inteiro, calcular o Fibonacci e exibir o resultado na área de texto. Repare que foi criado um tratamento de exceção caso um número não inteiro seja digitado pelo usuário, bem como só será calculado o Fibonacci para números maiores ou iguais a um (abaixo desse valor, a operação não será definida) e menor ou igual a 42 (acima desse valor, ocorrerá overflow). Na linha 55, foi criado um gerenciador de layout que organiza os componentes na vertical; nas linhas 56 e 57, por sua vez, foi dado um espaçamento entre as bordas e os componentes; nas linhas 58 e 59, foram definidos o tipo de alinhamento e a cor de fundo; nas linhas 60 a 63, foi criada a cena e adicionada na janela; por fim, nas linhas 65 a 71, temos o método que calcula o Fibonacci de um número inteiro.
Implemente o Código 3.24 e mande executá-lo. Faça a inserção de diversos valores no campo de texto, clique no botão calcular e analise o resultado. Sugerimos que faça diversas modificações nos parâmetros dos métodos acima, como setTextFill, setFont, setPadding, setSpacing, setAlignment e setStyle, bem como execute a aplicação para compreender, de fato, como esses parâmetros influenciam no aspecto gráfico.
No Código 3.24 acima, foi utilizado um ícone para deixar a interface mais intuitiva e agradável. Atualmente, existem diversos sites na internet que disponibilizam ícones de forma gratuita. Alguns bons sites para baixar ícones são: Flaticon, Iconfinder e Icon-icons.
Imagine, agora, que queremos construir uma aplicação que desenhe figuras geométricas 2D. Dessa maneira, o nosso próximo exemplo nos mostrará como desenhar retângulos, círculos, elipses, linhas, polígonos e polilinhas a partir do JavaFX. Para isso, as seguintes classes serão utilizadas: Rectangle, Circle, Ellipse, Line, Polygon e Polyline.
Analise o Código 3.25, que apresenta o trecho do método start, que é responsável por criar as figuras geométricas mencionadas. Alguns trechos do código foram omitidos por serem similares ao código 3.24, como a importação das bibliotecas, a criação da classe que herda Application e a criação do método main.
public void start(Stage janela) {
Rectangle retangulo = new Rectangle(100, 100);
retangulo.setTranslateX(10);
retangulo.setTranslateY(10);
retangulo.setFill(Color.RED);
Circle circulo = new Circle(50);
circulo.setTranslateX(170);
circulo.setTranslateY(60);
circulo.setFill(Color.GREEN);
Circle circunferencia = new Circle(50);
circunferencia.setTranslateX(280);
circunferencia.setTranslateY(60);
circunferencia.setStroke(Color.BLUE);
circunferencia.setStrokeWidth(3.0);
circunferencia.setFill(Color.WHITE);
Ellipse elipse = new Ellipse(50, 25);
elipse.setTranslateX(390);
elipse.setTranslateY(60);
elipse.setFill(Color.YELLOW);
Line linha = new Line(10.0f, 10.0f, 100.0f, 100.0f);
linha.setTranslateX(450);
linha.setTranslateY(10);
linha.setStroke(Color.GREENYELLOW);
linha.setStrokeWidth(3.0);
Polygon poligono = new Polygon();
poligono.getPoints().addAll(new Double[]{
0.0, 00.0,
100.0, 0.0,
50.0, 100.0
});
poligono.setTranslateX(550);
poligono.setTranslateY(10);
poligono.setFill(Color.SKYBLUE);
Polyline polilinha = new Polyline();
polilinha.getPoints().addAll(new Double[]{
0.0, 0.0,
100.0, 0.0,
0.0, 100.0,
100.0, 100.0
});
polilinha.setTranslateX(670);
polilinha.setTranslateY(10);
polilinha.setStroke(Color.BLACK);
polilinha.setStrokeWidth(3.0);
Group grupo = new Group();
grupo.getChildren().addAll(retangulo, circulo,
circunferencia, elipse, linha, poligono, polilinha);
Scene cena = new Scene(grupo, 800, 120);
janela.setTitle("Aplicação Figuras Geométricas 2D");
janela.setScene(cena);
janela.show();
}
No Código 3.25, na linha 2, criamos o retângulo que especifica a largura e a altura do objeto (a unidade de medida desses atributos é pixels); em seguida, nas linhas 3 a 5, definimos a localização na coordenada (x, y) e a cor do retângulo; já na linha 6, criamos um círculo passando o raio; já as linhas 7 a 9 são semelhantes ao retângulo e não serão comentadas; na linha 10, criamos um objeto chamado circunferência, e a novidade em relação ao círculo está nas linhas 13 e 14, em que definimos a cor da borda e a grossura da linha; na linha 16, criamos uma elipse e passamos o raio nos eixos x e y; na linha 20, criamos um objeto do tipo linha, em que são passadas as coordenadas (x, y) de início e (x, y) de fim; já nas linhas 25 a 30, criamos um polígono e adicionamos as coordenadas de seus vértices; nas linhas 34 a 40, criamos uma polilinha e adicionamos as coordenadas de seus vértices; por fim, nas linhas 45 a 47, criamos um nó do tipo grupo e adicionamos todas as figuras geométricas 2D.
Implemente o Código 3.25 e mande executá-lo. Sugerimos que você faça diversas modificações nos parâmetros dos métodos, como cor, localização (x, y), dimensões das figuras, entre outras, bem como execute a aplicação para compreender, de fato, como esses parâmetros influenciam no aspecto gráfico.
A Figura 3.13 nos mostra a interface gráfica gerada pelo código 3.25.
As telas gráficas construídas com JavaFX utilizam um sistema de coordenadas semelhantes às coordenadas cartesianas para inserção dos objetos/nós no cenário. O cenário da Figura 3.13 possui 800 × 120 pixels, e faz-se importante ter em mente que a coordenada (0, 0) está na parte superior esquerda. O eixo x cresce no sentido da esquerda para direita, já o eixo y cresce no sentido de cima para baixo (inverso do sistema cartesiano tradicional). O sistema de coordenadas utilizado pelo JavaFX é igual ao utilizado pela ferramenta Greenfoot, dessa maneira, analise a Figura 1.22, presente na Unidade 1, para compreender melhor esses dados.
Imagine, agora, que queremos construir uma aplicação que carregue imagens da internet e as exiba na tela. A biblioteca JavaFX nos ajudará a fazer isso de forma fácil. Para tanto, analise o Código 3.26 que apresenta os principais trechos da aplicação responsáveis por isso. Alguns trechos do código foram omitidos por serem similares ao código 3.24, como a importação das bibliotecas, a criação da classe que herda Application e a criação do método main.
private final String IMG_URL1 = "https://bit.ly/2Pxqady";
private final String IMG_URL2 = "https://bit.ly/2EZlriY";
private final String IMG_URL3 = "https://bit.ly/3fylvmj";
private final String IMG_URL4 = "https://bit.ly/3iaOOgk";
@Override
public void start(Stage janela) {
Text texto = new Text("Aplicação Exibe Imagens");
texto.setTranslateX(50);
texto.setTranslateY(20);
Image img1 = new Image(IMG_URL1);
ImageView view1 = new ImageView(img1);
view1.setTranslateX(100);
view1.setTranslateY(30);
Image img2 = new Image(IMG_URL2);
ImageView view2 = new ImageView(img2);
view2.setTranslateX(100);
view2.setTranslateY(90);
Image img3 = new Image(IMG_URL3);
ImageView view3 = new ImageView(img3);
view3.setTranslateX(100);
view3.setTranslateY(160);
Image img4 = new Image(IMG_URL4);
ImageView view4 = new ImageView(img4);
view4.setTranslateX(100);
view4.setTranslateY(220);
Group grupo = new Group();
grupo.getChildren().addAll(texto, view1, view2, view3, view4);
Scene cena = new Scene(grupo, 260, 300);
janela.setTitle("Aplicação Manipula Imagens");
janela.setScene(cena);
janela.show();
}
No Código 3.26, nas linhas 1 a 4, temos as URLs (Uniform Resource Locator) das imagens; já na linha 7, criamos um objeto de texto para ser colocado no topo da tela (semelhante a um label); na linha 10, criamos uma imagem a partir da URL; na linha 11, criamos um objeto do tipo ImageView, que é a imagem visualizável na tela, pois ImageView é um tipo de nó (herda da classe Node); por fim, as demais linhas do código são semelhantes às linhas anteriores já comentadas.
No Código 3.26, as URLs foram encurtadas para ficarem mais limpas no material, mas essa não é uma boa prática, pois cria uma camada a mais e desnecessária de processamento. Nesse tipo de aplicação, o ideal é que se tenha as imagens armazenadas localmente no computador, pois, assim, evita-se o tempo de carregamento da imagem no site, além de permitir que sua aplicação seja executada mesmo sem acesso à internet.
Implemente o Código 3.26 e o execute. A Figura 3.14 nos apresenta a interface gráfica gerada por esse código.
A biblioteca JavaFX dá um bom suporte também à criação de gráficos. Vamos criar, agora, uma aplicação que plota dois gráficos na tela. O primeiro gráfico plotado é um gráfico de barras, já o segundo é um gráfico de pizza. Analise o Código 3.27 que nos apresenta um trecho da aplicação que exibe os gráficos mencionados.
public void start(Stage janela) {
int dimx = 1000;
int dimy = 440;
BarChart bar = new BarChart<>(new CategoryAxis(), new NumberAxis());
bar.setTitle("Relação de Vendas de Carros Por Ano");
XYChart.Series carro1 = new XYChart.Series();
carro1.setName("Chevrolet Onix");
carro1.getData().add(new XYChart.Data("2017", 188654));
carro1.getData().add(new XYChart.Data("2018", 210466));
carro1.getData().add(new XYChart.Data("2019", 241214));
carro1.getData().add(new XYChart.Data("2020", 17463));
XYChart.Series carro2 = new XYChart.Series();
carro2.setName("Hyundai HB20");
carro2.getData().add(new XYChart.Data("2017", 105539));
carro2.getData().add(new XYChart.Data("2018", 105518));
carro2.getData().add(new XYChart.Data("2019", 101590));
carro2.getData().add(new XYChart.Data("2020", 6555));
XYChart.Series carro3 = new XYChart.Series();
carro3.setName("Ford Ka");
carro3.getData().add(new XYChart.Data("2017", 94893));
carro3.getData().add(new XYChart.Data("2018", 104450));
carro3.getData().add(new XYChart.Data("2019", 104331));
carro3.getData().add(new XYChart.Data("2020", 7334));
bar.getData().addAll(carro1, carro2, carro3);
bar.setPrefSize(dimx/2 - 20, dimy - 20);
PieChart graficoPizza = new PieChart();
graficoPizza.setTitle("Relação Consumo Energia por Dia");
graficoPizza.getData().addAll(
new PieChart.Data("Domingo", 18),
new PieChart.Data("Segunda", 38),
new PieChart.Data("Terça", 34),
new PieChart.Data("Quarta", 35),
new PieChart.Data("Quinta", 31),
new PieChart.Data("Sexta", 36),
new PieChart.Data("Sábado", 27));
graficoPizza.setPrefSize(dimx/2 - 20, dimy - 20);
HBox hbox = new HBox(bar, graficoPizza);
Scene cena = new Scene(hbox, dimx, dimy);
janela.setTitle("Aplicação Exibe Gráficos");
janela.setScene(cena);
janela.show();
}
Nas linhas 2 e 3, do Código 3.27, estão as dimensões x e y da janela; nas linhas 4 e 5, criamos um objeto que armazenará os dados do gráfico de barras e definimos um título para ele; nas linhas 6 e 7, criamos um objeto que armazenará as séries de dados e definimos o seu nome (neste caso, dados do carro Chevrolet Onix); já nas linhas 8 a 11, foram adicionados os dados desse carro, sendo que o primeiro valor é o eixo x e o segundo é o eixo y; nas linhas 13 a 23, mais dois tipos de objetos com os dados dos carros foram criados; na linha 24, foi adicionado ao gráfico de barras os dados relativos aos carros criados; nas linhas 26 e 27, foi criado um gráfico de pizza e seu título foi definido; nas linhas 28 a 35, os dados foram adicionados ao gráfico de pizza; por fim, na linha 37, um gerenciador de layout que organiza os nós na horizontal foi criado.
Implemente o Código 3.27 e o execute; após isso, uma tela semelhante à Figura 3.15 deverá ser mostrada. Leitor, faça alterações nos parâmetros dos métodos, execute a aplicação e analise as mudanças ocorridas. Esse tipo de teste o ajudará a compreender a influência de cada um dos parâmetros na aplicação.
Vamos considerar, agora, que queremos construir uma aplicação em que controlamos um robô em um cenário livre de obstáculos. Esse robô poderá se mover para cima, para baixo, para a esquerda e para a direita; o controle dele será feito por meio das setas do teclado do computador; ele poderá se movimentar em duas velocidades diferentes; e esse recurso será acionado ao pressionarmos a tecla espaço. Nessa aplicação, também desejamos que o robô fique restrito às dimensões da janela, ou seja, ele não pode sair da janela gráfica. Dessa maneira, analise o Código 3.28 mostrado abaixo.
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.stage.Stage;
public class AppMovRobo extends Application {
private final int DIM_X = 300;
private final int DIM_Y = 220;
private final int altura = 60;
private final int largura = 64;
private int posX = DIM_X/2 - largura/2;
private int posY = DIM_Y/2 - altura/2;
private int velocidade = 1;
private final Image imgRoboFrente = new Image(getClass()
.getResourceAsStream("recursos/robo1.png"));
private final Image imgRoboCostas = new Image(getClass()
.getResourceAsStream("recursos/robo2.png"));
private final Image imgRoboEsq = new Image(getClass()
.getResourceAsStream("recursos/robo3.png"));
private final Image imgRoboDir = new Image(getClass()
.getResourceAsStream("recursos/robo4.png"));
private final ImageView imgRobo = new ImageView(imgRoboFrente);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage janela) {
imgRobo.setTranslateX(posX);
imgRobo.setTranslateY(posY);
Group grupo = new Group();
grupo.getChildren().addAll(imgRobo);
Scene cena = new Scene(grupo, DIM_X, DIM_Y);
janela.setTitle("Aplicação Movimentar Robô");
janela.setScene(cena);
janela.show();
cena.setOnKeyPressed((evt) -> {
if (evt.getCode() == KeyCode.UP) {
imgRobo.setImage(imgRoboCostas);
posY = posY - velocidade;
if (posY < 0) {
posY = 0;
}
imgRobo.setTranslateX(posX);
imgRobo.setTranslateY(posY);
}
if (evt.getCode() == KeyCode.DOWN) {
imgRobo.setImage(imgRoboFrente);
posY = posY + velocidade;
if (posY + altura > DIM_Y) {
posY = DIM_Y - altura;
}
imgRobo.setTranslateX(posX);
imgRobo.setTranslateY(posY);
}
if (evt.getCode() == KeyCode.LEFT) {
imgRobo.setImage(imgRoboEsq);
posX = posX - velocidade;
if (posX < 0) {
posX = 0;
}
imgRobo.setTranslateX(posX);
imgRobo.setTranslateY(posY);
}
if (evt.getCode() == KeyCode.RIGHT) {
imgRobo.setImage(imgRoboDir);
posX = posX + velocidade;
if (posX + largura > DIM_X) {
posX = DIM_X - largura;
}
imgRobo.setTranslateX(posX);
imgRobo.setTranslateY(posY);
}
if (evt.getCode() == KeyCode.SPACE) {
if (velocidade == 1) {
velocidade = 4;
} else {
velocidade = 1;
}
}
});
}
}
No Código 3.28, nas linhas 9 a 15, temos a declaração de diversos atributos que são intuitivos, logo, não serão explicados; já nas linhas 16 a 23, foram carregadas quatro imagens diferentes do robô, cada uma com uma determinada orientação. As imagens estão especificadas a partir do caminho relativo e estão disponíveis no GitHub do autor. Na linha 24, temos um objeto do tipo ImageView que é responsável por exibir o robô na tela. A lógica principal da aplicação está nas linhas 38 a 82, que definem os eventos disparados quando clicadas as setas do teclado e a tecla espaço. Nas linhas 39 a 47, temos o controle do robô caso pressionada a tecla seta para cima; por fim, o restante do código intuitivo é semelhante ao código comentado, portanto, não será explicado.
O Código 3.28 exemplifica como se criar uma aplicação com GUI em que seja possível interagir com o personagem por meio de comandos do teclado. Implemente o Código 3.28 e execute-o; após isso, uma tela semelhante à Figura 3.16 deverá ser mostrada. Utilize as setas do teclado para controlar o robô; aperte também a tecla espaço e perceba que o robô ficará mais rápido ou mais lento à medida que você pressioná-la. Aplicações como essas, que se assemelham a um jogo de computador, ficam mais ricas/divertidas quanto mais comandos forem inseridos. Caso desejar, utilize essa aplicação como base para realizar a implementação de um jogo de seu interesse.
Agora que você aprendeu a criar diversas aplicações com JavaFX, reflita sobre como os códigos 3.24, 25, 26, 27 e 28 seguem a estrutura mostrada na Figura 3.8. Tente desenhar uma imagem semelhante à Figura 3.8 para cada um dos códigos. Você irá notar que o que muda de uma figura para outra é a estrutura de nós; o restante da aplicação permanece fixa. Esperamos que essa reflexão e esse exercício o ajudem a criar aplicações com dezenas e até centenas de nós.
Gostaríamos de ressaltar que o foco desta seção é a criação de aplicações básicas e simples envolvendo interfaces gráficas, logo, a separação entre os componentes da interface e da lógica de negócio não foi feita. No entanto, é importante que o leitor aprenda a desenvolver códigos modularizados separando a lógica de negócio da interface gráfica, principalmente quando as aplicações crescem.
Caro estudante, nesta seção você estudou os conteúdos relacionados à criação de interfaces gráficas, criou botões, rótulos, campos de texto, áreas de texto, desenhou figuras, inseriu imagens, criou gráficos e tratou eventos de clique. Foram mostrados a você diversos exemplos desses conceitos em JavaFX, e todos os códigos aqui mostrados podem ser acessados no GitHub do autor.
Na próxima seção, vamos construir aplicações que utilizam vetores e matrizes, bem como realizar diversas manipulações envolvendo strings; dessa maneira, avançaremos ainda mais no entendimento da linguagem Java.
ARANTES, J. da S. Livro-POO-Java. 2020. Disponível em: https://bit.ly/3eiUMcF. Acesso em: 29 jul. 2020.
CAELUM. Java e orientação a objetos: apostila do curso FJ-11. [s.d.]. Disponível em: https://bit.ly/2ZpTqrZ. Acesso em: 28 ago. 2020.
CURSO EM VÍDEO. Curso de Java #05 - Introdução ao Swing e JavaFX. 2015. Disponível em: https://bit.ly/3iD60Mg. Acesso em: 28 ago. 2020.
DEITEL, P. J.; DEITEL, H. M. Java: como programar. 10. ed. São Paulo: Pearson Education, 2016.
DESCOMPILA. JavaFX para Iniciantes. 2018. Disponível em: https://bit.ly/32uwdqO. Acesso em: 28 ago. 2020.
ECLIPSE. SWT: The Standard Widget Toolkit. 2020. Disponível em: https://bit.ly/2FFPiNy. Acesso em: 28 ago. 2020.
GITHUB. SwingLabs SwingX Project. 2020. Disponível em: https://bit.ly/2FvaVR6. Acesso em: 28 ago. 2020.
JGOODIES. Professional Java Desktop. [s.d.]. Disponível em: https://bit.ly/3hxzsC5. Acesso em: 28 ago. 2020.
OPEN JFX. JavaFX. [s.d.]. Disponível em: https://bit.ly/2E3dusR. Acesso em: 28 ago. 2020.
ORACLE. Abstract Window Toolkit. 2020. Disponível em: https://bit.ly/3c0xWae. Acesso em: 28 ago. 2020.
ORACLE. Trail: creating a GUI with JFC/Swing. [s.d.]. Disponível em: https://bit.ly/33A7vo2. Acesso em: 28 ago. 2020.
PIVOT. Apache Pivot. [s.d.]. Disponível em: https://bit.ly/2ZF12XW. Acesso em: 28 ago. 2020.
QTJAMBI. Qt Jambi Reference Documentation. 2009. Disponível em: https://bit.ly/3hyx1iC. Acesso em: 28 ago. 2020.
SIQUEIRA, W. A. Visualizando gráficos de funções matemáticas com JavaFX. 2018. Disponível em: https://bit.ly/3c2BrNB. Acesso em: 28 ago. 2020.