4 de nov de 2013

Apresentações de introdução ao JavaFX (em inglês)

Olá Pessoal,

Essa é uma postagem extra. Estou correndo com umas outras coisas e uns projetos paralelos e ainda não terminei a postagem prática sobre a classe Node. Então, resolvi compartilhar essas duas apresentações que encontrei na internet. Elas são uma boa introdução ao JavaFX, pena que estão em inglês...








Bem, esse não é o fim do blog! Os acessos aqui estão subindo de forma incrivelmente rápida! Eu quero cobrir mas três partes da API antes do Java 8, para isso tenho que fazer aproximadamente 5 postagens até o fim do ano

13 de out de 2013

A classe Node e seus principais atributos

Desde o começo desse blog nós falamos sobre a classe Node (nó). Ela é a classe pai(mãe?) de tudo que está em uma aplicação JavaFX: textos, formas geométricas, botões, tabelas, gerenciadores de leiautes que contém outros nós, etc... Nesse artigo, vamos dar um "rolê" na documentação do nó e tentar deixar claro por que a API do JavaFX, a tal do scene graph, é muito poderosa e facilita qualquer um começar a criar aplicações atrativas visualmente sem gastar muito tempo com aprendizagem.

A classe Node e seus principais atributos

Essa classe é grandinha: A documentação dela jé de assustar, mas imagine só que o código dela tem 8760 linhas! Portanto, não vamos cobrir todos os seus aspectos, mas vamos dividir essa parte em subseções: Transformações, atributos, eventos.
Nó, conforme repetido inúmeras vezes, é a classe pai de todos os componentes que estão em uma aplicação JavaFX. Com o nó você consegue navegar entre os objetos e tratar os mesmos sem se importar qual é a implementação(você consegue modificar algumas propriedades sem se preocupar se o nó em sí é um botão, forma geométrica, etc). O nó é também responsável pela arquitetura do JavaFX, o tal do Scene Graph:

Veja o que selecionamos para discutirmos sobre essa classe:

Transformações

É possível transformar um nó: Rotacionar, escalar(mudar o tamanho) e mudar sua posição. No post anterior acabamos por mostrar como é possível criar animações usando esses atributos e as classes de transições. Vejam os principais atributos de transformação de um nó:
  • Rotação: Permite rotacionar o nó usando o método setRotate(double). Lembre-se que a rotação é sempre de 0 a 360;
  • Escalar: Escalar um nó significa aumentar proporcionalmente o tamanho do mesmo. Podemos escalar a altura e largura. Exemplo: se escalamos o nó em 2 na largura X, quer dizer que a largura do mesmo será X*2. Os métodos para alterar a escala de largura e altura são, respectivamente, setScaleX(double) e setScaleY(double);
  • Trocar posição: Há dois atributos que determinam a posição do componente na tela: X e Y, onde X é a posição horizontal e Y é a posição vertical. Para mudar a posição vertical e horizontal de um componente, usamos, respectivamente, os métodos setTranslateY(double) e setTranslateX(double).

Atributos 

Alguns atributos são muito úteis e já estão presentes no nó. Eu escolhi alguns para abordar aqui. É óbvio que temos muitos outros, mas vamos deixar pra mais tarde. Se você estiver ansioso, fique a vontade para explorar a documentação da classe.
  • Effect: Um efeito a ser aplicado a esse nó. Ah, não vamos falar muitos de efeitos nessa postagem! Vamos deixar um biscoito, os efeitos estão todos no pacote javafx.scene.effect e vamos abordar com mais detalhes no futuro;
  • id: É um identificado único que podemos dar a esse nó. Podemos configurar o valor usando o método setId(String);
  • Disabled: Indica se um nó está desabilitado. Caso um nó esteja desabilitado, ele será visível, mas não receberá eventos (ver a seção Eventos nesse mesmo artigo) e sua aparência será de desabilitado, ou seja, você não poderia interagir com o nó. Para desabilitar um nó use: setDisabled(boolean).
  • Visible:  Indica se um nó será visível. Caso false, o nó não será visível e não receberá eventos. Configuramos o valor de visible com o método setVisible(boolean).
  • Focused: Informa se o nó tem o foco. Caso tenha o foco, ele poderá receber eventos de teclado. Você pode saber se um nó está focado através do método isFocused(). E para trazer o foco para um nó, você deverá usar o método requestFocus(). Note que o foco poderá vir naturalmente quando navegando na aplicação;
Eventos
Nós suportam todos os eventos possíveis, sejam eles vindo de teclados, toque, ou mouse. Se você quer entender sobre tratamento de eventos, por favor, veja esse artigo. Hoje iremos tratar de diversos outros eventos, mas seremos breves, pois a teoria básica está no artigo mencionado.
  • Eventos do Mouse: O nó contém diversos métodos setOnMouse*, onde * é uma ação relacionada ao mouse, que pode ser: Clicked, Moved, Exited, Released, entre outras. Em outras palavras, quando configuramos um EventHandler usando o método setOnMouseClicked, estamos informando uma ação que queremos que seja executada quando o usuário clica sobre o nó. Note que o tipo de evento depende do evento que foi feito, no caso do Mouse temos os dois principais eventos: MouseEvent e MouseDragEvent;
  • Eventos do Teclado: Similar aos eventos gerados por mouse, temos os eventos gerados pelo teclado. O evento gerado é o KeyEvent e configuração nosso listener usando os métodos setOnKey*;
  • Eventos gerados por gestos: Algo que recentemente tem se tornado imprescindível nos frameworks gráficos é o uso de eventos gerados pelo toque. Muitos dispositivos hoje contém uma touch screen que permitem que, com os dedos, geramos diversos eventos novos. Vejam a imagem abaixo com os principais eventos:
O JavaFX possuí suporte a esses eventos de touch, zoom, scroll, rotate e swipe. Há os métodos setOn* para cada um dos eventos que podemos gerar com os dedos, mas como precisaríamos de um dispositvo que tenha suporte a esses eventos, não vamos abordar eles nessa postagem.

Notem que todas essas propriedades são do tipo Property, ou seja, podemos realizar binding e adicionar listeners para elas. Mas, esse é um assunto para uma postagem futura :)

O nó na prática

No próximo artigo vamos discutir uma pequena aplicação que mostra como acessar os atributos do nó aqui mostrados. Para evitar estender demais a postagem, iremos fazer isso em um artigo dedicado.

Conclusão

A classe node do JavaFX é muito poderosa e facilita a manipulação de qualquer elemento da aplicação de forma fácil e unificada. Aprender essa classe é um passo importante no aprendizado eficaz da nova API gráfica da plataforma Java.

18 de set de 2013

Criando animações usando as transições do JavaFX 2 - Prática

Seguindo o artigo anterior, hoje vamos mostrar as transições na prática, mostrar um pouco de código!
Para demonstrar a ideia básica dessa API, criei uma aplicação e fiz um vídeo, vejam abaixo:



Código

Para criar as transições, usamos uma classe chamada FabricaTransicao  Nessa classe há um método chamado fazerTransicao que, dado um enum, duração e um nó, sempre cria uma nova transição:

public static class FabricaTransicao {

 public static enum Transicoes {
  FADE, TRANSLATE, SCALE, FILL, ROTATE
 }

 public static Transition fazerTransicao(Transicoes transicao,
   double duracaoSegundos, Node alvo) {
  Duration duracao = new Duration(duracaoSegundos * 1000);
  Transition t = null;

  switch (transicao) {
  case FADE:
   FadeTransition fadeTransition = new FadeTransition();
   fadeTransition.setFromValue(1);
   fadeTransition.setToValue(0);
   fadeTransition.setDuration(duracao);
   fadeTransition.setNode(alvo);
   t = fadeTransition;
   break;
  case FILL:
   FillTransition fillTransition = new FillTransition();
   fillTransition.setFromValue(Color.RED);
   fillTransition.setToValue(Color.DARKGREEN);
   fillTransition.setDuration(duracao);
   fillTransition.setShape((Shape) alvo);
   t = fillTransition;
   break;
  case ROTATE:
   RotateTransition rotateTransition = new RotateTransition();
   rotateTransition.setByAngle(360);
   rotateTransition.setDuration(duracao);
   rotateTransition.setNode(alvo);
   t = rotateTransition;
   break;
  case SCALE:
   ScaleTransition scaleTransition = new ScaleTransition();
   scaleTransition.setFromX(1);
   scaleTransition.setFromY(1);
   scaleTransition.setToX(4);
   scaleTransition.setToY(4);
   scaleTransition.setDuration(duracao);
   scaleTransition.setNode(alvo);
   t = scaleTransition;
   break;
  case TRANSLATE:
   TranslateTransition translateTransition = new TranslateTransition();
   translateTransition.setToX(600);
   translateTransition.setToY(250);
   translateTransition.setDuration(duracao);
   translateTransition.setNode(alvo);
   t = translateTransition;
   break;
  }
  t.setAutoReverse(true);
  t.setCycleCount(2);
  return t;
 }
}


Isso obviamente não é "bonito", mas esse código não utiliza as melhores práticas de codificação, ele é somente para demonstrar as transições. As 5 transições aí criadas mostram como usamos os métodos mais básicos da transição. Primeiramente criamos temos um atributo que é do tipo Transition, ou seja, uma classe abstrata, então de acordo com o valor do enum criamos uma transição concreta e atribuimos à transição abstrata.
Note a repetição de uso dos métodos setNode e setDuration. Esses métodos estão em quase todas as transições, mas não em todos, por isso eles não puderam ser definidos na classe abstrata. já nas seguintes duas linhas em destaque, temos dois métodos que são da classe abstrata, logo não precisamos repetir a chamada do mesmo para cada transição criada.

  public static Transition fazerTransicao(Transicoes transicao,
  

   switch (transicao) {
   case FADE:
    // ...
    fadeTransition.setDuration(duracao);
    fadeTransition.setNode(alvo);
    t = fadeTransition;
    break;
   case FILL:
    //...
    fillTransition.setDuration(duracao);
    fillTransition.setShape(alvo);
    t = fillTransition;
    break;
   case ROTATE:
    //...
    rotateTransition.setDuration(duracao);
    rotateTransition.setNode(alvo);
    t = rotateTransition;
    break;
   case SCALE:
    //...
    scaleTransition.setDuration(duracao);
    scaleTransition.setNode(alvo);
    t = scaleTransition;
    break;
   case TRANSLATE:
    //...
    translateTransition.setDuration(duracao);
    translateTransition.setNode(alvo);
    t = translateTransition;
    break;
   }
   
   t.setAutoReverse(true);
   t.setCycleCount(2);
   return t;
  }

Esses dois métodos simplesmente irão fazer com que a transição mude o atributo do nó e volte para o valor original. Para isso precisamos ter dois ciclos (ciclos são quantas vezes a transição será tocada).

Os botões na parte acima da aplicação são do tipo "ToggleButton" e são parte de um grupo. Esse grupo é gerado baseado no seguinte Enum que você pode ver declarado na classe FabricaTransicao mostrado acima. O Enum contém as transições que a Fábrica suporta e de acordo com os valores dele, a gente gera os botões. Veja o código abaixo:

private HBox criaPainelSuperior() {
 HBox hbTopo = new HBox(10);
 hbTopo.setSpacing(10);
 hbTopo.setAlignment(Pos.CENTER);
 Transicoes[] transicoes = Transicoes.values();
 // grupo para todas as transições
 botoesTransicao = new ToggleGroup();
 for (int i = 0; i < transicoes.length; i++) {
  Transicoes t = transicoes[i];
  ToggleButton tb = new ToggleButton(t.name());
  tb.setUserData(t);
  if (i == 0) {
   tb.setSelected(true);
  }
  tb.setToggleGroup(botoesTransicao);
  hbTopo.getChildren().add(tb);
 }
 return hbTopo;
}

Perceba que através do método setUserData nós adicionamos a cada botão o valor do enum que esse botão representa e usamos esse valor para fabricar nossa transição.  
Quando você clica no botão "Tocar", a "action" do mesmo será usar a fábrica para produzir uma transição de acordo com o botão selecionado, configurar o comportamento dos botões para que os mesmos não fiquem ativos quando a transição estiver tocando(ou que fiquem ativos só quando a transição estiver tocando). Veja a ação do botão Tocar:

btnTocar.setOnAction(new EventHandler() {
 @Override
 public void handle(ActionEvent e) {
  // antes de tocar, pegamos a mais nova transição selecionada
  Transicoes t = (Transicoes) botoesTransicao.getSelectedToggle()
    .getUserData();
  transicaoAtual = FabricaTransicao.fazerTransicao(t,
    sldTempo.getValue());
  // lógicas de habilitação dos botões, temos que setar todas as
  // vezes pq trocamos as transições
  btnParar.disableProperty().bind(
    transicaoAtual.statusProperty().isNotEqualTo(
      Status.RUNNING));
  btnTocar.disableProperty().bind(
    transicaoAtual.statusProperty().isEqualTo(
      Status.RUNNING));
  btnPausar.disableProperty().bind(
    transicaoAtual.statusProperty().isNotEqualTo(
      Status.RUNNING));
  btnAjusta.disableProperty().bind(
    transicaoAtual.statusProperty().isEqualTo(
      Status.RUNNING));
  sldTempo.disableProperty().bind(
    transicaoAtual.statusProperty().isEqualTo(
      Status.RUNNING));
  System.out.println("Tocando transição " + t);
  transicaoAtual.play();
 }
});

Os outros botões irão controlar a transição (parar e pausar) e um serve para "ajustar" o texto quando a transição é parada no meio. Veja o método que é chamado quando clicamos nesse botão.

private void criaNoAlvo() {
 // configurar coisas do texto alvo...
 alvo = new Text("** Transições **");
 alvo.setFont(new Font(60));
 // efeitinsss
 Reflection efeito = new Reflection();
 efeito.setFraction(0.7);
 alvo.setEffect(efeito);
 alvo.setFill(Color.RED);
 raiz.setCenter(alvo);
}

O "slider" no canto direito será usado para que possamos selecionar o tempo total da transição.  Ao criar a transição, pegamos o valor dele e enviamos para o método de criação. Veja a criação e o uso do slider:

// criando o slider
sldTempo = new Slider(1, 10, 5);
//... criando a transição
transicaoAtual = FabricaTransicao.fazerTransicao(t, sldTempo.getValue(), alvo);

Conclusão

Nesse breve artigo nós apresentamos o código de uma aplicação que as transições do JavaFX. Talvez algumas coisas nesse artigo podem parecer um pouco obscuras, mas provavelmente é por que você não acompanha o blog há muito tempo! Sinta-se a vontade para explorar os artigos antigos que muitas coisas serão esclarecidas.
O código completo pode ser conferido no github. Comente esse artigo se tiver dúvidas ou use nosso grupo sobre JavaFX.




15 de set de 2013

Criando animações usando as transições do JavaFX 2 - Teoria

Hoje vamos falar de algo mais interessante do que simples botões ou figuras geométricas: as transições! Com elas nós podemos criar animações simples com poquissímo código!

O que são transições?

Transições são um conjunto de classes da API do JavaFX 2 que  permitem que crie animações. Com ela nós podemos modificar o valor de uma propriedade em um dado tempo. Por exemplo, você poderia fazer um objeto mover da posição X 0 até a posição X 150 em 2 segundos e isso iria criar uma animação.
Após configurar os parâmetros corretamente, você pode decidir quando a transição começa e até parar antes da mesma terminar. Ou seja, você pode, por exemplo, utilizar um botão para disparar o início da transição e outro para parar. Para você ter ideia, abaixo seguem umas telas de aplicações que demonstram o uso de transições:



Transições disponíveis na API do JavaFX 2

As classes de transição oferecidades no JavaFX 2 ficam no pacote javafx.animation e as seguintes transições estão disponíveis para uso:

  • FadeTransition: Muda a opacidade(tranparência) de um nó. O FadeTransition permite variar essa opacidade em um dado tempo. Por exemplo, você pode configurar uma transição para em 1 segundo variar a opacidade de um nó(um botão, uma imagem, uma figura geométrica, etc) de 0 até 1 e isso fará com que o mesmo passe de invisível até ser completamente visível no tempo de 1 segundo;
  • FillTransition: Com a FillTransition nós podemos mudar a cor de preenchimento de um objetvo. Se um objeto tem o preenchimento com a cor azul e você usa a transição para mudar a cor de azul para rosa em um segundo, isso significa que a cor de preenchimento do mesmo irá iniciar totalmente azul e no espaço de tempo de 1 segundo irá se tornar completamente rosa, dando um efeito bastante interessante;
  • RotateTransition: Uma das propriedades mais comuns em um nó é a rotate (rotação). A RotateTransition mudará a rotação de um objeto de acordo com o tempo configurado. Por exemplo, você pode rotacionar um objeto de 0º até 90º em 2 segundos e após iniciar essa tranisção, ele irá ter a rotação modificada gradualmente até que o tempo termine;
  • ScaleTransition: A ScaleTransition server para você modificar a escala de um objeto, seja a altura ou a largura. Em outras palavras, você pode fazer a escala de um objeto ser modificada de X para X^2  em um dado intervalo de tempo;
  • TranslateTransition: Similarmente ao que foi falado na introdução desse artigo, a TranslateTransition irá modificar a posição X ou Y de um objeto em um dado intervalo de tempo;
  • StrokeTransition: A StrokeTransition é muito similar à FillTransition, no entanto, nessa transição a modificação não é do preenchimento, mas sim da linha que contorna o mesmo;
  • PathTransition: Embora complexa, a PathTransition é muito útil, pois permite que muitas ações sejam tomadas de acordo com o objeto Path passado;

A API do JavaFX também disponibiliza transições que permitem que várias transições sejam "tocadas" ao mesmo tempo, são elas:

SequentialTransition: A SequentialTransition server para adicionar diversas transições para serem "tocadas" de forma sequencial, ou seja, uma após a outra. Por exemplo, se adicionamos a transição t1, t2, t3 em uma SequentialTransition e tocar ela, t1 será ativada, em sequência será ativada t2 e por fim iremos fechar com t3; Se quisermos adicionar um tempo de espera entre as transições, podemos usar a PauseTransition, que é um tipo especial de transição cuja função é simplesmente "dar um tempo" antes da próxima transição da sequência;
ParallelTransition: A ParallelTransition atua de forma semelhante à SequentialTransition, mas toca todas as transições em paralelo, sendo que o tempo de duração será a da transição mais longa.



Lembre-se que todo componentes em uma aplicação JavaFX herda de (é um) nó e todos os nós tem propriedades em comum como rotação, posição X e Y, opacidade, etc;

Transições na prática

Como muitos já devem ter imaginado, temos uma classe comum para todas as transições, a classe Transition  Abaixo temos uma explicação de seus principais métodos:

play(): Começa a "tocar" a transição. Se a transição estava pausada antes, chamar esse método fará com que a transição volte a tocar do ponto onde tinha parada. Similar ao play, temos a playFromStart, que começa uma transição desde o começo e playFrom(Duration), onde podemos informar um ponto para a transição começar a tocar;
pause(): Para a transição em um dado momento, sendo que ao chamar play, a transição irá começar no momento parado por pause;
stop(): Para a transição por completo. A próxima vez que chamarmos play a transição irá iniciar do ponto inicial;
setOnFinished(EventHandler<ActionEvent>): Esse método é interessante! Com ele podemos informar uma ação que você deseja que seja feita assim que a transição termina de "tocar";
setAutoReverse(boolean value): Se chamarmos esse método e informar o valor true para value, iremos fazer com que a transição "volte", ou seja, se a transição for fazer um nó ir da posição X 0 para a posição 10, ao chamar setAutoReverse(true), o mesmo irá até a posição 10 e irá voltar para a posição 0 invés de parar na posição X 10;
setNode(Node): Aqui é onde falamos qual será nosso alvo
Outros métodos: Há outros métodos e atributos interessantes(acessados através de métodos) que você queria dar uma olhada. Para isso veja a documentação da classe que Transition veio, a Animation.

E o código?

Na próxima parte desse artigo vamos mostrar o código de uma aplicação que usa todas as transições do JavaFX. Eu sei que é "brochante" ler um textão desse e no fim não ter código, mas garanto um próximo artigo com bastante código pra gente discutir!

Conclusão

Transições é uma parte divertida da API do JavaFX. Com elas podemos criar animações com pouquíssimas linhas de código. Não perca o próximo artigo!

25 de jul de 2013

Apresentações e mini-curso sobre JavaFX

Olá pessoal! Fiquei uns meses sem postar por aqui, mas tenho 2 posts em andamento, em breve eles aparecem aqui! Hoje é uma postagem rápida.
Eu apresentei em 3 eventos sobre JavaFX esse ano: FISL 14 , TDC Floripa e Just Java. Ambos eventos de altíssima qualidade e com uma quantidade incrível de pessoas interessadas na tecnologia. Destaque para a sala cheia em um mini-curso no Just Java (cheia mesmo, algumas pessoas não entraram por essa razão).
Eu prometi, estou atrasado, mas aqui vão as apresentações que fiz para cada um dos eventos:

Desenvolvimento rápido de aplicações com JEE e JavaFX





JavaFX: A nova biblioteca gráfica da plataforma Java




É isso. Desculpe aos que acompanham o blog (eu sei que alguns acompanham), pois tenho estado muito desligado de TI no geral (acho que as vezes ficamos saturados) mas estou voltando aos poucos :) Em breve mais dois novos artigos, fiquem ligados :)

5 de mar de 2013

Gerenciadores de leiaute básicos II

Vamos dar continuidade ao post anterior apresentando mais gerenciadores de leiaute. Nesse artigo vamos apresentar o BorderPane, FlowPane e o GridPane. A arquitetura deles é a mesma, se você quiser saber mais sugiro que veja o primeiro artigo da série.

BorderPane 

Uma das heranças do bom e velho Swing é o BorderPane. A idéia é bem simples: você coloca os componentes em regiões do painél. Essas regiões são referenciadas como: norte, sul, leste, oeste e centro.
Não há nenhum segredo no uso dele, mas há um pequena diferença que é termos que informar na hora de adicionar os componentes a qual região o mesmo pertence. Vamos ao exemplo de código e em seguida a explicação.
BorderPane borderPane = new BorderPane();
Label lblTop, lblEsquerda, lblBaixo, lblDireita, lblCentro;
// 1
borderPane.setTop(lblTop = new Label("Topo"));
borderPane.setLeft(lblEsquerda = new Label("Esquerda"));
borderPane.setBottom(lblBaixo = new Label("Baixo"));
borderPane.setRight(lblDireita = new Label("Direita"));
borderPane.setCenter(lblCentro = new Label("Centro"));
// 2
BorderPane.setAlignment(lblTop, Pos.CENTER);

  1. Ao contrário dos layouts apresentados no último post, o BorderPane não utiliza os métodos add, set e remove que falamos no nosso último post, mas sim métodos correspondentes à região da tela. Os métodos setTop,setLeft,setBottom,setRight e setCenter, são respectivamente para informar os nós do topo, esquerda, baixo, direita e centro. Esses nós são agrupados dentro do espaço do BorderPane
  2. Nessa parte mostramos como alinhamos um nó. Veja que usamos um método estático para isso, o que já gerou muitas críticas. Cabe a você tentar outros valores de Pos na chamada desse método!

Abaixo o resultado desse código:



GridPane

O GridPane, ou painel de grade, permite adicionar componentes em posições específicas semelhantes á uma grade de nós. Para entender melhor imagine a área do GridPane como um tabuleiro de batalha naval. Nesse tipo de jogo, temos os campos definidos por divisões, como por exemplo A1, B5, etc. O GridPane atua de forma semelhante, posicionando componentes nessa grade. No entanto, especificamos a posição com dois números invés de uma letra e um número, exemplo: 1-1, 5-2, etc. Esse gerenciador de leiaute também não utiliza os métodos add, set e remove. Na verdade, no momento de adicionar o componente já especificamos qual a "gradezinha" ele vai ocupar. Vamos a um exemplo de código para esclarecer.
GridPane gridPane = new GridPane();
// 1 
gridPane.add(new Label("0 X 0"), 0, 0);
gridPane.add(new Label("0 X 1"), 0, 1);
gridPane.add(new Label("1 X 0"), 1, 0);
gridPane.add(new Label("1 X 1"), 1, 1);
// 2
gridPane.setVgap(20);
gridPane.setHgap(20);
// 3
gridPane.setTranslateX(120);
gridPane.setTranslateY(30);
  1. Estamos adicionando um componente ao GridPane e informando a posição X e Y que ele vai ocupar na grade. Um label está sendo adicionado para mostrar para você onde cada elemento vai ficar
  2. Esses métodos server para informar o espaçamento entre os componentes adicionados. setVgap é para o espaço na vertical e setHgap para o espaço na horizontal. "Gap" pode ser traduzido como "lacuna".
  3. Por fim configuramos a posição dos componentes na tela. Assim como qualquer nó, podemos informação a posição X e Y do componente no "pai" dele.
E isso resulta em:


FlowPane

"Painel de Fluxo" é um significado ao pé da letra para FlowPane. Como o nome diz, é um painel que segue o fluxo da coisa, ou seja, vocẽ vai adicionando componentes e ele vai colocando de acordo com o fluxo. O fluxo pode ser na vertical ou horizontal e os compomentes podem ser posicionados de forma centraliza, centraliza na vertical, tudo ao topo, etc. Parece difícil, mas é um dos paineis mais simples. Por exemplo, digamos que você utilize um desses do tipo horizontal e adicione 4 componentes. O 4 não caberia na mesma linha, então o FlowPane coloca ele na "linha abaixo", mesmo sobrando espaço na terceira linha. O mesmo acontece para o FlowPane na vertical, mas aí ele colocaria os componentes na próximo coluna, seguindo o fluxo. Lembrando que isso é dinâmico, se vocề redimensiona o pai, ele realoca os componentes sempre seguindo o fluxo. Mas chega de papo e vamos ao código.
// 1
FlowPane flowPane = new FlowPane();
// 2
flowPane.setAlignment(Pos.CENTER_RIGHT);
for (int i = 0; i < 10; i++) {
        // 3    
 flowPane.getChildren().add(new Label("Label " + i));
}
  1. Criamos o nosso FlowPane. Falei que podemos a direção do fluxo. Isso pode ser feito direto no construtor usando a classe Orientation.
  2. Aqui setamos o alinhamento: centro, centro para a direita, centro // para esquerda, topo para esquerda, etc. Brinque com outros valores :)
  3. Adicionando um componente ao nosso Painel. Isso é feito da forma simples já mostrada no nosso post anterior.
Bem, aqui está o resultado do código acima:



Conclusão

Mostramos mais três gerenciados de leiaute(ou layout). No próximo post já é hora de algo mais avançado e prático. Iremos criar uma APP mais empolgante que simples labels e figuras geométricas, fique ligado!