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!

Nenhum comentário:

Postar um comentário