Database
 sql >> Database >  >> RDS >> Database

Utilizzo dell'interfaccia utente JavaFX e delle applicazioni JDBC

Poiché JavaFX sta guadagnando terreno come framework GUI de facto di Java, prima o poi sostituirà Swing. JavaFX UI e JDBC possono essere una combinazione efficace durante la creazione di un'applicazione basata su database, specialmente in un sistema offline o incorporato. Questo articolo mostra essenzialmente come farlo con uno scenario di esempio.

Una panoramica dell'applicazione JDBC

L'evoluzione del framework della GUI Java ora si basa sulla libreria JavaFX. Fornisce un'alternativa potente ma flessibile allo sviluppo della GUI, in contrasto con il suo framework Swing e AWT esistente. JavaFX fornisce una vasta gamma di controlli e componenti che aiutano a creare un'interfaccia GUI in modo rapido ed efficace. È molto facile sviluppare un'applicazione desktop che interagisca con il database back-end. Un JDBC (Java Database Connectivity) l'applicazione ha principalmente un sistema di database back-end come MySQL, Derby, Oracle o qualsiasi altro database. Il codice Java viene scritto per recuperare i record da una o più tabelle nel database. L'SQL (Structured Query Language) le query vengono generate dal codice Java e inviate al motore di database per l'elaborazione. Il driver JDBC funge da intermediario tra il programma Java e il database e interpreta la raffica di informazioni avanti e indietro, in modo che sia la parte non corrispondente, come il database, sia il programma Java possano riconciliarsi in una soluzione praticabile. Il database non ha assolutamente idea del codice Java, delle sue sintassi o altro. Comprende semplicemente SQL e può comunicare solo con esso. Java, invece, è un OOP (Object Oriented Programming) lingua e non ha idea nemmeno di SQL o delle sue sintassi. Per rendere possibile la comunicazione, il fornitore del database fornisce i driver nativi insieme al database. Questo è chiamato driver JDBC. Si noti che sono disponibili quattro tipi di driver. Sono colloquialmente chiamati driver di Tipo-1, Tipo-2, Tipo-3 e Tipo-4. I driver nativi sono di tipo 4 e sono più comunemente usati. Sono anche più efficienti di altri tipi. Un programma Java può includere questi driver JDBC come una libreria esterna nel programma Java, poiché comunemente si trovano nei file di archivio JAR.

JavaFX nella scena

Ogni applicazione di database richiede un'interfaccia in modo che l'utente possa interagire con le informazioni del database. Meglio, se si tratta di un'interfaccia GUI in cui non dobbiamo abbassarci a un'interfaccia di comando di basso livello e intimidatoria, ma ottenere ciò che vogliamo con un clic di un pulsante. Sotto questo aspetto, JavaFX con JDBC può essere una combinazione killer perché ha un certo numero di componenti GUI visivamente interessanti che possono essere utilizzati per rappresentare i record del database in un modo più significativo. Ad esempio, i record possono essere visualizzati in forma tabellare con TableView controllo. Oppure possiamo creare un modulo per aggiungere nuovi record nella tabella del database. I dati inseriti dall'utente possono essere verificati tramite codice Java prima dell'invio al database. Il motore di database back-end ottiene una tregua dalla convalida dei dati e dall'elaborazione bloccata a causa di un errore di input. Inoltre, l'utente finale potrebbe essere un profano con poca o nessuna idea sui vincoli dei dati di input. Questo è idealmente fatto quando viene creato un modulo di input con TextField , Etichetta , ComboBox e Vista elenco controlli in JavaFX. Gli eventi generati da Button e altri controlli sono gestiti in modo tale che l'utente sia a proprio agio mentre interagisce con l'interfaccia GUI.

In uno scenario di esempio

Nell'esempio illustrato seguente, implementeremo una ListView operazione di ricerca inserendo il testo in un Campo di testo . L'elemento selezionato in ListView viene recuperato di conseguenza dal database back-end e visualizzato in TableView controllo. Quindi, è principalmente un tipo di applicazione di recupero e visualizzazione. Altre operazioni del database, come l'inserimento, l'eliminazione e l'aggiornamento dei record, non vengono implementate a causa dei vincoli di dimensione. Sarebbe un bel esercizio implementarli da soli.

Quindi, prima di iniziare, dobbiamo creare una tabella di database e un progetto Java. Useremo MySQL come database di back-end; puoi scegliere qualsiasi altro ma assicurati di includere i driver appropriati nel tuo pom.xml file. Ecco parte del codice SQL per creare la tabella, inserire alcuni dati fittizi e alcune altre operazioni.

CREATE DATABASE addressbook;
USE DATABASE addressbook;

DROP TABLE IF EXISTS contact;

CREATE TABLE contact(
   id INT UNSIGNED NOT NULL AUTO_INCREMENT,
   name VARCHAR(100) NOT NULL,
   nick_name VARCHAR(20),
   address VARCHAR(128),
   home_phone VARCHAR(10),
   work_phone VARCHAR(10),
   cell_phone VARCHAR(10),
   email VARCHAR(100),
   birthday date,
   web_site VARCHAR(100),
   profession VARCHAR(100),
   PRIMARY KEY (id)
);

INSERT INTO contact (name, nick_name, address, home_phone,
   work_phone, cell_phone, email, birthday, web_site,profession)
   VALUES ('Bruce Wayne', 'batman', 'XYZ Batcave', '9876543210',
   '6278287326', '9182872363', '[email protected]',
   '1976/02/03', 'batblog.com', 'Super Hero');
...

INSERT INTO contact (...) VALUES (...);

Maven Project: pom.xml
<project 
      xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
      http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.mano.jdbc.examples</groupId>
   <artifactId>JavaFXJDBCApp</artifactId>
   <version>1.0-SNAPSHOT</version>
   <packaging>jar</packaging>
   <name>JavaFXJDBCApp</name>
   <url>http://maven.apache.org</url>
   <properties>
      <project.build.sourceEncoding>
         UTF-8
      </project.build.sourceEncoding>
   </properties>
   <build>
      <plugins>
         <plugin>
            <groupId>
               org.apache.maven.plugins
            </groupId>
            <artifactId>
               maven-compiler-plugin
            </artifactId>
            <version>2.5.1</version>
            <configuration>
               <source>1.8</source>
               <target>1.8</target>
            </configuration>
         </plugin>
      </plugins>
   </build>
   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>
      <!-- https://mvnrepository.com/artifact/mysql/
           mysql-connector-java -->
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.1.6</version>
      </dependency>
   </dependencies>
</project>

Ora creiamo un oggetto dominio che useremo in entrambi ListView e TableView perché entrambi sono correlati, come affermato nel nostro caso. La TableView conterrà un elenco osservabile di persone (Persona di contatto ) in base al nome della persona selezionata da ListView controllo. Abbiamo anche un TextField per effettuare una rapida ricerca degli elementi (Persona di contatto name) contenuto in ListView . Alla selezione di un elemento specifico da ListView , viene attivata una query SQL e vengono recuperati i record pertinenti per popolare TableView controllare di conseguenza.

Oggetto dominio:Persona di contatto

La persona di contatto class non è altro che la rappresentazione POJO del contatto attributi della tabella. Contiene il costruttore e il semplice getter-setter metodi.

package org.mano.jdbc.examples;
import java.util.Date;
public class ContactPerson {
   private int id;
   private String name;
   private String nickName;
   private String address;
   private String homePhone;
   private String workPhone;
   private String cellPhone;
   private String email;
   private Date birthDate;
   private String webSite;
   private String profession;
   public ContactPerson() {
   }
   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getNickName() {
      return nickName;
   }
   public void setNickName(String nickName) {
      this.nickName = nickName;
   }
   public String getAddress() {
      return address;
   }
   public void setAddress(String address) {
      this.address = address;
   }
   public String getHomePhone() {
      return homePhone;
   }<
   public void setHomePhone(String homePhone) {
      this.homePhone = homePhone;
   }
   public String getWorkPhone() {
      return workPhone;
   }
   public void setWorkPhone(String workPhone) {
      this.workPhone = workPhone;
   }
   public String getCellPhone() {
      return cellPhone;
   }
   public void setCellPhone(String cellPhone) {
      this.cellPhone = cellPhone;
   }
   public String getEmail() {
      return email;
   }
   public void setEmail(String email) {
      this.email = email;
   }
   public Date getBirthDate() {
      return birthDate;
   }
   public void setBirthDate(Date birthDate) {
      this.birthDate = birthDate;
   }
   public String getWebSite() {
      return webSite;
   }
   public void setWebSite(String webSite) {
      this.webSite = webSite;
   }
   public String getProfession() {
      return profession;
   }
   public void setProfession(String profession) {
      this.profession = profession;
   }
}

Oggetto di accesso ai dati:ContactDAO

Il ContactDAO è una classe di oggetti di accesso ai dati che include principalmente l'operazione di accesso al database. Implementa il DAO interfaccia. Questa interfaccia potrebbe non essere importante nel nostro esempio, ma potrebbe essere utile se l'applicazione viene estesa con più classi di oggetti di accesso ai dati. Qui, il DAO include una stringa di connessione, un driver, un nome utente e una password per accedere al database MySQL.

DAO.java

package org.mano.jdbc.examples;
public interface DAO {
   public static final String DB_URL =
      "jdbc:mysql://localhost:3306/"+
   "addressbook?zeroDateTimeBehavior=convertToNull";
   public static final String DRIVER =
      "com.mysql.jdbc.Driver";
   public static final String USER = "root";
   public static final String PASS = "secret";
}

Contatta DAO.java

package org.mano.jdbc.examples;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class ContactDAO implements DAO {
   private ontactPerson createContactPerson(ResultSet rs) {
      ContactPerson p = new ContactPerson();
      try {
         p.setId(rs.getInt("id"));
         p.setName(rs.getString("name"));
         p.setNickName(rs.getString("nick_name"));
         p.setAddress(rs.getString("address"));
         p.setHomePhone(rs.getString("home_phone"));
         p.setWorkPhone(rs.getString("work_phone"));
         p.setCellPhone(rs.getString("cell_phone"));
         p.setEmail(rs.getString("email"));
         p.setBirthDate(rs.getDate("birthday"));
         p.setWebSite(rs.getString("web_site"));
         p.setProfession(rs.getString("profession"));
      } catch (SQLException ex) {
      }
      return p;
   }
   public List<ContactPerson> getContacts() {
      String sql = "Select * from contact order by name";
      List<ContactPerson> list = new ArrayList<>();
      try {
         Class.forName(DRIVER);
         Connection con = DriverManager.getConnection
            (DB_URL, USER, PASS);
         Statement stmt = con.createStatement();
         ResultSet rs = stmt.executeQuery(sql);
         while (rs.next()) {
            ContactPerson p = createContactPerson(rs);
            list.add(p);
         }
         rs.close();
         con.close();
      } catch (ClassNotFoundException | SQLException ex) {
      }
      return list;
   }

   public List<ContactPerson> getContactsForName(String name) {
      String sql = "Select * from contact where name like '%" +
         name + "%'";
      List<ContactPerson> list = new ArrayList<>();
      try {
         Class.forName(DRIVER);
         Connection con = DriverManager.getConnection
            (DB_URL, USER, PASS);
         Statement stmt = con.createStatement();
         ResultSet rs = stmt.executeQuery(sql);
         while (rs.next()) {
            ContactPerson p = createContactPerson(rs);
            list.add(p);
         }
         rs.close();
         con.close();
      } catch (ClassNotFoundException | SQLException ex) {
      }
      return list;
   }
}

Interfaccia GUI JavaFX:ContattaBrowser

Nell'applicazione JavaFX denominata ContactBrowser , impostiamo tutti i controlli a livello di codice. Questo può anche essere impostato utilizzando FXML o strumenti di utilità del builder come Scene Builder. Ma, secondo l'opinione dello scriba, possono essere utilizzati una volta che si è acquisita abbastanza esperienza su ciò che si nasconde dietro le quinte in JavaFX. La GUI è principalmente un'interazione di tre controlli, come un TextField (campo di ricerca ), una Vista elenco (listView ) e TableView (contactTableView ). Il codice è autoesplicativo, con commenti forniti nei punti appropriati. L'espressione Lambda viene utilizzata ove applicabile per mantenere il codice conciso. Fare riferimento alla documentazione dell'API JavaFX ove necessario.

package org.mano.jdbc.examples;
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.collections.transformation.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class ContactBrowser extends Application {
    // List of contact table properties
   private String[] propertyName = {"id",
      "name", "nickName", "address",
      "homePhone", "workPhone", "cellPhone",
      "email", "birthDate", "webSite",
      "profession"};
   private String[] propertyLabel = {"ID",
      "Name", "Nick Name", "Address",
      "Home Phone", "Work Phone", "Cell Phone",
      "Email", "Birth Date", "Website",
      "Profession"};
   private ContactDAO contact = new ContactDAO();
   private final GridPane gridPane = new GridPane();
   private final Label lblName = new Label("Search by Name");
   private final TextField searchField = new TextField();
   private ObservableList<ContactPerson> observableNames;
   private FilteredList<ContactPerson> filteredData;
   private SortedList<ContactPerson> sortedData;
   private final ListView<ContactPerson> listView;
   TableView<ContactPerson> contactTableView =
      new TableView<>();
   public ContactBrowser2() {
      lblName.setTextFill(Color.web("#0076a3"));
      observableNames = FXCollections.observableArrayList
         (contact.getContacts());
      filteredData = new FilteredList<>
         (observableNames, p -> true);
      sortedData = new SortedList<>(filteredData);
      listView = new ListView<>(sortedData);
   }
   @Override
   public void start(Stage primaryStage) {
      primaryStage.setTitle("Address Book");
      primaryStage.setMaximized(true);
      BorderPane borderPane = new BorderPane();
      Scene scene = new Scene(borderPane,650,400,true);
      gridPane.setPadding(new Insets(10));
      gridPane.setHgap(5);
      gridPane.setVgap(5);
      gridPane.add(lblName, 0, 0);
      gridPane.add(searchField, 0, 1);
      // Search TextField event handling
      searchField.textProperty()
         .addListener((observable, oldValue, newValue) ->
            filteredData.setPredicate(str -> {
               if (newValue == null || newValue.isEmpty())
                  return true;
               if (str.getName().toLowerCase().contains
                     (newValue.toLowerCase()))
                  return true;
               return false;
      }));
      listView.getSelectionModel().setSelectionMode
         (SelectionMode.SINGLE);
      listView.setPrefHeight(Integer.MAX_VALUE);
      // Sets a new cell factory to use in the ListView.
      // This throws away all old list cells and new ListCells
      // created with the new cell factory.
      listView.setCellFactory(listView-> {
         Tooltip tooltip = new Tooltip();
         ListCell<ContactPerson> cell = new
               ListCell<ContactPerson>() {
            @Override
            public voidupdateItem(ContactPerson contactPerson,
                  Boolean empty) {
               super.updateItem(contactPerson, empty);
               if (contactPerson != null) {
                  setText(contactPerson.getName());
                  tooltip.setText(contactPerson.getNickName());
                  setTooltip(tooltip);
               } else
                  setText(null);
            }
         };
         return cell;
      });
      gridPane.add(listView, 0, 2);
      // Create and initializing TableView
      ObservableList<ContactPerson> contactPeopleList
         = FXCollections.observableArrayList();
      contactTableView.setItems(contactPeopleList);
      contactTableView.setColumnResizePolicy(
         TableView.CONSTRAINED_RESIZE_POLICY);
      for (int i = 0; i <
            propertyLabel.length; i++) {
         TableColumn<ContactPerson, Object> col
            = new TableColumn<>(propertyLabel[i]);
         col.setCellValueFactory(new
            PropertyValueFactory<>(propertyName[i]));
         contactTableView.getColumns().add(col);
      }
      borderPane.setCenter(contactTableView)
      borderPane.setLeft(gridPane);
      // TableView will populate from the contactPeopleList
      // contactPeopleList will have value according to the
      // item selected in the ListView
      listView.getSelectionModel()
         .selectedItemProperty()
         .addListener(new ChangeListener<ContactPerson>() {
            @Override
            public void changed(
               ObservableValue<? extends
                  ContactPerson> observable,
               ContactPerson oldValue, ContactPerson newValue) {
               if (observable != null &&
                     observable.getValue() != null) {
                  contactPeopleList.clear();
                  contactPeopleList.addAll(
                     contact.getContactsForName
                        (newValue.getName()));
                  }
               }
            });
      primaryStage.setScene(scene);
      primaryStage.show();
   }
   public static void main(String[] args) {
      launch (args);
   }
}

Uscita


Figura 1: Uscita codice

Conclusione

Un'applicazione JDBC con JavaFX significa essenzialmente che il framework GUI JavaFX è stato utilizzato come motore di sviluppo front-end e JDBC è stato utilizzato per l'interazione con il database back-end. Possono essere di varietà di tipi con N numero di funzionalità in esse definite. La base è l'applicazione CRUD. Abbiamo implementato una parte dell'operazione di ricerca e visualizzazione. Ecco cosa puoi fare per estenderlo:implementare Crea , Elimina e Aggiorna operazioni; inoltre, puoi aggiungere nomi con immagini in ListView . Buona codifica 😉