Primeiro baixe o SDK (baixe uma versão LTS).
No Netbeans, vá em Tools >> Libraries >> New Librarie e crie uma nova biblioteca com o nome JavaFX. Vá nas propriedades do objeto e em ClassPath adicione os JARs da pasta lib do JavaFX. Dê OK.
Para criar um projeto, vá normalmente em Projeto Java (não use a opção Java FX), e crie com classe principal. Adicione a Biblioteca JavaFX criada no ClassPath. Em Run, no ModulePath, faça o mesmo.
Em Compiling desmarque a opção Compiling on Save.
Na parte Run (não a de libraries), coloque em VM Options o código:
--module-path %JAVAFX% --add-modules javafx.controls,javafx.fxml
PS: Entre o controls e o segundo javafx, é vírgula, sem espaço. Na variável de ambiente JAVAFX coloque o caminho da pasta lib do JavaFX. Caso esteja em Linux ou Mac, use $JAVAFX
.
Crie a classe principal num pacote, caso não tenha criado, com esse código:
package testefx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class TesteFX extends Application {
@Override
public void start(Stage st) throws Exception {
Parent rt = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene sc = new Scene(rt);
st.setScene(sc);
st.show();
}
public static void main(String[] args) {
launch(args);
}
}
Adicione um arquivo novo, no mesmo pacote da classe principal, de JavaFX, um Empty FXML, com o nome FXMLDocument, marque a opção ControllerClass e Create New.
Para executar um programa já construído e compilado num Jar, use o comando:
java --module-path %JAVAFX% --add-modules javafx.controls,javafx.fxml -jar TesteFX.jar
Abra uma nova aplicação FXML do Java FX, e clique duas vezes no FXML para abrir o Scene Builder.
Para entendermos, vamos mexer no DocumentController, da seguinte forma:
public class FXMLDocumentController implements Initializable {
@FXML
private Label labelOlaMundo;
@FXML
private void acaoDoBotao(ActionEvent event) {
labelOlaMundo.setText("Olá, Mundo!");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
O que está abaixo do primeiro @FXML é um encapsulamento da classe do Java FX Label, e o que está abaixo do segundo é o método que estará fazendo o programa funcionar. Ambos podem ter os nomes alterados, só não mexa no conteúdo implementado (com @Override).
Lembrando que, caso o FXML e o document controller não forem criados, vá em FXML Vazio que tem a opção pra criar ambos.
No Scene Builder, apague o frame e crie um novo, indo em Anchor Pane, e nele coloque um label e um botão.
No botão, clique nele e vá em Code, e em On Action, coloque o nome da ação executada (no caso, acaoDoBotao), e o ID em fx:id. Altere também o nome do botão em Properties.
No label, clique neme e vá em Code, e coloque a id em fx:id (no caso, labelOlaMundo) e altere também o texto padrão em Properties.
Depois vá em File e em Save para salvar.
PS: Também podemos estilizar as cores, fontes e textos deles em Properties. E podemos ver o código do Controler pronto indo em View e em Show Samplers Controller Skeleton, dentro do Builder.
Lembrando que caso o programa não abra ao executar, vá no documento FXML e na tag Anchor Pane, coloque fx:controller="nomedopacotedoprojeto.FXMLDocumentController"
. Ou dentro o Scene, vá em Controller e Controller Class.
PS: Caso não queira que o aplicativo seja maximixado, coloque isso na classe principal java (com o nome do aplicativo). No mesmo local, podemos colocar um título:
stage.setScene(scene);
stage.setResizable(false);
stage.setTitle("Olá Mundo!");
stage.show();
Continuando o projeto anterior, vamos colocar um TextField e colocar em fx:id a id txtNome.
No DocumentController, colocaremos esse código, dentro da classe:
@FXML
private TextField txtNome;
PS: TextField, Button, Label e outros componentes precisam ser importados.
E no setText do label, basta colocar isso:
labelNome.setText(txtNome.getText());
Abra um novo projeto Java FX com FXML, clique no FXML e no Scene Builder, crie um Anchor Pane (não esqueça de especificar o document controller).
Adicione um Combobox (lista, tipo select) nele, e em code coloque a ID categorias. E pegue o código em view e Show Sample e coloque no controller, assim:
@FXML
private ComboBox<?> categorias;
No mesmo projeto, crie um novo pacote e uma nova classe java denominada Categoria, com esse código:
package model;
public class Categoria {
private int id;
private String nome;
public Categoria(int id, String nome) {
this.id = id;
this.nome = nome;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
E no controller, altere o ? das tags pelo nome da classe Categoria (importe o conteúdo que terá o mesmo nome do pacote seguido da classe), faça o mesmo com a lista e os arrays (importe tudo):
@FXML
private ComboBox<Categoria> categorias;
@FXML
private List<Categoria> cats = new ArrayList<>();
@FXML
private ObservableList<Categoria> obsCats;
Crie também a função:
public void carregarCategorias() {
Categoria categoria1 = new Categoria(1, "Bebidas");
Categoria categoria2 = new Categoria(2, "Comidas");
cats.add(categoria1);
cats.add(categoria2);
obsCats = FXCollections.observableArrayList(cats); // Importe
categorias.setItems(obsCats);
}
E dentro do initialize, basta apenas invocarmos o método usando carregarCategorias()
.
Veja o código completo abaixo:
public class FXMLDocumentController implements Initializable {
@FXML
private ComboBox<Categoria> categorias;
@FXML
private List<Categoria> cats = new ArrayList<>();
@FXML
private ObservableList<Categoria> obsCats;
@Override
public void initialize(URL url, ResourceBundle rb) {
carregarCategorias();
}
public void carregarCategorias() {
Categoria categoria1 = new Categoria(1, "Bebidas");
Categoria categoria2 = new Categoria(2, "Comidas");
cats.add(categoria1);
cats.add(categoria2);
obsCats = FXCollections.observableArrayList(cats); // Importe
categorias.setItems(obsCats);
}
}
Agora, copie a classe principal do mesmo projeto para o mesmo pacote, mas com outro nome, atenção para ver se não é necessário alterar o FXML do projeto.
Mas tem um porém, ele imprimirá na lista o nome do pacote, classe e hashcod, para resolver isso, basta colocar um método toString() para sobrepor o método original, na classe categoria:
@Override
public String toString() {
return getNome();
}
Crie uma nova aplicação Java FX com FXML. Clique no FXML para abrir o Scene Builder, e no Anchor Pane, coloque dois checkbox e um botão,
Coloque como exemplo, as checkbox com os títulos Java e PHP, e com os IDs referentes (por exemplo, cbJava e cbPHP).
No botão, que terá o texto "Pegar", coloque no Action "pegarValores". E no Show Samplers, dentro do Builder, pegue o valor gerado.
O código da classe é esse:
public class FXMLDocumentController {
@FXML
private CheckBox cbJava;
@FXML
private CheckBox cbPHP;
@FXML
private void pegarValores() {
System.out.println("Java: " + cbJava.selectedProperty().getValue());
System.out.println("PHP: " + cbPHP.selectedProperty().getValue());
}
@FXML
private void clicouBotao(ActionEvent event) {
pegarValores();
}
}
Abra uma nova aplicação Java FX com FXML e clique no FXML para abrir o Builder, nele coloque dois botões de rádio com os textos "Comidas" e "Bebidas", e um botão com pegar, de exemplo parecido com o anterior.
Um erro comum em criar botões, é o fato de que só pode selecionar um. Para que isso aconteça corretamente, vá em Properties de ambos e coloque o mesmo nome pra ambos em ToogleGroup (no caso, grupo), e no mesmo local, marque o Selected pra um deles, pra ficar marcado como padrão.
Coloque o nome pegarSelecionado pro On Action do botão. Depois volte no FXML controller e coloque esse código (não esqueça de importar RadioButton e ToggleGroup):
public class FXMLDocumentController implements Initializable {
@FXML
private ToggleGroup grupo; // Não esqueça de importar
@FXML
private void pegarSelecionado() {
RadioButton radio = (RadioButton)grupo.getSelectedToggle(); // Não esqueça de importar
System.out.println(radio.getText());
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
Dentro de um Anchor Pane, podemos colocar um HBox e um Vbox, e dentro deles podemos colocar elementos como botões.
A diferença é que no HBox, independente da posição, tudo será alinhado horizontalmente.
O Vbox funciona da mesma forma, só que alinha verticalmente.
O Stack Pane é usado para "desenhar" polígonos no Java FX, já que os conteúdos são emplihados um em cima do outro.
Para isso, use a opção shapes, do lado esquerdo do Scene Builder.
Tal como outros elementos, podemos mudar cores e outros atributos.
Por exemplo, podemos criar algo como uma bandeira do Japão.
Para criar um Border Pane, fazemos da mesma forma com o Anchor Pane, colocando-o no lugar dele.
O Border Pane permite "divisões" em regiões no frame, para dividirmos componentes do mesmo por espaço.
Abra uma aplicação Java FX com FXML, e abra o Builder dele, apague o Anchor Pane e crie o Border Pane.
Na parte TOP, podemos colocar um MenuBar, e nas outras cada um pode ter seu botão, por exemplo.
Outro tipo de painel é o Grid Pane, que é parecido com o Border Pane, mas ele tem uma "grade" com diversos setores, com colunas e linhas, que podem ser adicionadas.
Em cada um dos setores, podemos colocar por exemplo, textField e labels.
Podemos colocar também imagens no Java FX, para isso colocamos um objeto ImageView e nele colocamos o caminho da imagem.
Para ser compilado corretamente, a imagem deverá estar numa pasta dentro do mesmo projeto (podendo criar um pacote só pra elas no projeto).
Podemos também colocar um ícone no Java FX, crie um pacote com a imagem desejada, e coloque o caminho nela assim, no arquivo da classe principal:
stage.getIcons().add(new Image(getClass().getResourceAsStream("/images/nomedaimagem.png"))); // Importe javafx.scene.image.Image
PS: Isso deve ser colocado antes do método stage.show().