Ez csak a régi Java 8-hoz van:
Rendelkezésre áll:
Windowson az .msi fájl alapértelmezetten profilba telepszik.
A linuxos verzió telepítése:
dpkg -i SceneBuilder-19.0.0.deb
Az /opt könyvtárba telepszik.
sudo mkdir /usr/share/desktop-directories/
Nélküle a következő hibát kapjuk:
xdg-desktop-menu: No writable system menu directory found.
Bővítmény telepítése:
A parancs panelon keresztül konfiguráljuk. Gépeljük be:
Scene
Válasszuk a következőt:
Configure Scene Builder path
Keressük meg az előugró párbeszédablakban a futtatható SceneBuilder szerkesztőt.
Például:
/opt/scenebuilder
Amit ki kell választani:
/opt/scenebuilder/bin
Windows esetén, egy lehetséges útvonal:
c:\Users\janos\AppData\Local\SceneBuilder\
A következő bővítményre van szükség:
A bővítmény nem érhető el tárolóból. Ezért töltsük le innen:
Jobb oldalon találunk egy „Download Extension” linket.
Letöltés után, ha 1.0.1 verzónk van:
codium --install-extension bilalekrem.scenebuilderextension-1.0.1.vsix
A parancs panelon keresztül konfiguráljuk. Gépeljük be:
Scene
Válasszuk a következőt:
Configure Scene Builder path
Keressük meg az előugró párbeszédablakban a futtatható SceneBuilder szerkesztőt.
Amit ki kell választani:
/opt/scenebuilder/bin
Készítsünk egy üres állományt, például:
mainScene.fxml
vagy:
app.fxml
Az állományon jobb egér gomb, majd:
A következő sor szükséges az fxml fájl használatához.
Parent root = FXMLLoader.load(getClass().getResource("mainScene.fxml"));
Ezek után a Scene() konstruktorában megadjuk:
Scene scene1 = new Scene(root, 300, 250);
A teljes start() függvény:
@Override public void start(Stage primaryStage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("mainScene.fxml")); Scene scene1 = new Scene(root, 300, 250); primaryStage.setScene(scene1); primaryStage.show(); }
A kivételeket eldobtuk. A getResource() az IOException kivételt vált ki.
Eseménykezeléshez meg kell adni:
Ha a MainController könyvtárban van, például egy controllers könyvtárban:
controllers.MainController
Vegyük észre a (.) pont karaktert, a (/) perjel vagy a (\) visszaperjel karakter helyett.
Eseménykezelő az App.java fájlon belül:
@FXML protected void onClickMehetGomb(ActionEvent event) { System.out.println("Működik"); }
Ha akcióknak van egy célkomponense azt szerepeltetni kell a SceneBuilder Code részén, a fx:id mezőben, egy tetszőleges névvel:
Ugyanennek a névnek szerepelnie kell az osztályban, ahol hivatkozni szeretnénk rá, egy FXML annotációval:
@FXML private Text celfelirat;
Együtt az eseménykezelővel:
@FXML private Label celfelirat; @FXML protected void onClickMehetGomb(ActionEvent event) { celfelirat.setText("Működik"); }
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.stage.Stage; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Label; public class App extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("app.fxml")); Scene scene1 = new Scene(root, 300, 250); primaryStage.setScene(scene1); primaryStage.show(); } @FXML private Label celfelirat; @FXML protected void onClickMehetGomb(ActionEvent event) { celfelirat.setText("Működik"); } }
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.*?> <?import java.lang.*?> <?import javafx.scene.layout.*?> <VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="App"> <children> <Label fx:id="celfelirat" text="Első Scene Builder" /> <Button mnemonicParsing="false" onAction="#onClickMehetGomb" text="Mehet" /> </children> </VBox>
Adott egy projekt, ahol a kontroller külön osztályban van. A következő fájl és könyvtárszerkezet van:
app01/ |-lib/ |-src/ | |-controllers/ | | `-MainController.java | |-models/ | | `-MainModel.java | |-views/ | | `-MainScene.fxml | `-App.java `-README.md
A kontroller a controllers/MainController.java fájlban van. A nézet a mainScene.fxml fájlban.
Mivel írni akarjuk a TextField mezőt, adnunk kell egy fx:id azonosítót:
Megmondjuk a kontroller osztály nevét:
package controllers; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.TextField; import models.MainModel; public class MainController { MainModel mainModel; @FXML private TextField textfield1; public MainController() { this.mainModel = new MainModel(); } @FXML protected void onClickMehetGomb(ActionEvent event) { System.out.println("Működik"); Integer num = this.mainModel.getNum(); textfield1.setText(num.toString()); } }
package models; public class MainModel { public int getNum() { return 15; } }
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.*?> <?import java.lang.*?> <?import javafx.scene.control.*?> <VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.MainController"> <children> <Label text="Label" /> <TextField fx:id="textfield1" /> <Button mnemonicParsing="false" onAction="#onClickMehetGomb" text="Button" /> </children> </VBox>
import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class App extends Application { public static void main(String[] args) throws Exception { launch(args); } @Override public void start(Stage primaryStage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("views/MainScene.fxml")); Scene scene1 = new Scene(root, 300, 250); primaryStage.setScene(scene1); primaryStage.show(); } }
A Maven bekéri a verziót:
A VSCode feldob egy ablakot, van rajta egy [Open] gomb. A gombra kattintva a projekt megnyílik.
module com.example { requires javafx.controls; requires javafx.fxml; opens com.example to javafx.fxml; exports com.example; }
Hozzuk létre egy controllers könyvtárat, abban például egy MainController.java fájlt:
package com.example.controllers; public class MainController { }
Ha szeretnénk létrehozni egy controllers könyvtárat, amit a FXML-ben (SceneBuilder-ben) szeretnénk használni fel kell vennünk ebbe a fájlba:
module com.example { requires javafx.controls; requires javafx.fxml; opens com.example to javafx.fxml; opens com.example.controllers to javafx.fxml; exports com.example; }
Így beállítható a kontroller a SceneBuilder felületén:
com.example.controllers.MainController
Implementálni kell az Initializable interfészt:
public class UserController implements Initializable { }
Az egyes osztlopok beállítása:
@Override public void initialize( URL url, ResourceBundle rb ) { this.idcol.setCellValueFactory(new PropertyValueFactory<>("id")); this.usernamecol.setCellValueFactory(new PropertyValueFactory<>("username")); this.passwordcol.setCellValueFactory(new PropertyValueFactory<>("password")); this.admincol.setCellValueFactory(new PropertyValueFactory<>("admin")); this.enabledcol.setCellValueFactory(new PropertyValueFactory<>("enabled")); }
Teljeskód egy UserController.java fájlban:
package lan.zold; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Alert; import javafx.scene.control.CheckBox; import javafx.scene.control.PasswordField; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; public class UserController implements Initializable { @FXML private TextField username; @FXML private PasswordField password; @FXML private CheckBox admin; @FXML private CheckBox enabled; @FXML private TableView<Employee> usertable; @FXML private TableColumn<Employee, Integer> idcol; @FXML private TableColumn<Employee, String> usernamecol; @FXML private TableColumn<Employee, String> passwordcol; @FXML private TableColumn<Employee, Boolean> admincol; @FXML private TableColumn<Employee, Boolean> enabledcol; @Override public void initialize( URL url, ResourceBundle rb ) { this.idcol.setCellValueFactory(new PropertyValueFactory<>("id")); this.usernamecol.setCellValueFactory(new PropertyValueFactory<>("username")); this.passwordcol.setCellValueFactory(new PropertyValueFactory<>("password")); this.admincol.setCellValueFactory(new PropertyValueFactory<>("admin")); this.enabledcol.setCellValueFactory(new PropertyValueFactory<>("enabled")); } @FXML private void addUser() { if(this.username.getText().isEmpty() || this.password.getText().isEmpty()) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("Hiba!"); alert.setHeaderText("Hiba!"); alert.setContentText("A felhasználónév vagy a jelszó üres!"); alert.showAndWait(); return; } System.out.println("Add user"); String username = this.username.getText(); String password = this.password.getText(); boolean admin = this.admin.isSelected(); boolean enabled = this.enabled.isSelected(); System.out.println("User added: " + username + " " + password + " " + admin + " " + enabled); Employee employee = new Employee(); employee.id = 0; employee.username = username; employee.password = password; employee.admin = admin; employee.enabled = enabled; usertable.getItems().add(employee); this.username.clear(); this.password.clear(); this.admin.setSelected(false); this.enabled.setSelected(false); } @FXML private void deleteUser() { if(usertable.getSelectionModel().getSelectedItem() == null) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("Hiba!"); alert.setHeaderText("Hiba!"); alert.setContentText("Nincs kijelölt elem!"); alert.showAndWait(); return; } System.out.println("Delete user"); usertable.getItems().remove(usertable.getSelectionModel().getSelectedItem()); } @FXML private void updateUser() { if(usertable.getSelectionModel().getSelectedItem() == null) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("Hiba!"); alert.setHeaderText("Felhasználó módosítása"); alert.setContentText("Nincs kijelölt elem!"); alert.showAndWait(); return; } System.out.println("Update user"); Employee employee = usertable.getSelectionModel().getSelectedItem(); employee.username = this.username.getText(); employee.password = this.password.getText(); employee.admin = this.admin.isSelected(); employee.enabled = this.enabled.isSelected(); usertable.refresh(); } @FXML private void closeUserStage() throws IOException { App.setRoot("main"); } }
@FXML private TableView<Employee> empTable; //... ArrayList<Employee> emps = employeeSource.getEmployees(); ObservableList<Employee> observableEmps = FXCollections.observableArrayList(emps); empTable.setItems(observableEmps);
startButton.disableProperty() .bind(table.getSelectionModel() .selectedItemProperty().isNull());
package com.example; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; public class MainController { @FXML private TableView<Employee> table; @FXML private TableColumn<Employee, Integer> idCol; @FXML private TableColumn<Employee, String> naemCol; @FXML private Button startButton; @FXML private void initialize() { idCol.setCellValueFactory(new PropertyValueFactory<>("id")); naemCol.setCellValueFactory(new PropertyValueFactory<>("name")); ObservableList<Employee> data = FXCollections.observableArrayList(); data.add(new Employee(1, "name1")); data.add(new Employee(2, "name2")); data.add(new Employee(3, "name3")); data.add(new Employee(4, "name4")); table.setItems(data); startButton.disableProperty() .bind(table.getSelectionModel() .selectedItemProperty().isNull()); } @FXML void onClickStartButton(ActionEvent event) { } }
Nem csak kiválasztottnak kell lennie, de a kiválasztott sor értéke ne legyen „name3”:
startButton.disableProperty() .bind(table.getSelectionModel() .selectedItemProperty().isNull() .or( Bindings.select( table.getSelectionModel() .selectedItemProperty(), "name") .isEqualTo("name3") ) );