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

6 de mar. de 2018

Visualizando gráficos de funções matemáticas com JavaFX

Já falamos nesse blog sobre os gráficos da API do JavaFX. Nessa postagem iremos compartilhar uma pequena aplicação que permite plotar qualquer função matemática de N, ou seja, um uso prático dos gráficos. A ideia é ter uma classe que permite você definir funções com nome e um lambda que contém a operação matemática. A aplicação irá de 1 até N (um número que você fornece) executando a função e coletando os dados para colocar no gráfico. O código é muito simples, veja:


Com esse código podemos plotar, por exemplo, as funções utilizadas em análise de algoritmos, que são:



Veja abaixo:


Podemos selecionar quais funções serão mostradas no momento e ajustar os valores mínimos:


Para rodar o código você só precisa de Java 8, baixar o arquivo, salvar em PlotarFuncao.java e executar:

$ javac PlotarFuncao.java
$ java PlotarFuncao

Você pode modificar o código e adicionar mais funções. Modifiquei a lista functions para isso:

static List<NamedFunction> functions = Arrays.asList(
NamedFunction.of("1", n -> 1d),
NamedFunction.of("log n", n -> log2(n)), 
NamedFunction.of("n", n -> n),
NamedFunction.of("n log n", n -> n * log2(n)), 
NamedFunction.of("n^2", n -> Math.pow(n, 2)),
NamedFunction.of("n^3", n -> Math.pow(n, 3)),
NamedFunction.of("2^n", n -> Math.pow(2, n))
);

Esse post foi mais um rapidinho para compartilhar essa pequena aplicação que, inclusive, já me foi util :-)

13 de jan. de 2017

Algoritmo Genético e um exemplo com JavaFX

Saindo do labirinto usando algoritmo genético




Um dos tópicos mais fascinantes no mundo da ciência da computação é Inteligência Artificial (IA). Uma sub-divisão no mundo da inteligência artificial são aqueles algoritmos que são baseados na natureza e nesse grupo temos os Algoritmos Genéticos.


Algoritmos Genéticos



Eu não irei me aprofundar nesse tópico, mas há ótimos materiais na internet.  A ideia geral é um algoritmo que leve em conta, dado um indíviduo, ele:

  • Tenha variação genética em diversos indivíduos (organismos também se aplica aqui);
  • Possa se reprodução e levar o código genético para suas gerações;
  • A cada reprodução haja ligeiras variações genéticas;
  • Uma "nota" para saber quão aquele indíviduo está adaptado ao ambiente atual.

Isso tudo é parte da teoria mais que comprovada de Darwin. O nome "teoria" confunde algumas pessoas e isso é incrível, acham que por ser uma teoria, é algo não confiável, mas interessantemente todas as evidências validam essa teoria desde que ela foi publicada! Sobre IA e Evolução, Pirulla fala um pouco disso no vídeo abaixo.



Para saber mais sugiro a página da Wikipédia sobre o assunto e o vídeo de uma aula do MIT e, de novo, um vídeo do Shiffman.







Algoritmos genéticos usando Java


Para colocar isso em prática usando em Java você pode desenvolver o seu próprio mini framework com DNA, Genes, cromossomos, algoritmos de mutação ou cruzamento e algoritmos de seleção natural, mas pra que reinventar a roda? No mundo Java temos algumas bibliotecas já conhecidas nesse meio, destaco a JGAP, um pouco antiga, e a moderna Jenetics, que usa Java 8 e os novos conceitos como Lambda, Method Reference, Stream, etc. O guia do usuário da API Jenetics é muito bom, cobre quase todas as classes que são usadas durante a programação. Mas ainda senti falta de exemplos mais claros, por isso, antes de tentar algo visual com JavaFX, eu criei 3 pequenas aplicações.


Seleciona o conjunto de double que tem a maior soma de algarismos; Esse é um exemplo besta, mas que mostra algumas classes importantes da API. A ideia é: dado um conjunto de double, qual tem a maior soma dos algarismos? Veja o código.
CODE

A saída é algo assim:

[[[85],[23],[62]]], sum 26
[[[42],[5],[53]]], sum 19
[[[4],[82],[14]]], sum 19
[[[17],[99],[41]]], sum 31
[[[32],[16],[23]]], sum 17
[[[15],[85],[38]]], sum 30
[[[54],[30],[51]]], sum 18
[[[31],[20],[76]]], sum 19
[[[88],[63],[69]]], sum 40
[[[52],[11],[6]]], sum 15
 (Um monte de passo intermediário)
[[[88],[97],[97]]], sum 48
[[[88],[97],[97]]], sum 48
[[[88],[29],[25]]], sum 34
[[[88],[97],[95]]], sum 46
[[[88],[97],[97]]], sum 48
Selected: [[[88],[97],[97]]]. Sum: 48


Veja que podemos resolver ele ser usar algoritmo genético, mas no código acima você pode começar a entender a pegada da API: Cromossomos tem um conjunto de genes, os genes são os objetos reais da sua aplicação (um número, uma String, um objeto do tipo pessoa...), genotype é o conjunto de cromossomos e criamos dois métodos importantes: um gera valores para serem trabalhados pela API (no exemplo acima usamos um cromossomo da própria API e ele tem o método pra gerar: Genotype.of(LongChromosome.of(1, 100, 3));) e o método que recebe o Genotype para que você possa trabalhar nele e retornar um ranking ou um número que indica quanto aquele genotype está adaptado ao ambiente (ver o método fitness).


Escrevendo uma frase: Se você conseguir 1 milhão de macacos e falar pra eles darem tapas no teclado de 1 milhão de computadores, qual seria a chance desse texto sair uma música da banda Queen? Raras, muito raras. Um programa com algoritmo genético pode chegar a esse resultado muito mais rápido e é claro que esse é somente outro exemplo. Veja abaixo um programa com Jenetics que consegue escrever uma frase que você escrever usando evolução:




Escape do Labirinto: Esse é um exemplo um pouco mais elaborado. Nele temos um pequeno labirinto gerado e a função do algoritmo genético é evoluir o conjunto inicial de direções do labirinto para encontrar uma saída. Bem, esse código é um pouco extenso, assim peço para vocês verem no meu github. A ideia é ter genes que são customizados, do tipo Direction  e esses genes são uma possível saída para o labirinto, representado pela classe Maze. Incrivelmente, com algoritmo genético, as direções iniciais são mutadas de forma que conseguem encontrar uma saída do labirinto! Vejam uma tela:



Como esse é um blog sobre JavaFX, foi criada uma aplicação que desenha o labirinto e permite que você teste parâmetros para rodar o algoritmo! O código dele também é extenso e ninguém vai ler um blog com dezenas de linhas de código! Então, caso queiram estudar mais, aqui vão os passos para executar a aplicação (precisa de Maven e Java 8):


$ mvn clean package exec:java -Dexec.mainClass=org.fxapps.genetics.mazefx.MazeFXApp

O resultado pode ser visto no vídeo abaixo:

30 de dez. de 2014

[Especial] Executando sua aplicação JavaFX 2.2 para Android

Olá Pessoal essa é uma postagem especial sobre como portar sua aplicação JavaFX para dispositivos Android!
Há um projeto do Johan Vos para trazer o suporte do JavaFX para o Android e iOs chamado JavaFX Ports e foi o destaque do JavaOne de 2014. O site contém todas as informações para transformar sua aplicação JavaFX 2.2 em uma app para Android,  no entanto, o mesmo está em inglês.
Felizmente, nosso amigo Bruno de Oliveira, que tem um livro sobre JavaFX publicado na casa do código, fez um vídeo ensinando passo-a-passo como colocar sua aplicação JavaFX no Android, confiram:


4 de ago. de 2014

Desenhando livremente com Canvas e o ColorPicker

Mostramos como desenhar formas geométricas com as classes que herdam de Shape. Essas formas, no entanto, ficam como nós separados no JavaFX. Como faremos se quisermos somente desenhar formas geométricas, textos e outras coisas livremente? Para isso temos o Canvas, uma classe muito interessante para desenharmos livremente!

Canvas

O canvas é simplesmente um nó que representa uma área para desenhar. Isso mesmo, nada mais do que isso. A mágica acontece com  a class GraphicContext, que pode ser adquirida assim que criamos um Canvas. Com o GraphicContext você pode desenhar formas geométricas, textos, imagens, mudar cor, aplicar efeito, etc. Veja um exemplo:



E para gerar isso usamos o seguinte código:

// O construtor do Canvas recebe a largura e a altura
Canvas canvas = new Canvas(300, 300);
// O objeto principal do Canvas é o GraphicsContext, que usamos para desenhar
GraphicsContext ctx = canvas.getGraphicsContext2D();
// estamos prontos para desenhar coisas! Vamos começar mudando a cor
ctx.setFill(Color.RED);
// podemos configurar uma fonte para os textos
ctx.setFont(Font.font("Serif", FontWeight.BOLD, 25));
// desenhando um texto, o primeiro param é o texto, os seguintes são a pos X e Y
ctx.fillText("Olá Mundo Canvas", 15, 30);
// podemos configurar efeitos e novamente trocar a cor
ctx.setFill(Color.BLUE);
ctx.setEffect(new BoxBlur());
ctx.fillText("Olá Mundo Canvas", 15, 60);
// agora vamos trocar o efeito, cor e desenhar um retângulo(x,y, largura, altura)
ctx.setEffect(new Reflection());
ctx.setFill(Color.AQUA);
ctx.fillRect(15, 90, 240, 20);
// ou um retângulo sem preenchimento
ctx.setStroke(Color.GREEN);
ctx.strokeRect(15, 135, 240, 30);
// ou circulos (forma oval)
ctx.setEffect(null);
ctx.setFill(Color.BROWN);
ctx.fillOval(15, 175, 90, 25);
ctx.setStroke(Color.YELLOWGREEN);
// ou formas ovais sem preenchimento
ctx.strokeOval(160, 175, 90, 25);
// ou até desenhar uns poligonos locos, usando diversos pontos X e Y
double xs[] = {15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270};
double ys[] = {205, 235, 250, 265, 205, 235, 205, 205, 235, 250, 265, 205, 235, 205, 205, 235, 250, 205};
ctx.setFill(Color.MAGENTA);
ctx.setEffect(new Reflection());
ctx.fillPolygon(xs, ys, 18);


Nesse momento, você deve estar se perguntando qual é a diferença do Canvas para uma aplicação JavaFX comum, já que podemos fazer tudo isso no JavaFX. Bem, o Canvas é uma tela de desenho, é ótimo para animações, jogos ou visualizações fantásticas. Já uma aplicação JavaFX, temos como maior objetivo objetos que se aninham hierarquicamente e são, no geral, estáticos, como essa página WEB. Desenhar essa página com o Canvas seria um buta dor de cabeça, já usar controles e outras características do JavaFX torna o serviço muito mais fácil.

Um mini paint com canvas

Nesse momento, já temos nossa missão cumprida! Pois apresentamos o componente que queríamos... No entanto, criamos uma aplicação um pouco mais complexa para demonstrar o poder desse componente: um micro paint. Vejam abaixo como é o nosso "paint":


Trocando de cor

Um controle até agora não abordado, mas que foi adicionado no Java 8, é o ColorPicker. Ele é um controle que herda de nó e pode ser adicionada à cena da aplicação e o objetivo é permitir o usuário escolher uma cor em uma paleta de cores! Assim, quando o usuário escolhe a cor, temos a chamada de um método onAction com e o valor do componente muda, podemos assim saber a cor escolhida. Veja o código completo no github.

Conclusão

Não julgue o Canvas só por essa postagem, ele é um dos componentes mais poderosos do JavaFX!
* Código no Github

18 de jul. de 2014

Adicionando estilo à sua aplicação com CSS

Até o momento nesse blog fizemos aplicações e deixamos a "cara" delas a padrão que vem com o JavaFX, ou seja, não nos preocupamos em mudar a aparência das da nossa aplicação. Para fazer isso no JavaFX, não precisamos escrever código Java, mas sim conhecer CSS (Cascade Style Sheet), onde podemos declarativamente configurar a aparência de nossa aplicação.

O que é e o que pode ser feito com CSS?

Com o CSS do javaFX é possível adicionar efeitos, mudar cores, dimensionar e completamente trocar a aparência da aplicação.  É possível também definir a aparência quando o mouse fica sobre o elemento.
CSS é uma linguagem declarativa onde identificamos os elementos da nossa aplicação e em seguida definimos valores para as propriedades suportadas para aquele componente.
Essa tecnologia já é utilizada em páginas WEB e para o JavaFX todas as possibilidades de uso do CSS estão descritas em um completo guia de referência.

Como referênciar os componentes do JavaFX no CSS?

Os componentes javafx podem ter várias classes CSS que referenciamos para usarmos na declaração do CSS. Assim, no código Java falamos qual a classe daquele componente e no CSS referenciamos a classe com ponto(".").  Também podemos dar um id para nosso componente e referenciar a classe dele usando cerquilha ("#"). Note que o ID deve ser único, já a classe pode ser aplicada a diversos nós.

Como carregar CSS no JavaFX?

O CSS pode ficar em um arquivo separado e ser carregado na Scene da aplicação ou podemos adicionar estilo a qualquer classe que estenda de nó (todas as classes de uma cena no JavaFX) usando o método setStyle. 

Exemplo

Criamos a seguinte aplicação de exemplo para que você possa ver o que abordamos anteriormente na prática.



Note que a aplicação está diferente. Isso é por que eu carreguei o arquivo app.css na cena:

cena.getStylesheets().add("app.css");

Esse arquivo configura o estilo raiz de toda a aplicação, veja o conteúdo:

.root{
    -fx-base: darkblue;
    -fx-background: lightblue;
}
.button {
    -fx-font-weight: bold;
    -fx-font-size: 15px;
}

.label {
    -fx-font-style: italic;
    -fx-font-size: 9px;
    -fx-text-fill: darkgreen;
}

.titulo {
    -fx-font-style: normal;
    -fx-font-weight: bolder;
    -fx-font-size: 30px;
    -fx-alignment: center;
}

Também temos contéudos para o label  lblTitulo que têm a classe titulo, que referenciamos para modificar o estilo:

No código Java:
 lblTitulo.getStyleClass().add("titulo");

No CSS:
.titulo {
    -fx-font-style: normal;
    -fx-font-weight: bolder;
    -fx-font-size: 30px;
    -fx-alignment: center;
}

Notem que alguns componentes já tem uma classe usado pelo próprio JavaFX, mas que você pode modificar como quiser. No lado esquerdo podemos adicionar o CSS que queremos e ao apertar o botão, esse CSS é aplicação no Text do lado direito. 

btnAplicar.setOnAction( event -> {
    txtAlvo.setStyle(txtCSS.getText());
});



Veja o código inteiro da nossa aplicação abaixo:

// imports omitidos
public class TesteCSS extends Application {

 String txt = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc porta erat id lectus interdum, a pharetra est luctus. Nulla interdum convallis molestie. In hac habitasse platea dictumst. Ut ullamcorper ultricies viverra. Quisque blandit libero in ante sagittis sagittis. Ut gravida nibh quis justo sodales rutrum. Fusce euismod diam diam, vitae vulputate urna placerat vel. ";
 
 public void start(Stage s) {
  // declarações
  BorderPane raiz = new BorderPane();
  HBox pnlCentro = new HBox(50);
  VBox vbEsquerda = new VBox(10);
  VBox vbDireita = new VBox(10);
  Button btnAplicar = new Button("Aplicar CSS");
  TextArea txtCSS = new TextArea();
  Text txtAlvo = new Text(txt);
  Label lblTitulo = new Label("Testando CSS");
  Scene cena = new Scene(raiz, 800, 250);

  // configurando Layout e adicionando componentes
  vbEsquerda.getChildren().addAll(new Label("Entre o CSS aqui"), txtCSS);
  vbDireita.getChildren().addAll(new Label("O texto Alvo"), txtAlvo);

  pnlCentro.getChildren().addAll(vbEsquerda, btnAplicar, vbDireita);
  pnlCentro.setAlignment(Pos.CENTER);

  raiz.setCenter(pnlCentro);
  raiz.setTop(lblTitulo);
  BorderPane.setAlignment(lblTitulo, Pos.CENTER); 

  txtCSS.setMinWidth(350);
  txtAlvo.setWrappingWidth(220);
  btnAplicar.setMinWidth(120);
  btnAplicar.setOnAction( event -> {
   txtAlvo.setStyle(txtCSS.getText());
  });
  // configuramos classes para os nossos labels especiais 
  lblTitulo.getStyleClass().add("titulo");
  // informamos o arquivo principal de CSS 
  cena.getStylesheets().add("app.css");
  s.setScene(cena);
  s.setTitle("Teste de CSS do JavaFX");
  s.show();
 }
}

Como fica se quisermos aplicar CSS:


Conclusão

Nesse artigo mostramos como é fácil mudar a aparência de nossas aplicaçõe usando JavaFX.



25 de jun. de 2014

[Especial] Outra app da Copa do Mundo... Usando JavaFX, FXML, Javascript e CSS

Olá pessoal, essa é uma postagem especial da copa do mundo onde faço uma tradução da minha postagem no blog fxapps.blogspot.com

Outra app da Copa do Mundo... Usando JavaFX, FXML, Javascript e CSS

A  Copa do mundo Brasil está acontecendo! É empolgante ver pessoas de todas as partes do mundo visitando nosso pais. Hoje eu decidi criar outra app para a Copa do Mundo, usando JavaFX, mas dessa vez eu não irei escrever nenhum código Java.
É uma aplicação muito simples para visualizar todas as partidas da copa do mundo e quando você clica em um jogo, você tem detalhes do mesmo. Eu gastei menos de 3 horas trabalhando no "core" da aplicação e algumas horas mais trabalhando nos detalhes.

Adquirindo os recursos para criar a aplicação

Recursos quer dizer imagens and para adquiri elas eu baixei todas as imagens de bandeiras do site da Fifa. Fiz um pequeno e fácil scrapping. Note que todas as imagens seguem o seguinte padrão de URL: http://img.fifa.com/images/flags/4/{CODE}.png. Então, para baixar todas as bandeiras, fiz o seguinte script python:

import urllib2
codes = open('countries_codes.txt', 'r')
for line in codes:
        code = line.replace('\n', '').lower() + '.png'
        img_url = 'http://img.fifa.com/images/flags/4/' + code
        print img_url
        req = urllib2.Request(img_url)
        response = urllib2.urlopen(req)
        img = response.read()
        f = open(code, 'w')
        f.write(img)

Também utilizei a seguinte imagem como uma inspiração para nossa aplicação:


A view da aplicação

A view foi inteiramente criada no Scene Builder e foi dado estilos e id para os componentes da view, então, do Javascript nós podemos destacar algumas partes de acordo com as informações da copa.


Temos todos os jogos mostrados na aplicação e quando o usuários clica em um jogo, os detalhes do mesmo são mostrados em um painel:


O estilo da aplicação

Para mudarmos a aplicação para termos as cores do Brasil, usamos um simples arquivo CSS que também troca a aparência da partida quando passamos sobre ela:

.root{
        -fx-base: CornflowerBlue;
        -fx-background: rgb(227,231,239);
}
.TitledPane{
        -fx-text-fill: FIREBRICK;
}
#match_details{
        -fx-background-color: rgb(177,174,218);
}
.match:hover{
        -fx-font: bold 12pt "Calibri";
        -fx-effect: dropshadow(three-pass-box , blue, 20, 0.4 , 0 , 0 );
        -fx-cursor: hand;
}

A lógica

Como essa é uma aplicação temporal, não precisamos criar classes de modelo para representar os dados do jogo, então usamos somente Javascript para escrever a lógica da aplicação!
Uma boa alma raspou os dados da FIFA e disponibiliza eles em JSON. Nós lemos esse JSON e basicamente preenchemos a view com os dados que nele vem. Notem que para cada partida eu dei um ID(isso foi chato bagario) e do JSON que peguei, eu preencho os dados. Veja:

var matches = downloadMatchesInfo()
...
function downloadMatchesInfo(){
        print("Trying to download the matches information.........")
        var out, scanner
        try{
                var urlStream = new java.net.URL(MATCHES_DATA_URL).openStream()
                scanner = new java.util.Scanner(urlStream, "UTF-8")
                // TODO: save the latest downloaded JSON
        }catch(e){
                print("Couldn't download the updated information, using a cached one.....")
                scanner = new java.util.Scanner(new java.io.File(CACHED_DATA_URL), "UTF-8")
    
        }    
        scanner.useDelimiter("\\A")
        out = scanner.next();
        scanner.close();
        return eval(out);
}

Usando a função eval, transformamos a nossa String de resposta em um object Javascript para que possamos acessar os dados JSON diretamente. Para entender melhor, veja como as partidas são preenchidas:

function fillMatch(match){
        var viewMatch = $STAGE.scene.lookup("#match_" + match.match_number)
        if(viewMatch && match.home_team.country){
                viewMatch.children[0].image = getImg(match.away_team.code)
                viewMatch.children[1].text = match.status == "future"? "_": match.home_team.goals;
                viewMatch.children[3].text = match.status == "future"? "_": match.away_team.goals;
                viewMatch.children[4].image = getImg(match.home_team.code)
        }
        viewMatch.onMouseClicked = function(e){
                fillMatchDetails(match)
        }
}

function getImg(code){
        var imgUrl = code?"./images/teams/" + code.toLowerCase() + ".png":"./images/no_team.png"
        if(!imgCache[imgUrl])
                imgCache[imgUrl] = new javafx.scene.image.Image(new java.io.FileInputStream(imgUrl))
        return imgCache[imgUrl]

}


Você pode ver no código acima como é fácil usar estruturas do Javascript em um código que lida com bibliotecas Java(veja a variável de cache de imagens chamada imgCache). Notem que quando o usuário clica em uma partida, registramos um listener para preencher os dados da partida em um painel central:

function fillMatchDetails(match){
        var s = $STAGE.scene;
        detailsTransition.playFromStart()
        var notPlayedScore = match.status == "completed"?"0":"_"
        s.lookup("#match_home_team").image = getImg(match.home_team.code)
        s.lookup("#match_away_team").image = getImg(match.away_team.code)
        s.lookup("#match_home_score").text = match.home_team.goals?match.home_team.goals:notPlayedScore
        s.lookup("#match_away_score").text = match.away_team.goals?match.away_team.goals:notPlayedScore
        s.lookup("#match_status").text = "Match " + match.status
        s.lookup("#match_time").text =  match.datetime.substring(0, 16)
        s.lookup("#match_location").text =  match.location
}


Por fim, vejam que invés de injetar os componentes em uma classe controller, decidimos pegar os elementos por ID usando o método lookup da Scene.

Rodando a aplicação

A aplicação não é compilada, é interpretada! Para rodar ela, você simplesmente precisa ter Java 8 instalado e no seu PATH assim você pode rodar a aplicação jjs para rodar a aplicação. Como o código está no github, você pode clonar it e já executar:

$ git clone https://github.com/jesuino/another-world-cup-app.git
$ cd another-world-cup-app
$ jjs -fx app.js
Você também pode editar o arquivo run.sh para configurar a variável JAVA_HOME e fazer o arquivo executável para rodar nossa app:


$ chmod +x run.sh
$ ./run.sh
Se você estiver no windows, minha namorada Luana testou a aplicação nesse "sistema operacional" e ela simplesmente criou um arquivo chamado run.bat com o seguinte conteúdo:
"C:\Program Files\Java\jre8\bin\jjs" -fx app.js


Note que você deve mudar o conteúdo desse arquivo de acordo com sua instalação.

Conclusão

Como você pode ver, é muito fácil criar aplicações JavaFX e não precisamos sequer escrever código Java! Usamos Javascript para ler o JSON e interagir com a view, o que se mostrou uma ótima abordagem, já que não precisamos usar nenhuma biblioteca de terceiros para lidar com o "parsing" de JSON.
Também ensinei minha namorada como rodar e mudar a aparência da aplicação e ela não é uma programadora Java. Isso mostra como aplicações JavaFX são acessíveis a todos os programadores.

A nossa aplicação final:



26 de mai. de 2014

Adicionando efeitos à sua aplicação

Muitos efeitos vêm no JavaFX prontos para uso na sua aplicação!  Nessa postagem vamos falar e demonstar os efeitos mais famosos da biblioteca gráfica do Java.

A API de efeitos

Conforme já falamos aqui, a classe nó tem um método chamado setEffect que aceita um parâmetro de tipo que herda da classe abstrata javafx.scene.effect.Effect. Essa classe é base de todos os efeitos que temos na API do JavaFX. Lembrando que por ser um nó, qualquer coisa em uma cena JavaFX pode receber efeitos: QUALQUER COISA. Algumas classes que herdam de Effect são listadas abaixo.

Uma aplicação de exemplo

Criamos uma aplicação de exemplo para testar os efeitos mais famosos do JavaFX em uma imagem. O código dessa aplicação está no github. A ideia da aplicação é que você possa ler a documentação e explorar os efeitos por sí próprio.



24 de abr. de 2014

Usando Tabelas com JavaFX: TableView

Um dos controles mais utilizados em aplicações cotidianas é a Tabela. Com controles que permitam visualizar dados em forma de tabelas podemos mostrar: lista de funcionários, de produtos, dados já ordenados em planilhas, informações diversas que vêm de algum servidor.
Nesse aspecto, estamos bem "servidos" com o TableView do JavaFX. A TableView, juntamente com a classe TableColumn, facilita visualizações de dados em uma aplicação JavaFX.
Nesse artigo, iremos mostrar o básico sobre criação de tabelas usando JavaFX.

Visão geral da classe TableView 

TableView é mais um controle de interface. Para começarmos falando dela, veja a seguinte imagem:



Uma tabela tem colunas e linhas. Quando configuramos as colunas de uma TableView, temos que também dizer como cada coluna vai representar os dados da tabela.

Itens

Os dados devem ser do tipo da declaração da tabela. Por exemplo, se declaramos uma tabela usando:

TableView<Pessoa> tabela = new TableView<>();

A tabela só irá aceitar dados do tipo Pessoa: 

List<Pessoa> pessoas = ....
tabela.setItems(FXCollections.observableArrayList(pessoas));

Caso você tente inserir dados de outro tipo, simplesmente você terá um erro de compilação.

Colunas

As colunas são definidades pela classe TableColumn e devem saber lidar com cada linha da tabela. Isso é feito através de fábricas de células, que são classes que recebem cada item da tabela e retornam uma célula da tabela. A fábrica você deve fornecer ou usar algumas colunas que já sabem fabricar as células de um tipo já conhecido. Veja um exemplo onde criamos colunas para as propriedades nome, idade e email de uma pessoa:

TableColumn<Pessoa, String> colunaNome = new TableColumn<>("Nome");
TableColumn<Pessoa, String> colunaIdade = new TableColumn<>("Idade");
TableColumn<Pessoa, String> colunaEmail = new TableColumn<>("E-mail");
tabela.getColumns().addAll(colunaNome, colunaIdade, colunaEmail);

Por exemplo, para acessar as propriedades do objeto Pessoa, podemos usar uma fábrica pronta, a PropertyValueFactory. Abaixo criamos as fábricas para as propriedades (atributos) da classe pessoa, note a String que ele recebe no construtor que é o nome da propriedade que declaramos na classe:

colunaNome.setCellValueFactory(new PropertyValueFactory<>("nome"));
colunaIdade.setCellValueFactory(new PropertyValueFactory<>("idade"));
colunaEmail.setCellValueFactory(new PropertyValueFactory<>("email"));

Um exemplo completo de uso da TableView

Abaixo temos um código simples que mostra como mostrar uma lista de pessoas em uma TableView. Veja que não é nada sofisticado, mas com esse código, você já estará apto a construir suas próprias aplicações que usam tabelas.

import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

/**
 *
 * @author william
 */
public class Post13Tabelas extends Application {

    @Override
    public void start(Stage primaryStage) {
        List pessoas = Arrays.asList(
                new Pessoa("William", 32, "william@email.com"),
                new Pessoa("Luana", 17, "luana@email.com"),
                new Pessoa("Maria", 12, "maria@email.com"),
                new Pessoa("João", 15, "joao@email.com"),
                new Pessoa("Antônio", 28, "antonio@email.com"),
                new Pessoa("Teles", 17, "teles@email.com"),
                new Pessoa("Eduan", 30, "eduan@email.com"),
                new Pessoa("Gabu", 22, "gabu@email.com")
        );

        TableView tabela = new TableView<>();
        TableColumn colunaNome = new TableColumn<>("Nome");
        TableColumn colunaIdade = new TableColumn<>("Idade");
        TableColumn colunaEmail = new TableColumn<>("E-mail");

        colunaNome.setCellValueFactory(new PropertyValueFactory<>("nome"));
        colunaIdade.setCellValueFactory(new PropertyValueFactory<>("idade"));
        colunaEmail.setCellValueFactory(new PropertyValueFactory<>("email"));

        tabela.setItems(FXCollections.observableArrayList(pessoas));
        tabela.getColumns().addAll(colunaNome, colunaIdade, colunaEmail);
        
        primaryStage.setScene(new Scene(tabela));
        primaryStage.setWidth(250);
        primaryStage.setHeight(300);
        primaryStage.setTitle("Tabelas no JavaFX");
        primaryStage.show();
    }

    public static class Pessoa {

        private String nome;
        private int idade;
        private String email;

        public Pessoa(String nome, int idade, String email) {
            this.nome = nome;
            this.idade = idade;
            this.email = email;
        }

        public String getNome() {
            return nome;
        }

        public void setNome(String nome) {
            this.nome = nome;
        }

        public int getIdade() {
            return idade;
        }

        public void setIdade(int idade) {
            this.idade = idade;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

    }
}


Conclusão

Nesse breve artigo nós mostramos como criar tabelas em JavaFX. Claro que o tópico é extenso e podemos voltar ao tópico no futuro.

Nosso código agora é usando Java 8 e Netbeans 8.  Veja o código no github.

15 de abr. de 2014

Escrevendo aplicações JavaFX 8 usando Javascript

Uma das novidades mais legais do Java 8 é a nova engine javascript chamada "Nashorn". Com ela podemos escrever aplicações inteiras que usam JavaFX com a linguagem Javascript.
Hoje vamos mostrar aplicações simples para introduzir e apresentar esse conceito. Lembre que estamos usando a mais nova versão do Java, o Java 8.

* É requerido ter feito pelo menos o "Olá mundo" do JavaFX para seguir nessa postagem

Carregando javascript a partir do Java

Através de sua aplicação, você pode colocar variáveis visíveis para o Javascript e do seu código Java chamar Javascript. O código abaixo é uma aplicação JavaFX que usa a engine para colocar o Stage principal no escopo do script Javascript e então chamamos um script do nosso sistema de arquivos com o resto do código da view:

import javafx.application.Application;
import javafx.stage.Stage;
import javax.script.*;
import java.io.FileReader;

public class CarregaJS extends Application{

        @Override
        public void start(Stage stage){
                try{
                        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
                        engine.put("stage", stage);
                        engine.eval(new FileReader("/opt/helloJavaFX.js"));
                }catch(Exception e){ 
                        e.printStackTrace();
                }   
        }   
 }


Veja o uso da classe ScriptEngineManager para carregar a engine do Nashorn. Logo, carregamos o conteúdo do arquivo em um FileReader e interpretamos o script usando o método eval, mas antes disso colocamos o objeto stage no escopo do Javascript. Veja como ficou nosso script:


var txtOla = new javafx.scene.control.Label(">> Olá Mundo! <<")
txtOla.font = new javafx.scene.text.Font(50)
stage.scene = new javafx.scene.Scene(txtOla)
stage.width = 500 
stage.title = "Olá JavaFX + Javascript"
stage.show()


Note que se você quiser alterar a view, você simplesmente pode modificar o script sem ter que recompilar o seu código Java! Resultado:


Carregando scripts usando a linha de comando

É possível usar a ferramenta jjs e escrever somente javascript. Para JavaFX especificamente, há um parâmetro que, quando usado, o Nashorn irá colocar uma variável chamada $STAGE para ser usada no seu script. Ela representa o stage principal da sua aplicação. Veja um "Olá Mundo" só com Javascript:

var txtOla = new javafx.scene.control.Label(">> Olá Mundo! <<")
txtOla.font = new javafx.scene.text.Font(50)
$STAGE.scene = new javafx.scene.Scene(txtOla)
$STAGE.width = 500 
$STAGE.title = "Olá JavaFX + Javascript"
$STAGE.show()


Para executar ele, tenha o JDK 8 instalado e no seu "path", ou navegue até o diretório $JAVA_HOME/bin/ e encontre o executável do jjs e execute o seguinte comando:

$ jjs -fx helloJavaFX.js

Esse script produz o mesmo resultado do código anterior.

Conclusão

Com Java 8 temos uma nova alternativa para escrever aplicações. Claro que o "Olá Mundo" é só o começo, mas teríamos que explorar a nova engine e sua compatibilidade com as APIs Java para construirmos grandes aplicações.
Caso você não queira escrever Java, nem Javascript, lembre-se que você poderá usar FXML e a ferramenta Scene Builder.

O código Javascript do Olá mundo está 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!