Introdução ao FXML: Criando interfaces em JavaFX usando XML e o Scene Builder

Até agora utilizamos código Java na criação das interfaces gráficas(GUI). O uso de Java pode parecer atrativo a primeira vista, no entanto, o código pode se tornar complexo e de díficil manutenção, mas não é só em Java que podemos criar as telas.

O uso de XML é possível no JavaFX para que possamos criar a GUI de uma aplicação e então referenciar o mesmo no código Java. Os XMLs que contém componentes JavaFX são chamados de FXML.

O modo Java de se fazer interfaces

Digamos que temos uma aplicação que contém um campo de texto, um botão e um campo de texto de leitura com uma saudação ao nome entrado. O código de interface para esse simples programa ficaria como segue:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.effect.Effect;
import javafx.scene.effect.Reflection;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class DigaOlaComJavaFX extends Application {

    public static void main(String[] args) {
        launch();
    }

    @Override
    public void start(Stage palco) throws Exception {
        final Effect r = new Reflection();
        final VBox raiz = new VBox(30);
        final HBox hbTopo = new HBox(5);
        final TextField txtNome = new TextField();
        final Button btnAcao = new Button("Enviar");
        final Label lblMensagem = new Label();
        raiz.setTranslateX(10);
        raiz.setTranslateY(10);
        lblMensagem.setText("Digite seu nome e clique no botão");
        hbTopo.getChildren().addAll(txtNome, btnAcao);
        raiz.getChildren().addAll(hbTopo, lblMensagem);
        lblMensagem.setEffect(r);
        Scene cena = new Scene(raiz, 250, 100);
        palco.setTitle("Aplicação usando código Java");
        palco.setScene(cena);
        palco.show();

        btnAcao.setOnAction(e -> lblMensagem.setText("Olá, " + txtNome.getText() + ", bem vindo!"));
    }
}

Essa é uma aplicação simples, temos poucos componentes e um layout muito fácil de se montar. Mas e quando temos aplicações cheia de controles e layout complexo?

Usando FXML

Utilizar XML em interface gráfica não é uma novidade. O Pivot, um framework Java para criação de aplicações desktop, e o Adobe Flex também utilizam esse conceito. A grande vantagem do uso dessa linguagem declarativa está na possibilidade de usar uma ferramenta para a geração da interface e a possibilidade de modificar o XML sem ter que recompilar a aplicação inteira.

O JavaFX traz suporte ao FXML, uma forma de declarar todos os elementos de interface sem escrever uma linha de código de Java. Veja como o programa que demonstramos anteriormente ficaria com FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<AnchorPane id="AnchorPane" prefHeight="88.0" prefWidth="306.0" xmlns:fx="http://javafx.com/fxml" 
    fx:controller="main.ControleAplicacao">
  <children>
    <TextField layoutX="14.0" layoutY="14.0" prefWidth="200.0" fx:id="txtNome" />
    <Button layoutX="226.0" layoutY="15.0" mnemonicParsing="false" 
      onAction="#atualizaMensagem" text="Clique!" />
    <Label fx:id="lblMensagem" layoutX="14.0" layoutY="44.0" prefHeight="21.0" 
      prefWidth="264.0" text="Digite seu nome e clique no botão">
      <effect>
        <Reflection fraction="0.9" />
      </effect>
    </Label>
  </children>
</AnchorPane>

Claro que o FXML também pode ser complexo e gigante, já falamos mais sobre isso. No código Java acima é fácil adicionar ações ao botão e manipular os elementos da interface. Mas como fazer com FXML?

O controller de um FXML

A lógica e o tratamento de eventos em uma aplicação JavaFX que usa FXML fica em uma classe que referênciamos no próprio FXML, essa classe é chamada de controller. Nessa classe podemos referenciar os elementos declarados no FXML para manipulação deles, lá também declaramos o método que irá tratar os eventos. Veja como fica o FXML completo e pronto para uso com o nosso controller.

O código do controller ControleAplicacao está mais abaixo e ele tem declarado campos correspondentes ao nosso TextField e Label. Notem que usamos a anotação @FXML no campo, é ela que informa o nome do mesmo e o JavaFX injeta o campo declarado lá no XML para nosso uso aqui! Veja o método atualizaMensagem também, é ele que é invocado quando clicamos no botão.

import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;

public class ControleAplicacao {

 @FXML
 Label lblMensagem;

 @FXML
 TextField txtNome;

 public void atualizaMensagem() {
  lblMensagem.setText("Olá, " + txtNome.getText() + ", bem vindo!");
 }
}

Executando sua aplicação com FXML

Nesse momento, nossa aplicação está funcionando. Só precisamos carregar o FXML e isso é feito através da classe FXMLLoader, que lê o nosso arquivo .fxml e retorna um objeto do tipo Parent. Com ele é possível configurar a raiz da cena da aplicação, veja:

public class DigaOlaComFXML extends Application {

 public static void main(String[] args) {
  launch(); 
 }

 @Override
 public void start(Stage palco) throws Exception {
  URL arquivoFXML = getClass().getResource(
    "./ola-mundo.fxml");
  Parent fxmlParent = (Parent) FXMLLoader.load(arquivoFXML);
  palco.setScene(new Scene(fxmlParent, 300, 100));
  palco.setTitle("Olá mundo com FXML");
  palco.show();
 }
}

Criando interfaces visualmente com o Scene Builder

Falamos que com Java o projeto poderia ficar muito complexo, mas você pode perceber que o XML não é lá aquelas facilidades... Felizmente temos uma ferramenta onde podemos arrastar e soltar componentes para desenhar nossa tela. Em seguida, exportamos um arquivo .fxml para uso em nossa aplicação JavaFX! Veja uma imagem da ferramenta.

Essa ótima ferramenta é mantida pela empresa Gluon e pode ser baixada no seguinte endereço: http://gluonhq.com/labs/scene-builder

results matching ""

    No results matching ""