Mostrando postagens com marcador fxml. Mostrar todas as postagens
Mostrando postagens com marcador fxml. Mostrar todas as postagens

25 de out. de 2017

Usando CDI 2.0 em uma aplicação JavaFX

Com o lançamento do CDI 2.0 nós temos um container que pode ser usado em uma aplicação Java SE! Anteriorment se você quisesse fazer uso de CDI em uma aplicação Java SE você teria que usar classes proprietárias do Weld, veja o artigo FXML & JavaFX—Fueled by CDI & JBoss Weld.

Essa feature é bem explicada pelo Adam Bien em um vídeo, veja:


Claro que era meu objetivo tentar isso em uma aplicação javaFX e nesse artigo breve compartilharei com vocês a minha experiência e o código.

Crie o container em uma aplicação JavaFX


Uma aplicação JavaFX é uma classe que estende de javafx.application.Application, que é o ponto de entrada para aplicações JavaFX e onde o stage principal pode ser usado. Para usar CDI devemos criar o SeContainer e certificar-se que ele irá criar todas as classes gerenciadas pelo CDI. Isso deve ser feito no ponto de entrada da Application para que possamos gerenciar todas as classes criadas de lá.

Uma vez criado o container você tem diferente formas de enviar o Stage para a aplicação JavaFX (a que você vai programar e não a que criamos para grudar CDI ao javaFX). Por exemplo, você pode fazer com que users possam estender uma interface e então injetar a classe do usuário dentro da nossa CDI application para invocar por lá.



Hpa uma forma mais elegante que é usando a API de observer do CDI. Nesse caso podemos criar uma anotação que será o qualifier para o evento  javafx.stage.Stage. CDI sabe inteligentemente as classes que observam aquele evento e vai selecionar a classe quando ativarmos o evento com o stage principal. Isso é semelhante ao que você pode ver no artigo que mencionamos FXML & JavaFX—Fueled by CDI & JBoss Weld.



Independente da solução que escolher não "desligue o container" ou isso pode deixar app inconsistente. Na verdade isso não deve afetar muito, mas eu decidi não fazer o shutdown.

Beleza! Daqui pra frente você pode usar CDI na sua app! Vá em frente e injete coisas nas suas classes JavaFX. Exceto, é claro, se você estiver usando FXML. Nesse caso JavaFX cria os controllers para você usando reflection e CDI não estará ciente da classe criada, ou seja, vai tudo ser nulo pois CDI não injetará. Uma solução é criar um FXMLLoader e fazer o CDI criar os controllers invés de deixar o FXML loader criar ele. O código abaixo foi novamente pego de  FXML & JavaFX—Fueled by CDI & JBoss Weld mas com a adição do delicioso lambda do Java 8:






Finalmente você pode criar sua própria aplicação mas NUNCA chame os métodos estáticos do FXMLLoader, use o injetado, por exemplo:



Lembre que você agora pode injetar coisas no seu controller. No nosso caso eu injetei um clássico Greeter, semelhante ao que abordo no post Primeiros Passos com CDI:





Não se esqueça também  do arquivo vazio beans.xml que irá ativar CDI. Essa é a estrutura do projeto que eu usei nos meus testes:




O resultado final foi mostrado abaixo - a diferença é que a mensagem veio de um bean gerenciado por FXML:


O código completo pode ser encontrado no github.

4 de mar. de 2014

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

Veja aqui um CRUD com JavaFX


Até agora nossas postagem utilizaram 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 JavaFX. 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:

public class DigaOlaComJava extends Application {

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

 @Override
 public void start(Stage palco) throws Exception {
  final Reflection 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(new EventHandler() {
   @Override
   public void handle(ActionEvent arg0) {
    lblMensagem.setText("Olá, " + txtNome.getText()
      + ", bem vindo!");
   }
  });
 }
}

Essa é uma aplicação simples, temos poucos componentes e um leiaute muito fácil de se montar. Mas e quando temos aplicações cheia de controles e leiaute 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(código no github):



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. (mais imagens e informações nesse blog)



Em uma postagem futura iremos trazer mais detalhes com relação ao uso do Scene Builder. O download pode ser feito no site da Oracle.O Scenebuilder deve ser baixado no site da empresa Gluon.

Vídeo

Abaixo um vídeo demonstrando o que falamos nesse breve artigo.


Conclusão

Criar interfaces com  FXML traz agilidade e facilidade na criação de aplicações em JavaFX, além de forçar o usuário a separar bem sua lógica da construção da GUI.

 O código da aplicação está no Github!