+ All Categories
Home > Documents > Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... ·...

Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... ·...

Date post: 25-Dec-2019
Category:
Upload: others
View: 51 times
Download: 0 times
Share this document with a friend
27
APLICAȚII JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul aplicațiilor grafice cu interfața definită printr-o variantă a limbajului XML (Extensible Markup Language) este în continuă creștere. Pentru a satisface aceste cerințe Microsoft au inventat XAML, Flex – MXML, iar acum și Oracle are o variantă proprietară numită Java FXML. Java FXML este un limbaj bazat pe XML folosit la construirea de grafuri de obiecte Java. Este o alternativă la construirea acestor grafuri prin metode de cod procedural și este ideal pentru definirea de interfețe cu utilizatorul, deoarece structura unui document XML este foarte asemănătoare cu structura de cod folosită la definirea unui graf de scenă într-o aplicație Java FX obișnuită. FXML nu are o schemă, dar are o structură predefinită. Ceea ce poate fi exprimat în FXML și cum este aplicat grafului scenei depinde de interfața de cod a obiectelor construite. Deoarece FXML este mapat direct în cod Java, aproape toate clasele de Java FX au un element XML corespondent cu atributele descrise în clasa Java mapată. Java FX BorderPane border = new BorderPane(); Label topPaneText = new Label("Page Title"); border.setTop(topPaneText); Label centerPaneText = new Label ("Some data here"); border.setCenter(centerPaneText); Java FXML <BorderPane> <top>
Transcript
Page 1: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

APLICAȚII JAVA FXML CU BAZE DE DATE

Breviar teoreticÎn industrie trendul aplicațiilor grafice cu interfața definită printr-o variantă a limbajului XML (Extensible Markup Language) este în continuă creștere. Pentru a satisface aceste cerințe Microsoft au inventat XAML, Flex – MXML, iar acum și Oracle are o variantă proprietară numită Java FXML.

Java FXML este un limbaj bazat pe XML folosit la construirea de grafuri de obiecte Java. Este o alternativă la construirea acestor grafuri prin metode de cod procedural și este ideal pentru definirea de interfețe cu utilizatorul, deoarece structura unui document XML este foarte asemănătoare cu structura de cod folosită la definirea unui graf de scenă într-o aplicație Java FX obișnuită.

FXML nu are o schemă, dar are o structură predefinită. Ceea ce poate fi exprimat în FXML și cum este aplicat grafului scenei depinde de interfața de cod a obiectelor construite. Deoarece FXML este mapat direct în cod Java, aproape toate clasele de Java FX au un element XML corespondent cu atributele descrise în clasa Java mapată.

Java FX

BorderPane border = new BorderPane();

Label topPaneText = new Label("Page Title");

border.setTop(topPaneText);

Label centerPaneText = new Label ("Some data here");

border.setCenter(centerPaneText);

Java FXML

<BorderPane>

<top>

<Label text="Page Title"/>

</top>

<center>

<Label text="Some data here"/>

</center>

</BorderPane>

Page 2: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

Pentru a eficientiza procesul de dezvoltare al aplicațiilor cu interfețe grafice au fost create șabloane (patternuri) și arhitecturi de aplicații. Cel mai popular pattern pentru aplicațiile desktop este Model View Controller, care a devenit folosit chiar și în aplicațiile web.

Patternul Model View Controller este o metodă de a implementa interfețe cu utilizatorul, care divide software-ul implementat în trei părți interconectate, pentru a separa reprezentările interne de informațiile prezentate utilizatorilor.

Din perspectiva patternului Model View Controller, fișierul care conține descrierea XML a interfeței este View-ul. Controllerul este o clasă de Java care este declarată ca și controllerul fișierului XML. Modelul este constituit din obiectele domeniului definite în Java. Modelul se leagă de interfață folosind Controllere.

Pentru a interacționa cu o bază de date vom încapsula logica necesară interogărilor și extragerii primare de date folosind un alt pattern numit Data Access Object. Această abstractizare permite operațiuni specifice (de exemplu operațiile CRUD) fără a divulga detaliile mecanismului de persistență a datelor.

Aceste două patternuri ne vor ajuta să ne structurăm aplicația într-o manieră scalabilă și ușor de înțeles.

Model Punctul central al aplicației: datele și regulile procesului. Este independent de interfață.

View Afișează datele din model. Are și rolul de a transmite evenimente legate de interacțiunea utilizatorului la Controller.

Controller Conectează modelul si view-ul (interfața cu utilizatorul). Are rolul de a pregăti datele pentru afișare și de a răspunde la comenzile primite din interfață.

Page 3: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

Aplicație Realizarea unei aplicații grafice folosind Java FXML și conectarea acesteia la o bază de date SQLite

Aplicația pe care o vom dezvolta se va conecta la o bază de date SQLite, care conține o tabelă Person (FirstName, LastName), și va pune la dispoziția utilizatorului o interfața prietenoasă prin care se poate realiza operațiile de CRUD (Create, Read, Update, Delete). Interfața va arăta în felul următor:

Vom folosi mediul de programare NetBeans și vom crea un nou proiect Java – Application cu numele SqliteJavaFxml. Pentru aplicația noastră avem nevoie de pachetul sqlite-jdbc, pe care îl putem downloada de la acest link sqlite-jdbc-3.8.11.2.jar .

După ce am descărcat sqlite-jdbc, trebuie adăugat la referințele proiectului in directorul Libraries – click dreapta → Add JAR/Folder → Alegem fișierul nou descărcat sqlite-jdbc-3.8.11.2.jar.

Următorii pași care sunt sugerați în dezvoltarea acestei aplicații sunt stabilirea structurii de fișiere. Ne vom crea module (packages) astfel încât să urmăm principiile MVC și DAO.

Vom redenumi packageul implicit sqlite.java.fxml în model pentru a respecta convenția noastră.

Apoi vom crea și următoarele module view și dataaccess. Restul fișierelor vor fi adăugate în modulele aferente folosind meniul contextual click dreapta pe modul și Add Other…

Structura finală a proiectului va fi cea din figura alăturată:

Page 4: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

Vom porni de la stabilirea clară a modelului aplicației, adică fișierul Person.java, urmat de layerul de acces la baza de date (PersonDAO – Data Access Object), clasa principală a aplicației noastre (SqliteJavaFxml.java) care face legatura dintre toate componentele, la urmă rămânând fișierele care descriu interfața și controllerele asociate acestora.

Fișierul Person.java conține definiția clasei Person, care va corespunde ca și proprietăți tabelei Person din baza de date folosită în aplicație.

package model;

import javafx.beans.property.SimpleStringProperty;

import javafx.beans.property.StringProperty;

public class Person {

private int id;

private final StringProperty firstName;

private final StringProperty lastName;

public Person() {

this(0, null, null);

}

public Person(int id, String firstName, String lastName) {

this.id = id;

this.firstName = new SimpleStringProperty(firstName);

this.lastName = new SimpleStringProperty(lastName);

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

Page 5: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

}

public String getFirstName() {

return firstName.get();

}

public void setFirstName(String firstName) {

this.firstName.set(firstName);

}

public StringProperty firstNameProperty() {

return firstName;

}

public String getLastName() {

return lastName.get();

}

public void setLastName(String lastName) {

this.lastName.set(lastName);

}

public StringProperty lastNameProperty() {

return lastName;

}

}

După definirea proprietăților, vom putea scrie mai departe modulul de acces la baza de date. Acest modul se va ocupa de crearea tabelei în cazul în care nu există deja și de interacționarea din cod Java cu tabela Person (Create, Read, Update, Delete). Conținutul fișierului PersonDAO va fi următorul:

Page 6: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

package dataaccess;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.ArrayList;

import java.util.List;

import java.util.logging.Level;

import java.util.logging.Logger;

import model.SqliteJavaFxml;

import model.Person;

public class PersonDAO {

private final String databaseConnectionString;

public PersonDAO(String databaseConnectionString) throws ClassNotFoundException {

Class.forName("org.sqlite.JDBC");

this.databaseConnectionString = databaseConnectionString;

this.ensureTables();

}

private void ensureTables() {

try (Connection connection = DriverManager.getConnection(databaseConnectionString);

Statement statement = connection.createStatement()) {

String query = "CREATE TABLE IF NOT EXISTS PERSON("

+ "ID INTEGER PRIMARY KEY AUTOINCREMENT,"

Page 7: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

+ "FIRST_NAME NVARCHAR(32),"

+ "LAST_NAME NVARCHAR(32));";

statement.execute(query);

System.out.println("Tables created successfully!");

} catch (SQLException ex) {

Logger.getLogger(SqliteJavaFxml.class.getName()).log(Level.SEVERE, null, ex);

}

}

public List<Person> getAllPersons() {

List<Person> persons = new ArrayList<Person>();

try (Connection connection = DriverManager.getConnection(databaseConnectionString);

Statement statement = connection.createStatement()) {

String query = "SELECT ID, FIRST_NAME, LAST_NAME FROM PERSON;";

try (ResultSet rs = statement.executeQuery(query)) {

while (rs.next()) {

int id = rs.getInt("ID");

String firstName = rs.getString("FIRST_NAME");

String lastName = rs.getString("LAST_NAME");

persons.add(new Person(id, firstName, lastName));

}

}

} catch (SQLException ex) {

Logger.getLogger(SqliteJavaFxml.class.getName()).log(Level.SEVERE, null, ex);

}

return persons;

}

Page 8: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

public Person getPerson(int personId) {

Person person = null;

try (Connection connection = DriverManager.getConnection(databaseConnectionString);

PreparedStatement statement

= connection.prepareStatement("SELECT ID, FIRST_NAME, LAST_NAME FROM PERSON WHERE ID = ?;")) {

statement.setInt(1, personId);

try (ResultSet rs = statement.executeQuery()) {

while (rs.next()) {

int id = rs.getInt("ID");

String firstName = rs.getString("FIRST_NAME");

String lastName = rs.getString("LAST_NAME");

person = new Person(id, firstName, lastName);

}

}

} catch (SQLException ex) {

Logger.getLogger(SqliteJavaFxml.class.getName()).log(Level.SEVERE, null, ex);

}

return person;

}

public boolean insertPerson(Person person) {

boolean success = true;

try (Connection connection = DriverManager.getConnection(databaseConnectionString);

PreparedStatement statement

= connection.prepareStatement("INSERT INTO PERSON (FIRST_NAME, LAST_NAME) VALUES (?, ?);")) {

statement.setString(1, person.getFirstName());

statement.setString(2, person.getLastName());

Page 9: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

statement.executeUpdate();

} catch (SQLException ex) {

Logger.getLogger(SqliteJavaFxml.class.getName()).log(Level.SEVERE, null, ex);

success = false;

}

return success;

}

public boolean updatePerson(Person person) {

boolean success = true;

try (Connection connection = DriverManager.getConnection(databaseConnectionString);

PreparedStatement statement

= connection.prepareStatement("UPDATE PERSON "

+ " SET FIRST_NAME = ?, LAST_NAME = ? "

+ " WHERE ID = ?;")) {

statement.setString(1, person.getFirstName());

statement.setString(2, person.getLastName());

statement.setInt(3, person.getId());

statement.executeUpdate();

} catch (SQLException ex) {

Logger.getLogger(SqliteJavaFxml.class.getName()).log(Level.SEVERE, null, ex);

success = false;

}

return success;

}

public boolean deletePerson(Person person) {

boolean success = true;

try (Connection connection = DriverManager.getConnection(databaseConnectionString);

PreparedStatement statement

Page 10: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

= connection.prepareStatement("DELETE FROM PERSON WHERE ID = ?;")) {

statement.setInt(1, person.getId());

statement.executeUpdate();

} catch (SQLException ex) {

Logger.getLogger(SqliteJavaFxml.class.getName()).log(Level.SEVERE, null, ex);

success = false;

}

return success;

}

}

Fișierul principal al aplicației noastre îl constituie SqliteJavaFxml.java și va conține codul pentru gestionarea scenei și a viewurilor. În acest fișier vom scrie următoarele:

package model;

import dataaccess.PersonDAO;

import java.io.IOException;

import javafx.application.Application;

import javafx.fxml.FXMLLoader;

import javafx.scene.Scene;

import javafx.scene.layout.AnchorPane;

import javafx.scene.layout.BorderPane;

import javafx.stage.Modality;

import javafx.stage.Stage;

import view.PersonEditDialogController;

import view.PersonOverviewController;

public class SqliteJavaFxml extends Application {

Page 11: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

private Stage primaryStage;

private BorderPane rootLayout;

private final PersonDAO personDAO;

public SqliteJavaFxml() throws ClassNotFoundException {

this.personDAO = new PersonDAO("jdbc:sqlite:crudapp.db");

}

public PersonDAO getPersonDAO() {

return this.personDAO;

}

@Override

public void start(Stage primaryStage) {

this.primaryStage = primaryStage;

this.primaryStage.setTitle("SQLite Java FXML Crud App");

initRootLayout();

showPersonOverview();

}

public void initRootLayout() {

try {

FXMLLoader loader = new FXMLLoader();

loader.setLocation(SqliteJavaFxml.class.getResource("/view/RootLayout.fxml"));

rootLayout = (BorderPane) loader.load();

Scene scene = new Scene(rootLayout);

Page 12: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

primaryStage.setScene(scene);

primaryStage.show();

} catch (IOException e) {

}

}

public void showPersonOverview() {

try {

FXMLLoader loader = new FXMLLoader();

loader.setLocation(SqliteJavaFxml.class.getResource("/view/PersonOverview.fxml"));

AnchorPane personOverview = (AnchorPane) loader.load();

rootLayout.setCenter(personOverview);

PersonOverviewController controller = loader.getController();

controller.setMainApp(this);

} catch (IOException e) {

}

}

public boolean showPersonEditDialog(Person person) {

try {

FXMLLoader loader = new FXMLLoader();

loader.setLocation(SqliteJavaFxml.class.getResource("/view/PersonEditDialog.fxml"));

AnchorPane page = (AnchorPane) loader.load();

Stage dialogStage = new Stage();

dialogStage.setTitle("Edit Person");

dialogStage.initModality(Modality.WINDOW_MODAL);

Page 13: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

dialogStage.initOwner(primaryStage);

Scene scene = new Scene(page);

dialogStage.setScene(scene);

PersonEditDialogController controller = loader.getController();

controller.setDialogStage(dialogStage);

controller.setPerson(person);

dialogStage.showAndWait();

return controller.isOkClicked();

} catch (IOException e) {

return false;

}

}

public Stage getPrimaryStage() {

return primaryStage;

}

public static void main(String[] args) {

launch(args);

}

}

Observăm că în constructorul clasei principale se află instanțierea Data Access Objectului pentru persoane care primește ca parametru adresa bazei de date SQLite. Reamintim că această baze de date se creează automat la rularea programului direct în directorul proiectului.

this.personDAO = new PersonDAO("jdbc:sqlite:crudapp.db");

Page 14: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

Metodele care controlează viewurile sunt initRootLayout, showPersonOverview, showPersonEditDialog.

După cum se poate observa, toate cele trei metode au o structura similară, în sensul că se deschid cu un bloc de gestionare a excepțiilor provenite din lipsa fișierelor (Input/Output) sau lipsa accesului la aceste resurse. Resursele, adică fișierele în care sunt descrise viewurile sunt încărcate cu ajutorul clasei FXMLLoader, folosind metodele

setLocation si load.

Pentru a lega controllerele de aceste viewuri, apelăm tot la loaderul FXML, folosind metoda getController.

Vom continua cu definirea fiecărui View și Controller asociat.

Fișierul RootLayout.fxml va conține doar un cadru pentru aplicația noastră, va fi practic containerul care dimensionează fereastra principală a aplicației.

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>

<?import java.lang.*?>

<?import javafx.scene.layout.*?>

<?import javafx.scene.layout.BorderPane?>

<BorderPane prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40">

</BorderPane>

Acest View nu are nevoie de un controller asociat deoarece nu are legături de date, el fiind folosit doar pentru a aranja layoutul aplicației.

Fișierul PersonOverview.fxml va conține descrierea tabelului FXML corespunzător tabelei Person dintr-o bază de date SQLite, care va fi folosit desigur la extragerea și afișarea datelor din acea tabelă. În acest View vom regăsi și trei butoane de acțiune care au rolul de a manipula datele din tabel, respectiv baza de date, prin intermediul de ferestre intermediare sau acțiuni asupra modelului.

De remarcat sunt legarea proprietăților din controller la view cu atributul fx:id (fx:id="firstNameColumn") și

legarea funcțiilor cu prefixul "#" (#handleNewPerson);

<?xml version="1.0" encoding="UTF-8"?>

Page 15: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

<?import javafx.scene.control.*?>

<?import java.lang.*?>

<?import javafx.scene.layout.*?>

<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.PersonOverviewController">

<children>

<TableView fx:id="personTable" layoutX="-12.0" layoutY="49.0" prefHeight="298.0" prefWidth="175.0" AnchorPane.bottomAnchor="45.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">

<columns>

<TableColumn fx:id="firstNameColumn" prefWidth="75.0" text="First Name" />

<TableColumn fx:id="lastNameColumn" prefWidth="75.0" text="Last Name" />

</columns>

<columnResizePolicy>

<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />

</columnResizePolicy>

</TableView>

<ButtonBar layoutX="54.0" layoutY="250.0" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="10.0">

<buttons>

<Button mnemonicParsing="false" onAction="#handleNewPerson" text="New..." />

<Button mnemonicParsing="false" onAction="#handleEditPerson" text="Edit..." />

<Button mnemonicParsing="false" onAction="#handleDeletePerson" text="Delete" />

</buttons>

</ButtonBar>

</children>

</AnchorPane>

Page 16: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

Controllerul acestui View se regăsește în fișierul PersonOverviewController.java și va face legătura dintre interfața grafica și model, persistând rezultatul acțiunilor utilizatorului în baza de date prin intermediul Person Data Access Objectului.

De remarcat sunt decoratorii (@FXML) folosiți pentru a marca proprietățile și funcțiile ce interacționează în corpul lor

cu elemente din fișierul FXML pe care îl controlează. Dacă metodele, respectiv proprietățile nu sunt decorate cu @FXML, aplicația va avea erori de funcționare. În cazul în care nu este selectată nicio înregistrare din tabel, apăsarea

butoanelor de acțiune pentru editare și ștergere vor declanșa apariția unui mesaj de eroare (metoda showAlert).

package view;

import dataaccess.PersonDAO;

import java.util.List;

import javafx.collections.FXCollections;

import javafx.collections.ObservableList;

import javafx.fxml.FXML;

import javafx.scene.control.Alert;

import javafx.scene.control.Alert.AlertType;

import javafx.scene.control.TableColumn;

import javafx.scene.control.TableView;

import model.SqliteJavaFxml;

import model.Person;

public class PersonOverviewController {

@FXML

private TableView<Person> personTable;

@FXML

private TableColumn<Person, String> firstNameColumn;

@FXML

private TableColumn<Person, String> lastNameColumn;

private SqliteJavaFxml mainApp;

Page 17: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

private PersonDAO personDAO;

public PersonOverviewController() {

}

@FXML

private void initialize() {

firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());

lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());

}

public void setMainApp(SqliteJavaFxml mainApp) {

this.mainApp = mainApp;

handleRefreshPersons();

}

@FXML

private void handleDeletePerson() {

Person selectedPerson = personTable.getSelectionModel().getSelectedItem();

if (selectedPerson != null) {

mainApp.getPersonDAO().deletePerson(selectedPerson);

handleRefreshPersons();

} else {

showAlert();

}

}

@FXML

private void handleNewPerson() {

Person tempPerson = new Person();

Page 18: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

boolean okClicked = mainApp.showPersonEditDialog(tempPerson);

if (okClicked) {

mainApp.getPersonDAO().insertPerson(tempPerson);

handleRefreshPersons();

}

}

@FXML

private void handleEditPerson() {

Person selectedPerson = personTable.getSelectionModel().getSelectedItem();

if (selectedPerson != null) {

boolean okClicked = mainApp.showPersonEditDialog(selectedPerson);

if (okClicked) {

mainApp.getPersonDAO().updatePerson(selectedPerson);

handleRefreshPersons();

}

} else {

showAlert();

}

}

@FXML

private void handleRefreshPersons() {

List<Person> persons = mainApp.getPersonDAO().getAllPersons();

ObservableList<Person> items = FXCollections.observableArrayList(persons);

personTable.setItems(items);

}

private void showAlert() {

Alert alert = new Alert(AlertType.WARNING);

alert.initOwner(mainApp.getPrimaryStage());

Page 19: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

alert.setTitle("No Selection");

alert.setHeaderText("No Person Selected");

alert.setContentText("Please select a person in the table.");

alert.showAndWait();

}

}

Ultimul view folosit în aplicație este cel care descrie fereastra de tip dialog prin care un utilizator poate introduce datele unei persoane noi sau poate edita pe cele ale uneia existente în baza de date. În funcție de metoda de unde a fost apelat controllerul acestui view, rezultatul acțiunii de a apăsa butonul OK va declanșa o acțiune de adăugare sau de editare a tabelei Person.

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>

<?import java.lang.*?>

<?import javafx.scene.layout.*?>

<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="120.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="view.PersonEditDialogController">

<children>

<GridPane layoutX="30.0" layoutY="28.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">

<columnConstraints>

<ColumnConstraints prefWidth="150.0" />

<ColumnConstraints prefWidth="250.0" />

</columnConstraints>

<rowConstraints>

<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />

<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />

Page 20: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

</rowConstraints>

<children>

<Label text="First Name" />

<Label text="Last Name" GridPane.rowIndex="1" />

<TextField fx:id="firstNameField" GridPane.columnIndex="1" />

<TextField fx:id="lastNameField" GridPane.columnIndex="1" GridPane.rowIndex="1" />

</children>

</GridPane>

<ButtonBar AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="10.0">

<buttons>

<Button mnemonicParsing="false" onAction="#handleOk" text="OK" />

<Button mnemonicParsing="false" onAction="#handleCancel" text="Cancel" />

</buttons>

</ButtonBar>

</children>

</AnchorPane>

Controllerul pentru acest view, PersonEditDialogController.java , este folosit pentru a verifica introducerea corectă de date și validarea modificarărilor la nivel de interfață. Acesta comunică schimbările modelului controllerului PersonOverviewController, iar acesta din urmă va acționa și în baza de date.

package view;

import javafx.fxml.FXML;

import javafx.scene.control.Alert;

import javafx.scene.control.Alert.AlertType;

import javafx.scene.control.TextField;

import javafx.stage.Stage;

import model.Person;

public class PersonEditDialogController {

Page 21: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

@FXML

private TextField firstNameField;

@FXML

private TextField lastNameField;

private Stage dialogStage;

private Person person;

private boolean okClicked = false;

@FXML

private void initialize() {

}

public void setDialogStage(Stage dialogStage) {

this.dialogStage = dialogStage;

}

public void setPerson(Person person) {

this.person = person;

firstNameField.setText(person.getFirstName());

lastNameField.setText(person.getLastName());

}

public boolean isOkClicked() {

return okClicked;

}

@FXML

Page 22: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

private void handleOk() {

if (isInputValid()) {

person.setFirstName(firstNameField.getText());

person.setLastName(lastNameField.getText());

okClicked = true;

dialogStage.close();

}

}

@FXML

private void handleCancel() {

dialogStage.close();

}

private boolean isInputValid() {

String errorMessage = "";

if (firstNameField.getText() == null || firstNameField.getText().length() == 0) {

errorMessage += "No valid first name!\n";

}

if (lastNameField.getText() == null || lastNameField.getText().length() == 0) {

errorMessage += "No valid last name!\n";

}

if (errorMessage.length() == 0) {

return true;

} else {

Alert alert = new Alert(AlertType.ERROR);

alert.initOwner(dialogStage);

alert.setTitle("Invalid Fields");

Page 23: Aplicații JAVA FXML CU BAZE DE DATErobotics.ucv.ro/carti/java/Laborator/Aplicatii Java FXML... · Web viewAplicații JAVA FXML CU BAZE DE DATE Breviar teoretic În industrie trendul

alert.setHeaderText("Please correct invalid fields");

alert.setContentText(errorMessage);

alert.showAndWait();

return false;

}

}

}

Putem vedea relația dintre aceste doua controllere ca Master-Slave, unul fiind utilizat pentru controlul la nivel doar de interfață (PersonEditDialogController), iar celălalt pentru a gestiona logica aplicației.

Așadar, am realizat o aplicație cu interfață grafică, susținută de o bază de date SQLite. Concluzia este că aplicând o arhitectură MVC putem scrie codul într-un mod modular, ușor de extins, care ține cont de patternuri aplicate în tehnicile moderne de programare și putem îl refolosi pentru aplicații asemănătoare.


Recommended