Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
laboratoare:laborator09 [2015/12/18 01:55]
Andrei Roșu-Cojocaru
laboratoare:laborator09 [2015/12/28 15:52] (current)
Andrei Roșu-Cojocaru
Line 7: Line 7:
   * identificarea principalelor componente din cadrul arhitecturii JavaFX;   * identificarea principalelor componente din cadrul arhitecturii JavaFX;
   * descrierea structurii generale a unei aplicații JavaFX și a firelor de execuție din contextul cărora pot fi accesate obiectele corespunzătoare controalelor grafice, respectiv interacțiunii cu utilizatorul;​   * descrierea structurii generale a unei aplicații JavaFX și a firelor de execuție din contextul cărora pot fi accesate obiectele corespunzătoare controalelor grafice, respectiv interacțiunii cu utilizatorul;​
-  * implementarea unei interfețe cu utilizatorul folosind Scene Builder ​2.0 / FXML cu injectarea controalelor grafice / metodelor de tratare a evenimentelor în clasa controller din codul sursă;+  * implementarea unei interfețe cu utilizatorul folosind Scene Builder / FXML cu injectarea controalelor grafice / metodelor de tratare a evenimentelor în clasa controller din codul sursă;
   * înțelegerea mecanismului de tratare a evenimentelor legate de interacțiunea cu utilizatorul în JavaFX; dezvoltarea de filtre și metode de tratare pentru diferite acțiuni ale utilizatorului;​   * înțelegerea mecanismului de tratare a evenimentelor legate de interacțiunea cu utilizatorul în JavaFX; dezvoltarea de filtre și metode de tratare pentru diferite acțiuni ale utilizatorului;​
   * însușirea practicilor utilizate pentru dezvoltarea aplicațiilor JavaFX.   * însușirea practicilor utilizate pentru dezvoltarea aplicațiilor JavaFX.
Line 28: Line 28:
   * **integrare cu Java**. JavaFX ​ este o interfaţă de programare integrată în distribuţia limbajului de programare Java, instalarea sa făcându-se împreună cu acesta; prin urmare, din JavaFX pot fi accesate toate API-urile Java cu funcţionalităţile lor, acesta reprezentând o alternativă la celelalte limbaje de programare care folosesc Java Virtual Machine, precum JRuby sau Scala; ​   * **integrare cu Java**. JavaFX ​ este o interfaţă de programare integrată în distribuţia limbajului de programare Java, instalarea sa făcându-se împreună cu acesta; prin urmare, din JavaFX pot fi accesate toate API-urile Java cu funcţionalităţile lor, acesta reprezentând o alternativă la celelalte limbaje de programare care folosesc Java Virtual Machine, precum JRuby sau Scala; ​
   * **limbajul de adnotare FXML şi utilitarul SceneBuilder**. FXML este un limbaj declarativ de adnotare bazat pe XML prin intermediul căruia pot fi dezvoltate interfeţe grafice cu utilizatorul,​ fără a fi necesar ca aplicaţia să fie recompilată de fiecare dată când sunt modificate elemente din cadrul acesteia. În acest mod se realizează o separare între nivelul de prezentare și nivelul de logică a aplicației. SceneBuilder permite construirea interfeţei în mod vizual, generând automat şi documentul FXML asociat, acesta putând fi integrat apoi în orice mediu de dezvoltare. Astfel, nu mai este necesară decât implementarea mecanismelor de tratare a evenimentelor corespunzătoare diferitelor controale (elemente din cadrul interfeței grafice);   * **limbajul de adnotare FXML şi utilitarul SceneBuilder**. FXML este un limbaj declarativ de adnotare bazat pe XML prin intermediul căruia pot fi dezvoltate interfeţe grafice cu utilizatorul,​ fără a fi necesar ca aplicaţia să fie recompilată de fiecare dată când sunt modificate elemente din cadrul acesteia. În acest mod se realizează o separare între nivelul de prezentare și nivelul de logică a aplicației. SceneBuilder permite construirea interfeţei în mod vizual, generând automat şi documentul FXML asociat, acesta putând fi integrat apoi în orice mediu de dezvoltare. Astfel, nu mai este necesară decât implementarea mecanismelor de tratare a evenimentelor corespunzătoare diferitelor controale (elemente din cadrul interfeței grafice);
-  * **componente WebView**. Un modul ce foloseşte tehnologia WebKitHTML permite integrarea de pagini Internet în cadrul unei interfeţe grafice. De asemenea, codul JavaScript ce rulează în WebView poate accesa orice API-uri Java, la fel cum API-urile Java pot executa cod JavaScript care rulează în WebView. Există suport și pentru anumite funcționalități HTML5 (Web Sockets, Web Workers, Web Fonts) sau capabilități de tipărire;​ +  * **componente WebView**. Un modul ce foloseşte tehnologia WebKitHTML permite integrarea de pagini Internet în cadrul unei interfeţe grafice. De asemenea, codul JavaScript ce rulează în [[https://​docs.oracle.com/​javase/​8/​javafx/​api/​javafx/​scene/​web/​WebView.html|WebView]] poate accesa orice API-uri Java, la fel cum API-urile Java pot executa cod JavaScript care rulează în WebView. Există suport și pentru anumite funcționalități HTML5 (Web Sockets, Web Workers, Web Fonts) sau capabilități de tipărire;​ 
-  * **interoperabilitate cu tehnologia Swing**. Aplicaţiile Swing existente pot fi extinse cu funcţionalităţi JavaFX, ca redarea de conţinuturi grafice sau a unor pagini Internet integrate. Clasa ''​SwingNode'' ​permite integrarea unui conținut dezvoltat folosind tehnologia Swing în cadrul aplicației JavaFX; +  * **interoperabilitate cu tehnologia Swing**. Aplicaţiile Swing existente pot fi extinse cu funcţionalităţi JavaFX, ca redarea de conţinuturi grafice sau a unor pagini Internet integrate. Clasa [[https://​docs.oracle.com/​javase/​8/​javafx/​api/​javafx/​embed/​swing/​SwingNode.html|SwingNode]] permite integrarea unui conținut dezvoltat folosind tehnologia Swing în cadrul aplicației JavaFX; 
-  * **biblioteci de controale şi foi de stil**. JavaFX pune la dispoziţia programatorilor majoritatea controalelor necesare pentru dezvoltarea unei interfeţe cu utilizatorul complete (inclusiv ​''​DatePicker'' ​și ''​TreeTableView''​), aspectul acestora putând fi particularizat folosind tehnologii web standard ca foile de stil (//eng.// CSS – cascading style sheets), prin intermediul claselor ''​Styleable*'';​+  * **biblioteci de controale şi foi de stil**. JavaFX pune la dispoziţia programatorilor majoritatea controalelor necesare pentru dezvoltarea unei interfeţe cu utilizatorul complete (inclusiv ​[[https://​docs.oracle.com/​javase/​8/​javafx/​api/​javafx/​scene/​control/​DatePicker.html|DatePicker]] ​și [[https://​docs.oracle.com/​javase/​8/​javafx/​api/​javafx/​scene/​control/​TreeTableView.html|TreeTableView]]), aspectul acestora putând fi particularizat folosind tehnologii web standard ca foile de stil (//eng.// CSS – cascading style sheets), prin intermediul claselor ''​Styleable*'';​
   * **tema Modena** este folosită ca implicită pentru toate aplicațiile JavaFX (înlocuind tema Caspian, care poate fi utilizată prin apelul metodei ''​setUserAgentStylesheet(STYLESHEET_CASPIAN)''​ în metoda ''​start()''​ a clasei derivate din ''​Application'';​   * **tema Modena** este folosită ca implicită pentru toate aplicațiile JavaFX (înlocuind tema Caspian, care poate fi utilizată prin apelul metodei ''​setUserAgentStylesheet(STYLESHEET_CASPIAN)''​ în metoda ''​start()''​ a clasei derivate din ''​Application'';​
   * **funcționalități de grafică 3D**. Biblioteca de grafică 3D a fost îmbogățită prin:   * **funcționalități de grafică 3D**. Biblioteca de grafică 3D a fost îmbogățită prin:
Line 1993: Line 1993:
 ==== JavaFX Scene Builder ==== ==== JavaFX Scene Builder ====
  
-Documentele FXML pot fi dezvoltate în mod vizual folosind utilitarul [[http://www.oracle.com/technetwork/java/javase/​downloads/​sb2download-2177776.html|SceneBuilder]],​ disponibil pe platformele Windows (32/64 de biţi), Mac OS X şi Linux (32/64 biţi) – sub formă de pachete ''​.deb''​ şi arhive ''​tar.gz''​. ​+Documentele FXML pot fi dezvoltate în mod vizual folosind utilitarul [[http://gluonhq.com/open-source/scene-builder/​|SceneBuilder]],​ disponibil pe platformele Windows (32/64 de biţi), Mac OS X şi Linux (32/64 biţi) – sub formă de pachete ''​.deb''​ şi arhive ''​tar.gz''​. ​
  
 Acesta permite construirea interfeței grafice interactiv, simultan cu generarea automată a documentului FXML, fiecare control putând fi configurat, grupate în proprietăţi,​ moduri de dispunere şi cod. Acesta permite construirea interfeței grafice interactiv, simultan cu generarea automată a documentului FXML, fiecare control putând fi configurat, grupate în proprietăţi,​ moduri de dispunere şi cod.
Line 2177: Line 2177:
  
 În privinţa nivelului de logică a aplicaţiei,​ cele mai frecvent uzitate tehnici sunt:  În privinţa nivelului de logică a aplicaţiei,​ cele mai frecvent uzitate tehnici sunt: 
-  * folosirea ​ecrane animatelor ​care să indice progresul acelor procese de lungă durată astfel încât aplicaţia să nu pară că nu răspunde la interacţiunea cu utilizatorul;​+  * folosirea ​ecranelor animate ​care să indice progresul acelor procese de lungă durată astfel încât aplicaţia să nu pară că nu răspunde la interacţiunea cu utilizatorul;​
   * folosirea unor denumiri simbolice pentru pachetele implementate pentru ca aplicaţia să fie mai organizată şi mai uşor de întreţinut;​   * folosirea unor denumiri simbolice pentru pachetele implementate pentru ca aplicaţia să fie mai organizată şi mai uşor de întreţinut;​
   * implementarea arhitecturii model-view-controller (MVC) prin intermediul fişierelor FXML pentru definirea scenelor, acestea reprezentând partea de vizualizare,​ în timp ce modelul este reprezentat de obiectele de domeniu specifice aplicaţiei,​ iar partea de control aparţine codului Java care defineşte comportamentul interfeţei grafice în interacţiunea cu utilizatorul;​   * implementarea arhitecturii model-view-controller (MVC) prin intermediul fişierelor FXML pentru definirea scenelor, acestea reprezentând partea de vizualizare,​ în timp ce modelul este reprezentat de obiectele de domeniu specifice aplicaţiei,​ iar partea de control aparţine codului Java care defineşte comportamentul interfeţei grafice în interacţiunea cu utilizatorul;​
Line 2385: Line 2385:
  
 <​spoiler|Indicații de Rezolvare>​ <​spoiler|Indicații de Rezolvare>​
 +Se parcurge, în cadrul unei iterații, lista de controale, acestea putând avea tipul: 
 +  - ''​ComboBox'':​ se folosește metoda ''​setValue()''​ primind ca argument șirul vid: ''​%%((ComboBox<​String>​) attributeControl).setValue(""​);​%%'';​ 
 +  - ''​TextField'':​ se utilizează metoda ''​setText()''​ primind ca argument: 
 +    - valoarea maximă a cheii primare în cadrul tabelei (pentru indexul 0, corespunzător identificatorului),​ prin intermediul metodei ''​getTablePrimaryKeyMaximimValue()'',​ disponibilă în interfața ''​DatabaseOperations'':​ ''​%%((TextField) attributeControl).setText(Integer.toString(databaseOperations.getTablePrimaryKeyMaximumValue(tableName) + 1));​%%'';​ 
 +    - șirul vid, altfel: ''​%%((TextField) attributeControl).setText(""​);​%%''​.
 </​spoiler>​ </​spoiler>​
  
Line 2391: Line 2395:
  
 <​spoiler|Indicații de Rezolvare>​ <​spoiler|Indicații de Rezolvare>​
 +În clasa ''​Container''​ din pachetul ''​ro.pub.cs.aipi.lab09.controller''​ se instanțiază un obiect de tip ''​Dialog''​ pentru care se specifică următoarele proprietăți:​
 +  * titlul este ''​Constants.ABOUT_WINDOW_TITLE'';​
 +  * locația de la care se va încărca pictograma este ''​Constants.ABOUT_ICON_LOCATION'';​
 +  * mesajul care va fi vizualizat este ''​Constants.ABOUT_MESSAGE_CONTENT''​.
 +Fereastra trebuie afișată prin invocarea metodei ''​start()''​.
  
 +<code java>
 +Dialog dialog = new Dialog();
 +dialog.setProperties(Constants.ABOUT_WINDOW_TITLE,​ Constants.ABOUT_ICON_LOCATION,​ Constants.ABOUT_MESSAGE_CONTENT);​
 +dialog.start();​
 +</​code>​
 </​spoiler>​ </​spoiler>​
  
Line 2397: Line 2411:
  
 <​spoiler|Indicații de Rezolvare>​ <​spoiler|Indicații de Rezolvare>​
 +În clasa ''​TableManagement''​ din pachetul ''​ro.pub.cs.aipi.lab09.controller'',​ se va implementa metoda ''​searchButtonHandler()'',​ în cadrul căreia va fi parcursă, în cadrul unei iterații, lista de controale, pentru a se obține perechea de atribute și de valori pe baza cărora va fi realizată căutarea.
 +  - dacă controlul este de tip ''​ComboBox''​ se identifică valoarea din tabela referită corespunzătoare atributului,​ prin invocarea metodei ''​getForeignKeyValue()'':​ <code java>
 +if (attributeControl instanceof ComboBox) {
 +  try {
 +    String parentTableValues = ((ComboBox<​String>​) attributeControl).getValue();​
 +    if (parentTableValues != null && !parentTableValues.isEmpty()) {
 +      value = databaseOperations.getForeignKeyValue(tableName,​ attributesLabels.get(currentIndex).getText(),​ Utilities.decompress(parentTableValues));​
 +    }
 +  } catch (Exception exception) {
 +    System.out.println("​An exception had occured: " + exception.getMessage());​
 +    if (Constants.DEBUG) {
 +      exception.printStackTrace();​
 +    }
 +  }
 +}
 +</​code> ​
 +  - în situația în care controlul este de tip ''​TextField'',​ se identifică valoarea prin intermediul metodei ''​getText()'':​ ''​%%value = ((TextField) attributeControl).getText();​%%''​
  
 +Se construiește clauza ''​WHERE''​ a interogării pe baza căreia este realizată căutarea folosind șablonul ''​atribut='​%valoare%''',​ aceasta fiind transmisă ca parametru al metodei ''​populateTableView()'':​ <code java>
 +for (Control attributeControl : attributesControls) {
 +  // ...
 +  if (value != null && !value.isEmpty() && currentIndex != 0) {
 +    whereClause += ((whereClause.isEmpty()) ? ""​ : " AND ") + attributesLabels.get(currentIndex).getText() + " LIKE \'​%"​ + Utilities.escape(value) + "​%\'";​
 +  }
 +  currentIndex++;​
 +  // ...
 +}
 +populateTableView(!whereClause.isEmpty() ? whereClause : null);
 +</​code>​
 </​spoiler>​ </​spoiler>​
  
-**8**. Să se creeze o animaţie asupra butonului deasupra căruia se găseşte mouse-ul astfel încât acesta să aibă un efect de tip umbră exterioară (''​DropShadow''​) implementând şi o tranziţie care pe parcursul unei secunde modifică transparenţa de la 1.0 la 0.8 şi scalează dimensiunile cu 0.1. Animaţia trebuie cât timp mouse-ul se găseşte deasupra butonului având un caracter ciclic. Metoda se va implementa pentru toate butoanele ce realizează modificări asupra înregistrărilor din baza de date.+**8**. Să se creeze o animaţie asupra butonului deasupra căruia se găseşte mouse-ul astfel încât acesta să aibă un efect de tip umbră exterioară ([[https://​docs.oracle.com/​javafx/​2/​api/​javafx/​scene/​effect/​DropShadow.html|DropShadow]]) implementând şi o tranziţie care pe parcursul unei secunde modifică transparenţa de la 1.0 la 0.8 şi scalează dimensiunile cu 0.1. Animaţia trebuie cât timp mouse-ul se găseşte deasupra butonului având un caracter ciclic. Metoda se va implementa pentru toate butoanele ce realizează modificări asupra înregistrărilor din baza de date.
  
 <​spoiler|Indicații de Rezolvare>​ <​spoiler|Indicații de Rezolvare>​
 +Se creează următoarele efecte:
 +  - o umbră care va fi aplicată butoanelor (un obiect de tip ''​DropShadow''​);​
 +  - o animație de tip dispariție având transparențele variabile între 1 și 0.8, cu durata de 1 secundă, care se va repeta nedefinit (un obiect de tip ''​FadeTransition''​);​
 +  - o animație de tip scalare, având valorile de 0.1 atât pe axa Ox cât și pe aza Oy, cu durata de 1 secundă, care va rula nedefinit (un obiect de tip ''​ScaleTransition''​);​
 +  - un efect paralel, care include animațiile de tip dispariție,​ respectiv scalare, care vor fi aplicate concomitent (un obiect de tip ''​ParallelTransition''​).
  
 +<code java>
 +final DropShadow dropShadow = new DropShadow();​
 +final FadeTransition fadeTransition = new FadeTransition(Duration.seconds(1));​
 +fadeTransition.setFromValue(1.0f);​
 +fadeTransition.setToValue(0.8f);​
 +fadeTransition.setCycleCount(Timeline.INDEFINITE);​
 +fadeTransition.setAutoReverse(true);​
 +final ScaleTransition scaleTransition = new ScaleTransition(Duration.seconds(1));​
 +scaleTransition.setByX(0.1f);​
 +scaleTransition.setByY(0.1f);​
 +scaleTransition.setCycleCount(Timeline.INDEFINITE);​
 +scaleTransition.setAutoReverse(true);​
 +final ParallelTransition parallelTransition = new ParallelTransition(fadeTransition,​ scaleTransition);​
 +</​code>​
 +
 +Pentru fiecare buton în parte, se vor defini metodele ascultător pentru fiecare dintre cele două evenimente:
 +  - ''​MouseEvent.MOUSE_ENTERED''​ - se sta stabilește efectul de tip umbră, se transmite nodul ca obiect al animațiilor de tipul ''​Fade''​ și ''​Scale'',​ după care tranziția paralelă este începută , folosind metoda ''​play()'';​
 +  - ''​MouseEvent.MOUSE_EXITED''​ - se pierd efectele anterioare (metoda ''​setEfect()''​ primește argumentul null), durata animației devine 0, animațiile pierd referința de pe nod, iar tranziția paralelă este oprită, folosind metoda ''​stop()''​.
 +
 +<code java>
 +buttonList.stream().map((currentButton) -> {
 +  currentButton.addEventHandler(MouseEvent.MOUSE_ENTERED,​ (MouseEvent event) -> {
 +    currentButton.setEffect(dropShadow);​
 +    fadeTransition.setNode(currentButton);​
 +    scaleTransition.setNode(currentButton);​
 +    parallelTransition.play();​
 +  });
 +  return currentButton;​
 +}).forEach((currentButton) -> {
 +  currentButton.addEventHandler(MouseEvent.MOUSE_EXITED,​ (MouseEvent event) -> {
 +    currentButton.setEffect(null);​
 +    parallelTransition.jumpTo(Duration.ZERO);​
 +    fadeTransition.setNode(null);​
 +    scaleTransition.setNode(null);​
 +    parallelTransition.stop();​
 +    parallelTransition.setNode(null);​
 +  });
 +});
 +</​code>​
 </​spoiler>​ </​spoiler>​
  
Line 2413: Line 2499:
 ===== Soluții ===== ===== Soluții =====
  
-TODO+[[https://​github.com/​aipi2015/​Laborator09/​tree/​master/​solutions/​eclipse/​09-BookStore-JavaFX|Proiect Eclipse]]\\  
 +[[https://​github.com/​aipi2015/​Laborator09/​tree/​master/​solutions/​netbeans/​09-BookStore-JavaFX|Proiect NetBeans]]
laboratoare/laborator09.1450396537.txt.gz · Last modified: 2015/12/18 01:55 by Andrei Roșu-Cojocaru
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0