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

29 de nov. de 2015

Buscando nós filhos de um Node usando seletores CSS

Nessa postagem vamos fala sobre como retornar os filhos de um classe Node.

Como já falamos aqui, tudo que está em uma aplicação JavaFX é um Node (nó): botões, labels, tabelas, organizadores de leiaute e por aí vai. Alguns desses nodes têm filhos. É o caso do Group, VBox, HBox e outros organizadores de leiaute.

Uma dúvida comum, inclusive perguntada nessa postagem do JavaFree, é sobre como podemos buscar os elementos filhos sem sair fazendo for  e ir lendo elemento por elemento, testar seus atributos e assim achar o que procura. Há outras formas! E a melhor forma é usando o método lookup e lookupAll. Vamos falar sobre eles hoje!

Seletores CSS


Para usar os métodos acima, devemos usar seletores CSS através de uma String. Para entender melhor, vejam esse artigo do W3 Schools e a ferramenta que eles indicam para testar os seletores. 
Basicamente os selectores são formas de buscar alguma coisa usando uma linguagem simples de representação dos elementos. Por exemplo, se quisermos buscar algum nó pelo seu ID, usamos #ID, onde ID é o ID que se pretende buscar. Há também possibilidades de buscar pela classe do elemento, por valores de seus atributos e por aí vai. Sugiro a leitura do artigo da W3 Schools para melhor entender ou buscar on google alguma fonte em português (o motivo de "linkar" W3 Schools é a confiabilidade e estabilidade do recurso).
O fato é que o seletor CSS muitas vezes retorna vários resultados, pois podemos usar coringas (símbolos especiais que representam um ou mais elementos, como o "*", que representa tudo) ou há vários Nodes que batem com aquela busca. 

lookup e lookupAll


Esse são os dois métodos da classe node que podemos usar para buscar seus filhinhos. A principal diferença entre ele é que o lookup retorna sempre um resultado que corresponde aquela busca e o lookupAll retorna todos os elementos que correspondem a busca em um java.util.Set(uma collection do Java que não permite que os elementos se repitam, sendo sempre únicos). Se nenhum nó filho corresponde à busca usando lookup, o retorno é nulo, já com o lookupAll, o retorno é um Set vazio.

Muito papo né? Vamos fazer um código de exemplo!


Exemplo usando lookupAll


Agora vamos para o nosso código que é uma "aplicaçãozinha" que permite fazer a busca de Labels que estão em uma VBox. Se um ou mais labels correspondem a busca, eles ficam grande, se nenhum corresponder a busca, a gente informa usando um dialog. Vejam uma imagem da nossa APP:




Agora vejam o código no github e em seguida uma explicação. Notem o uso de Stream, assim sugerimos fortemente que leiam a série de artigos sobre Java 8 de um colega aí ;)

Por fim, eu gravei  um vídeo rapidão.




Conclusão


Mostramos o uso dos métodos lookup e lookupAll da classe node. É muito fácil fazer busca de elementos no JavaFX :-) 

11 de fev. de 2014

A classe Node e seus principais atributos: Aplicação de exemplo

Olá Pessoal,

Na última postagem nós falamos da classe Node do JavaFX. Ela é a classe chave de toda a arquitetura do JavaFX 2 e aprendendo ela de forma efetiva, você vai ficar apto a desenvolver aplicações mais rapidamente!
A nossa aplicação de exemplo usa um nó como algo e o nó pode sofrer diversas modificações. Veja abaixo um screenshot.



O ponto maior dessa aplicação é demonstrar que existem propriedades comuns que são aplicáveis a qualquer classe que está em uma aplicação JavaFX. Logo, no painel à esquerda, notem diversos controles. Eles irão modificar os mais famosos atributos do nó.

A mágica está em trocar o controle para mudar os seus atributos sem mexer em nenhuma outra parte do código. Em termos práticos, você troca de um texto para um botão e os controles do lado esquerdo continuam funcionando e são aplicados sem qualquer outra modificação no código. Em seguida, podemos trocar o botão por qualquer outro controle: figuras, um vídeo, controles, etc... Veja como isso é feito nas linhas de código que selecionei abaixo:

// aqui criamos o nó
Node alvo = criaNo();

// usamos ele em diversos pontos
// aqui vamos "amarrar" as propriedades dos controles da tela com as
// propriedades do nó
sldEscalaX.valueProperty().bindBidirectional(alvo.scaleXProperty());
sldEscalaY.valueProperty().bindBidirectional(alvo.scaleYProperty());
sldRotacao.valueProperty().bindBidirectional(alvo.rotateProperty());

// um listener para os botões que movimentam o nó
EventHandler cliqueBotoesMovimento = new EventHandler() {

 @Override
 public void handle(ActionEvent evt) {
  // de acordo com o botão clicado vamos manipular nosso nó
  Object botaoClicado = evt.getSource();
  if (botaoClicado == btnDecrementaX) {
   alvo.setTranslateX(alvo.getTranslateX() - 1);
  } else if (botaoClicado == btnIncrementaX) {
   alvo.setTranslateX(alvo.getTranslateX() + 1);
  } else if (botaoClicado == btnDecrementaY) {
   alvo.setTranslateY(alvo.getTranslateY() - 1);
  } else if (botaoClicado == btnIncrementaY) {
   alvo.setTranslateY(alvo.getTranslateY() + 1);
  }
 }
};
// muda o efeito
cbEfeitos.getSelectionModel().selectedItemProperty()
 .addListener(new ChangeListener() {
  @Override
  public void changed(
    ObservableValue valor,
    String antigo, String novo) {
   switch (valor.getValue().toString()) {
   case BORRAR:
    alvo.setEffect(efeitoBorrar);
    break;
   case SOMBRA:
    alvo.setEffect(efeitoSombra);
    break;
   case REFLEXAO:
    alvo.setEffect(efeitoReflexao);
    break;
   case NENHUM:
    alvo.setEffect(null);
    break;
   default:
    break;
   }
  }
 });

Se você quiser fazer isso, pegue o código no github importe no Eclipe e localize o seguinte método:

private Node criaNo() {
 // Modifique esse método para criar o nó que você quiser e retornar! O
 // programa vai funcionar independente do nó que você cira
 Text texto = new Text("\\o/ exemplo \\o/  ");
 texto.setFont(new Font(40));

 Rectangle rect = new Rectangle(200, 150);
 rect.setFill(Color.RED);

 HBox caixinha = new HBox(20);
 caixinha.getChildren().addAll(new Rectangle(80, 60), new Circle(30),
   new Button("Um botão de teste"), new Text("um texto"));
 caixinha.setAlignment(Pos.CENTER);

 // crie seus próprios nós e retorne aqui!
 return texto;
}

Veja que há outros possíveis nós que estão no código acima. Use um deles e rode o programa novamente, aí pode brincar com os controles do lado esquerdo e verá que eles se aplicam da mesma forma que o texto anterior se aplicava!

Um ponto interessante desse programa é que eu criei um "handler" genérico para todos os eventos do mouse! Mais detalhes sobre isso pode ser encontrado nesse artigo(em inglês) e mais sobre tratatamento de eventos vocês podem ver nesse artigo aqui no nosso blog.
Outro ponto, e que vamos explicar futuramente, é o uso de Binding. É uma técnica para evitarmos muito código fazer com que duas propriedades tem o mesmo valor e sejam atualizados quando elas mudam o valor. No nosso caso alguns campos do nó alvo têm o seu valor alterado quando mexemos nos controles, veja:

sldEscalaX.valueProperty().bindBidirectional(alvo.scaleXProperty());
sldEscalaY.valueProperty().bindBidirectional(alvo.scaleYProperty());
sldRotacao.valueProperty().bindBidirectional(alvo.rotateProperty());

Há também o uso dos efeitos Reflection, DropShadow e BoxBlur, que vamos abordar futuramente!
Por final, fiz um vídeo usando esse programa para ilustrar melhor o que estou falando.


Divirta-se e avise se tiver qualquer dúvida!

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.