Toques de requinte
para aplicações
Desktop com JavaFX
Conhecendo o funcionamento desta plataforma que
promete estilizar aplicações Desktop, mesmo sem grandes
conhecimentos de CSS.
/ 42
Bruno Henrique de Oliveira | bruno.vky@live.com
cursando Análise e Desenvolvimento de Sistemas na FATEC São José dos Campos, programa com Java desde 2010, focado em
desenvolvimento Android e JavaFX, possui conhecimento em desenvolvimento de jogos em Android com a framework AndEngine.
um AnchorPane, que seria equivalente ao JPanel do O método main é necessário para executar o nosso
Swing, para adicionar os componentes. Os compo- formulário. O método launch é estático, da classe Ap-
nentes são adicionados ao painel, que é adicionado à plication, e passa como parâmetro o args que vem do
cena, que por sua vez é adicionada ao estágio. método main, caso haja alguma variável que venha
junto da execução da classe. O método start é imple-
Listagem 1. Criação de uma tela simples. mentado também da classe Application, e é nele que
colocamos a lógica para inicialização do formulário.
package application;
inicialmente criamos um painel que conterá os com-
ponentes da tela, o AnchorPane, e damos sua largu-
import javafx.application.Application; ra e altura com o método setPrefSize(double width,
import javafx.scene.Scene; double height), no exemplo, damos 150x200. Então,
import javafx.scene.layout.AnchorPane; criamos uma nova Scene, correspondente à tela,
import javafx.stage.Stage; passando o componente de visualização principal da
tela, no caso o nosso pane. indicaremos o valor da
public class CadastroApp extends Application { variável stage, que é do tipo Stage, que seria nossa
tela propriamente dita, passando para ela qual cena
// Método principal para execução da Application
public static void main(String[] args) { acontecerá com o método setScene(Scene scene).
launch(args); Demos também um título para a tela com o método
} setTitle(String value), e por fim abrimos a tela com o
método show(), da Stage.
// Método implementado da Application, para iniciar
a tela
@Override
Criando os componentes
public void start(Stage stage) throws Exception {
Nossa tela terá poucos e básicos itens, como
AnchorPane pane = new AnchorPane(); campos de texto e botões. Criaremos um método
pane.setPrefSize(150, 200); para inicializar os componentes e adicioná-los à
Scene scene = new Scene(pane); cena.
stage.setScene(scene);
stage.setTitle(“Cadastro de Clientes”); Listagem 2. Método para inicialização de compo-
stage.show(); nentes.
}
private void initComponents(AnchorPane pane) {
TextField txNome = new TextField();
}
txNome.setPromptText(“Digite seu nome”);
TextField txIdade = new TextField();
43 \
O método setOnAction(EventHandler han-
txIdade.setPromptText(“Digite sua idade”); dler) é o que indica a ação do botão, criamos um
txIdade.setLayoutY(30); novo EventHandler para indicar o evento de ação,
RadioButton rbMasc = new RadioButton(“Masculino”); este método deve ser implementado, com o método
rbMasc.setLayoutY(60); handle(ActionEvent arg0).
RadioButton rbFem = new RadioButton(“Feminino”); Para a função de cadastrar, apenas exibiremos
rbFem.setLayoutY(90);
uma caixa de mensagem dizendo que o cliente foi ca-
ToggleGroup groupSexo = new ToggleGroup();
groupSexo.getToggles().addAll(rbMasc, rbFem); dastrado com sucesso.
Button btCadastrar = new Button(“Cadastrar”); btCadastrar.setOnAction(new EventHandler<ActionEvent>()
btCadastrar.setLayoutY(120); {
Button btSair = new Button(“Sair”); @Override
btSair.setLayoutY(150); public void handle(ActionEvent event) {
pane.getChildren().addAll(txNome, txIdade, rbMasc, JOptionPane.showMessageDialog(null,
rbFem, btCadastrar, btSair); “Cliente cadastrado com sucesso!”);
} }
});
/ 44
Figura 1. Formulário de cadastro de clientes. Figura 2. Tela de cadastro com efeito gradiente
do texto dos RadioButtons para branco, para melhor E dará o mesmo efeito do exemplo com o arquivo
visualização. CSS.
Listagem 4. Modificação no arquivo CSS.
.pane {
Segundo toque de requinte – Effects
Com o JavaFX, podemos usufruir de efeitos grá-
-fx-background-color: linear-gradient(from 0% 0% to 100% ficos visuais surpreendentes, como, por exemplo, um
100%, blue 0%, gray 100%); espelho d’água em um componente, ou uma sombra
} no mesmo. São diversas opções de Effects, a própria
Oracle disponibiliza exemplos práticos de uso.
.rb { Neste artigo, mostraremos dois exemplos, com
-fx-text-fill: white; Reflection e Drop Shadow. Primeiro, usaremos o Re-
} flection para dar um efeito de reflexão aos dois bo-
tões da tela. Seu uso em código é muito simples.
E apenas precisamos indicar nos RadioButtons, o
nosso iD deste arquivo. btCadastrar.setEffect(new Reflection());
btSair.setEffect(new Reflection());
rbMasc.getStyleClass().add(“rb”);
rbFem.getStyleClass().add(“rb”); O método setEffect(Effect effect) indica o tipo de
efeito utilizado no componente. instanciando um
novo Reflection, já vemos seu efeito prático. A figura
Veja o toque de requinte dado à aplicação, depois 3 apresenta este efeito.
dessas modificações. O efeito gradiente para painéis
faz uma diferença gráfica perceptível para qualquer
leigo. A figura 2 mostrará o resultado da modificação Podemos alterar certas propriedades do Reflec-
de estilo CSS na tela. tion, como a opacidade da reflexão. Para isto, bas-
A partir daqui, veremos diversos estilos de CSS ta instanciar uma variável do tipo Reflection e usar
para produzirmos efeitos visuais para a aplicação. seus métodos para configurá-lo da sua maneira. Este
Podemos também indicar o CSS direto no código. mesmo efeito poderia ser facilmente utilizado nos
Veremos o exemplo do efeito gradiente: RadioButtons ou nos TextFields, com o mesmo mé-
todo, presente em qualquer componente, pois todos
pane.setStyle(“-fx-background-color: linear-gradient( derivam da classe Node, envolvendo o conceito do
from 0% 0% to 100% 100%, blue 0%, gray 100%);”);
Composite Pattern.
45 \
Figura 3. Efeito Reflection. Figura 4. Efeito Drop Shadow.
Agora vamos colocar um efeito de sombra nos dois Listagem 5. FadeTransition no botão btCadastrar.
TextFields. Com o mesmo método setEffect(Effect
effect), podemos indicar o Drop Shadow. // Ação no botão, ao passar ao mouse sobre o componente
btCadastrar.setOnMouseEntered(new
DropShadow dropShadow = new DropShadow(); EventHandler<MouseEvent>() {
dropShadow.setSpread(0.5); @Override
public void handle(MouseEvent event) {
Usamos o método setSpread(double value) ape- FadeTransition transition = new FadeTransition(
nas para aumentar o espaço de sombreamento do Duration.millis(2000), btCadastrar);
transition.setFromValue(0.0);
componente. Agora, basta passar o efeito para cada
transition.setToValue(1.0);
componente. transition.play();
}
txNome.setEffect(dropShadow);
});
txIdade.setEffect(dropShadow);
/ 46
ver um componente de um ponto ao outro, daremos
este efeito para o botão “sair”.
KeyValue kv = new Keyvalue(btSair.scalexProperty(),
Listagem 6. Timeline no botão btSair. 1.0);
//Listagem 6. Timeline no botão btSair. KeyValue kv2 = new Keyvalue(
btSair.setOnMouseEntered(new btSair.scaleYProperty(), 1.0);
EventHandler<MouseEvent>() { KeyFrame kf = new KeyFrame(Duration.millis(1000),
@Override kv, kv2);
public void handle(MouseEvent arg0) { timeline.getKeyFrames().add(kf);
Timeline timeline = new Timeline(); timeline.play();
KeyValue kv = new Keyvalue(btSair. }
layoutxProperty(), btSair.getLayoutx() + 20); });
KeyFrame kf = new KeyFrame(
Duration.millis(2000), kv);
timeline.getKeyFrames().add(kf);
timeline.play(); A novidade aqui é a indicação de duas KeyValues
} ao mesmo tempo, para aumentar a escala do botão
}); em coordenada X e Y. Na construção da KeyFra-
me, indicamos todas as KeyValues necessárias,
logo após a duração. Utilizamos também o método
Criamos uma nova Timeline, que será responsável setOnMouseExited(EventHandler handler) para indi-
pelo efeito. A criação da KeyValue indica qual a tran- car uma ação ao tirar o mouse do componente, ele irá
sição de valores ocorrerá, no nosso caso, a coordenada fazer o botão voltar ao normal, conforme outra Time-
X do btSair será incrementada em 20. A KeyFrame in- line criada.
dica o tempo de execução do efeito, necessita passar
em sua construção qual a duração (Duration) e qual a
KeyValue, pode-se passar diversas KeyValues ao mes-
Considerações finais
Vimos um pouco do que o JavaFX oferece para
mo tempo. Adicionamos a KeyFrame para a Timeline,
os desenvolvedores Java. Seus efeitos gráficos visu-
com o método getKeyFrames().add(KeyFrame kf), e,
ais mostram-se incríveis para aplicações Desktop,
por fim, executamos, com o método play().
dando-nos poder para pensar em um layout adequa-
Ao passar o mouse sobre o botão, veremos o mes-
do e belo, mesmo sem conhecer efeitos avançados de
mo movendo-se para o lado direito. Este efeito já se
CSS e JavaScript, por exemplo. Com esta plataforma,
mostra bastante avançado. Podemos também au-
torna-se simples programar extensos formulários e
mentar a largura e altura de um componente, voltan-
dimensioná-los na tela de forma limpa. Pode-se tor-
do ao normal quando tira o mouse dele.
nar ainda mais organizado utilizando o programa da
Listagem 7. Efeito Scale no botão btSair. Oracle, o JavaFX Scene Builder, que é um ambiente
para desenvolver layouts do JavaFX com um sistema
btSair.setOnMouseEntered(new drag-and-drop. Ele gera um arquivo FXML, que é fa-
EventHandler<MouseEvent>() { cilmente identificado em código.
@Override
public void handle(MouseEvent arg0) {
Timeline timeline = new Timeline(); /referências
KeyValue kv = new Keyvalue(btSair.scalexProperty(), > JavaFX 2.0: Introduction by Example, de Carl Dea,
1.2);
ed. Apress. – Livro para introduzir JavaFX, com códigos
KeyValue kv2 = new Keyvalue(
btSair.scaleYProperty(), 1.2); práticos e ensino fácil, porém em inglês.
KeyFrame kf = new KeyFrame(Duration.millis(1000),
> http://docs.oracle.com/javafx/2/visual_effects/jfxpub-
kv, kv2);
timeline.getKeyFrames().add(kf); visual_effects.htm – Documentação sobre Effects
timeline.play(); > http://docs.oracle.com/javafx/2/animations/jfxpub-
}
animations.htm – Documentação sobre Transitions e
});
btSair.setOnMouseExited(new EventHandler Timelines
<MouseEvent>() {
> http://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/
@Override
public void handle(MouseEvent arg0) { cssref.html – Documentação sobre CSS JavaFX
Timeline timeline = new Timeline();
47 \