×

ARDUINO

Control d’accés amb contrasenya. Orgue de llums. Comparativa de editors Arduino. Projecte bon Nadal. Sensor de gas i de fums. Control de la qualitat del aire interior (CO2) amb semàfor LED.

NodeMCU

NodeMCU-ThingSpeak. ThingSpeak. NodeMCU com AccessPoint. Control de la llum de casa per web. Control de un led per el mòbil. Sistema de fitxers en ESP8266. Altura del nivell d'aigua. Avis d’alarma a Telegram. Control de la llum de casa des de Telegram. Control de la intensitat de llum de un LED per Internet. Magatzematge de temperatura i humitat en Thinger. Publicar temperatura i humitat en Google Sheets. ESP8266 i Firebase. ESP8266-BME280 Firebase. La bàscula. ESP8266 NodeMCU amb cèl·lula de càrrega..

ESP32

ESP32-CAM, exemple de prova. Esp32-Cam captura fotos per ser vistes en la WEB. Pujar fotos a un servidor FTP amb ESP32-CAM. Foto amb ESP32-CAM i Telegram. Alarma amb avis a Telegram, utilitzant la placa ESP32-CAM.

PROGRAMACIÓ

Matemàtiques. App Inventor tutorial. MicroPython en ESP8266. Visual Estudio Code per Arduino

Intel·ligència artificial

Classificador d’imatges.

SERVIDORS

Instal·lar i configurar Apache en Ubuntu. Accés a un servidor Linux remotament. Client i Servidor FTP.

MÀQUINES VIRTUALS

Màquina virtual UBUNTU. WindowsXP en Virtualbox.

ELECTRÒNICA

Simulador Multisim. Simulador Proteus.

BASE DE DADES

MySQL. Instal·lació. MySQL. Aplicacions.

JAVA

Netbeans Maven MySQL. Java+Netbeans+Maven+EclipseLink+MySQL Aplicació d’escriptori JavaFX App JavaFX amb SceneBuilder App Java-Swing
favicon
logo

Tresavis

Benvinguts al blog de tresavis de noves tecnologies i més.

Correu : tresavis3@gmail.com

facebook   Instagram   youtube   x   tiktok

☰ Pràctiques   ☰ Articles

Vídeo 1ª part


Programari

El programari que fem servir per desenvolupar l’aplicació és:

Windows 11

JDK 20

Apache Netbeans 18

Ant

EclipseLink

Java Swing

MySQL 8

Finalitat

Manteniment de la base de dades MySQL: compres

Compres té dues taules : proveïdor i despesa. La relació és de 1 a n. Un proveïdor pot tenir moltes despeses però una despesa és de un sol proveïdor.

Els Id de cada taula són clau primaria i auto-increment.

JavaSwing2

Volem a arribar a una vista de proveïdors amb una taula que mostri tots els proveïdors i un botó i tres camps de text per inserir nous proveïdors.

JavaSwing3

Projecte Compres

Creem un nou projecte Java: with Ant/Java Application

JavaSwing4

Posem el nom i des-cliquem en crear una classe principal

JavaSwing5

MySQL connector Java

Descarreguem el connector de Java per MySQL en la següent pàgina:

https://dev.mysql.com/downloads/connector/j/

Escollim la plataforma independent i descarreguem el ZIP

JavaSwing6

Obrim el ZIP i guardem el .jar

JavaSwing7

Llibreries

MySQL Connector:

En el projecte en llibreries, add jar/Folder, busquem el .jar

EclipseLink:

En llibreries / add Library i escollim EclipseLink

JavaSwing8

Unitat de persistencia

Sobre el projecte / botó dret / new / Persistence Unit

JavaSwing9

Es crea el fitxer persistence.xml a dins de la carpeta META_INF:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence           http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
  <persistence-unit name="UnitatPersistencia" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
   <class>Models.Despesa</class>
  <class>Models.Proveidor</class>
    <properties>
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/compres?zeroDateTimeBehavior=CONVERT_TO_NULL"/>
     <property name="javax.persistence.jdbc.user" value="root"/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.password" value="123456"/>
     <property name="javax.persistence.schema-generation.database.action" value="create"/>
   </properties>
  </persistence-unit>
</persistence>            
        

Models

Sobre el projecte / botó dret / new / Java Package / Models

Es crea el nou Package Models

Sobre Models / new / Entity Classes from Database

Automàticament es creant dues classes: proveidor.java i despesa.java

Els atributs de les classes són les columnes de les taules. Cada classe té els constructors els get i els set

Controladors

Sobre el projecte / botó dret / new / Java Package / Controladors

Sobre Controladors / new / JPA Controller Classes from Entity Classes

Automàticament es creen dues classes: ProveidorJpaController.java i DespesaJpaController.java

Aquestes classes contenen els mètodes: create, destroy, edit, find... per mantenir la base de dades

JavaSwing910
JavaSwing11

JFrame VistaProveidor.java

Sobre Source Package / New / JFrame Form

S’obre el disseny de la nova vista:

JavaSwing12

Si cliquem sobre Source es mostra el codi de la vista:

JavaSwing13

El constructor on posarem el nostre codi i que ja conté el mètode initComponents() que es crea automàticament i només es pot modificar en el disseny. El mètode principal main que amb el mètode run fa visible la vista.

Classe principal

Assignem la VistaProveidor.java com a classe principal

Botó dret sobre el projecte / propietats / Run / busquem en Main Class la nostre VistaProveidor.java

JavaSwing14

Taula

En VistaProveidor en el disseny arrastrem en el JFrame una Table

Clic en la taula i en les propietats / model / canviem els noms de les columnes així com el tipus d’objecte. Posem els Rows a 0

JavaSwing15

Codi per mostrar proveïdors en la taula:

    public class VistaProveidor extends javax.swing.JFrame {

    private static final String UNITAT_PERSISTENCIA = "UnitatPersistencia";
    private static final EntityManagerFactory FACTORIA = Persistence.createEntityManagerFactory(UNITAT_PERSISTENCIA);
    private static ProveidorJpaController controladorProveidor = new ProveidorJpaController(FACTORIA);

    /**
     * Creates new form VistaProveidor
     */
    public VistaProveidor() {
        initComponents();
        mostrarProveidors();
    }

    private static void mostrarProveidors() {
        List proveidors = new ArrayList<>();
        proveidors = controladorProveidor.findProveidorEntities();
        afegirProveidorsTaula(proveidors, jTaula);        
    }

    private static void afegirProveidorsTaula(List proveidors, JTable jTaula) {
        for (Proveidor p : proveidors) {
            ((DefaultTableModel) jTaula.getModel()).addRow(new Object[]{
                p.getId(),
                p.getNom(),
                p.getTelefon()
            });
        }
    }        
        

Primer hem instanciat el controladorProveidor de la classe ProveidorJpaController

En el constructor hem posat el nostre mètode mostrarProveidors()

Omple una llista buida amb el mètode del controladorProveidor

      proveidors = controladorProveidor.findProveidorEntities();      
        

Amb un for per cada proveïdor a dins de la llista de proveïdors amb el mètode de model addRow afegim el id , el nom i el telèfon

            ((DefaultTableModel) jTaula.getModel()).addRow(new Object[]{
                p.getId(),
                p.getNom(),
                p.getTelefon()
            });            
        

Vídeo 2ª part


Botó Inserir proveïdors

Arrastrem un botó sobre el JFrame, canviem el nom de la variable a btoInserir

Clic dues vegades sobre el botó i sobre el codi amb l’enunciat de mètode

JavaSwing16

El codi per inserir nous proveïdors és com el que segueix:

private void btnInserirActionPerformed(java.awt.event.ActionEvent evt) {                                           
    //id es autoincrement
    String nom = txtNom.getText();
    String telefon = txtTelefon.getText();
    if (nom.compareTo("") != 0
            && telefon.compareTo("") != 0) {

        Proveidor p = new Proveidor();

        p.setNom(nom);
        p.setTelefon(telefon);
        controladorProveidor.create(p);
        buidarTaula();
        mostrarProveidors();
    } else {
        JOptionPane.showMessageDialog(jTaula,
                "El nom i el telèfon son obligatoris",
                "ERROR al inserir",
                JOptionPane.WARNING_MESSAGE);
    }
}       
        

Obtenim el nom i el telèfon dels camps de text, el id no cal, el posa la base de dades, ja que és un valor auto-increment

En el if comparem si els camps estan plens, altrament saltem al missatge d’error del else

Si entrem en el if creem un objecte Proveidor buit i l’omplim amb els setNom() i setTelefon()

El mètode create(Proveidor) del controladorProveidor insereix el nou proveïdor a la base de dades

Buidem la taula i la tornem a mostrar

Mètode de buidarTaula():

private void buidarTaula() {
    DefaultTableModel model = (DefaultTableModel) jTaula.getModel();
    model.setRowCount(0);
}            
        

Obtenim el model de la taula i posem el comptador de files a 0

JFrame VistaDespesa.java

Creem una nova vista (JFrame Form) VistaDespesa

Col·loquem la taula jTaula, els noms de les columnes, el tipus d’objecte i el comptador de les files a 0

JavaSwing17

Vídeo 3ª part


Mostrar despeses

El codi per mostrarDespeses():

private static void mostrarDespeses() {
    List despeses = new ArrayList<>();
    despeses = controladorDespesa.findDespesaEntities();
    afegirDespesesTaula(despeses, jTaula);
}

private static void afegirDespesesTaula(List despeses, JTable jTaula) {
    for (Despesa d : despeses) {
        ((DefaultTableModel) jTaula.getModel()).addRow(new Object[]{
            d.getDespesaPK().getId(),
            d.getData(),
            d.getTotal(),
            d.getProveidor().getNom(),
            d.getProveidor().getId()
        });
    }
}            
        

És igual a la vista proveïdors, només canvia les columnes de la taula

Codi Inserir

Col·loquem un botó per inserir noves despeses, clic sobre el botó dues vegades i en el mètode creat en el codi i posem el següent :

private void btnInserirActionPerformed(java.awt.event.ActionEvent evt) {                                           
    // Les variables id i la data no cal entrar-les
    String totalStr = txtTotal.getText();
    String idProveidorStr = cbProveidor.getSelectedItem().toString();
    float total = Float.parseFloat(totalStr);
    int idProveidor = Integer.parseInt(idProveidorStr);
    //comparem si els camps estan plens
    if (totalStr.compareTo("") != 0
            && esValidFloat(totalStr)
            && idProveidorStr.compareTo("") != 0) {

        Despesa d = new Despesa();
        Proveidor p = controladorProveidor.findProveidor(idProveidor);
        //posem valors a la despesa d
        d.setTotal(total);
        d.setProveidor(p);
        try {
            d.setData(java.sql.Date.from(now()));
        } catch (Exception e) {
        }
        //inserim la despesa d
        try {
            controladorDespesa.create(d);
        } catch (Exception ex) {
            Logger.getLogger(VistaDespeses.class.getName()).log(Level.SEVERE, null, ex);
        }

        buidarTaula();
        mostrarDespeses();
    } else {
        JOptionPane.showMessageDialog(jTaula, """
                                              El total i el prove\u00efdor son obligatoris
                                              El total ha de ser un nombre v\u00e0lid""",
                "ERROR al inserir",
                JOptionPane.WARNING_MESSAGE);
    }
}  
            
        

La variables id de la despesa no cal ja que la taula es auto-increment i agafa el valor automàticament

La variable data tampoc cal posar-la en el camp de text, posarem la data actual

Obtenim el total del camp txtTotal i el id del proveïdor del ComboBox

Amb un if comparem si el camps estan plens i si el total és un número vàlid. Si és així continuem, altrament saltem al else amb un missatge de error

A dins del if, creem una despesa buida. Obtenim el objecte Proveidor amb el controlador i el seu mètode findProveidor i d’argument el id del proveïdor

A dins del if, creem una despesa buida. Obtenim el objecte Proveidor amb el controlador i el seu mètode findProveidor i d’argument el id del proveïdor

Omplim la despesa buida amb el total el proveïdor i la data amb el mètode now()

Inserim la nova despesa amb:

controladorDespesa.create(d);       
        

Buidem la taula i la tornem a mostrar

Per saber si el total es un número vàlid fem sevir el següent mètode:

private boolean esValidFloat(String valor) {
    try {
        Float.parseFloat(valor);
        return true;
    } catch (NumberFormatException ex) {
        return false;
    }
}            
        

A dins d’un try-catch, en el try si accepta :

Float.parseFloat(valor);            
        

Vol dir que si el valor es vàlid, retorna true, altrament salta al catch i retorna false

Codi al sel·leccionar una fila de la taula

Creem un event a la taula que al fer clic sobre una fila es mostren els valors de la fila en els camps de text

Amb la taula seleccionada, en Events anem a MouseClicked, clic i s’obre el codi amb el mètode buit

JavaSwing19

Posem el següent codi:

JavaSwing20
private void jTaulaMouseClicked(java.awt.event.MouseEvent evt) {                                    
    DefaultTableModel model = (DefaultTableModel) jTaula.getModel();
    int filaSeleccionada = jTaula.getSelectedRow();
    txtId.setText(model.getValueAt(filaSeleccionada, 0).toString());
    txtData.setText(model.getValueAt(filaSeleccionada, 1).toString());
    txtTotal.setText(model.getValueAt(filaSeleccionada, 2).toString());
    cbProveidor.setSelectedItem(jTaula.getValueAt(filaSeleccionada, 3).toString());
}             
        

Codi omplir ComboBox

Per omplir el ComboBox de proveïdors, primer anem a les propietats del component i eliminem els items que hi han per defecte. Anem a Properties / model / tres punts / Reset to Default

JavaSwing21

Codi per omplir el ComboBox amb els id dels proveïdors:

private void omplirComboBoxProveidors() {
    List proveidors = new ArrayList<>();
    proveidors = controladorProveidor.findProveidorEntities();
    for (Proveidor p : proveidors) {
        cbProveidor.addItem(p.getId() + "");
    }
}       
        

Una vegada hem emplenat la llista de proveïdors de la base de dades, a dins d’un for, per cada proveïdor p en la llista de proveïdors, fem:

cbProveidor.addItem(p.getId() + "");            
        

p.getId() retorna un int, el convertim a String afegint “”

Vídeo 4ª part


Codi inserir despeses

Ja està explicat en la 3ª part

Botó eliminar despesa i el seu codi

Codi del botó btoEliminar:

private void btoEliminarActionPerformed(java.awt.event.ActionEvent evt) {                                            
    int filaSeleccionada=jTaula.getSelectedRow();
    int id = (Integer) jTaula.getModel().getValueAt(filaSeleccionada, 0);
    int proveidorId = (Integer) jTaula.getModel().getValueAt(filaSeleccionada, 4);

    buidarTaula();
    //destroy(DespesaPK); constructor: DespesaPK(proveidorId, id)
    try {
        controladorDespesa.destroy(new DespesaPK(proveidorId, id));
    } catch (NonexistentEntityException ex) {
        Logger.getLogger(VistaDespeses.class.getName()).log(Level.SEVERE, null, ex);
    }
    mostrarDespeses();
}             
        

El mètode del controladorDespesa: destroy(DespesaPK)

Demana un objecte DespesaPK com argument i per construir-lo necessitem el constructor: DespesaPK(proveidorId, id)

Té com argument el proveidorId i el id de la despesa

Obtenim la fila seleccionada:

int filaSeleccionada=jTaula.getSelectedRow();                  
        

Obtenim proveidorId i el id de la fila i la columna seleccionada:

int id = (Integer) jTaula.getModel().getValueAt(filaSeleccionada, 0);
int proveidorId = (Integer) jTaula.getModel().getValueAt(filaSeleccionada, 4);            
        

Buidem la taula

Eliminem la despesa:

controladorDespesa.destroy(new DespesaPK(proveidorId, id));            
        

Mostrem les despeses actualitzades

Botó eliminar proveïdor i el seu codi

Codi del botó btoEliminar proveïdors:

private void btoEliminarActionPerformed(java.awt.event.ActionEvent evt) {                                            
    int id =(Integer) jTaula.getModel().getValueAt(jTaula.getSelectedRow(), 0);
    Proveidor p=controladorProveidor.findProveidor(id);
    if(p.getDespesaCollection().isEmpty()){
        try {
            controladorProveidor.destroy(id);
        } catch (IllegalOrphanException ex) {
            Logger.getLogger(VistaProveidor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NonexistentEntityException ex) {
            Logger.getLogger(VistaProveidor.class.getName()).log(Level.SEVERE, null, ex);
        }
        buidarTaula();
        mostrarProveidors();
    }else{
        JOptionPane.showMessageDialog(jTaula,
                "El proveïdor no es pot eliminar perquè té despeses.\n"
                        + "Cal primer eliminar les despeses associades.",
                "ERROR al eliminar proveïdor",
                JOptionPane.WARNING_MESSAGE);
    }
}               
        

Obtenim el objecte Proveïdor que té com id el de la fila seleccionada:

Proveidor p=controladorProveidor.findProveidor(id);               
        

Si el proveïdor té despeses no el podem eliminar. Hem de comprovar-ho. Ho fem amb un if:

if(p.getDespesaCollection().isEmpty())              
        

Si no té despeses el podem eliminar:

controladorProveidor.destroy(id);            
        

Event de la taula al clicar sobre una fila de la taula Despeses

Al clicar en una fila de la taula volem que els seus valors es mostrin en els camps de text

En Events de la taula / models /mouseClicket / es forma el mètode que hem de programar:/p>

private void jTaulaMouseClicked(java.awt.event.MouseEvent evt) {                                    
    DefaultTableModel model = (DefaultTableModel) jTaula.getModel();
    int filaSeleccionada = jTaula.getSelectedRow();
    txtId.setText(model.getValueAt(filaSeleccionada, 0).toString());
    txtData.setText(model.getValueAt(filaSeleccionada, 1).toString());
    txtTotal.setText(model.getValueAt(filaSeleccionada, 2).toString());
    cbProveidor.setSelectedItem(jTaula.getValueAt(filaSeleccionada, 3).toString());
}             
        

Obtenim el model de la taula

Obtenim la fila seleccionada

Omplim els camps de text i el ComboBox amb la fila i les columnes corresponents

Omplir ComboBox anys

Codi per omplir el cbAnys:

private void omplirComboBoxAnys() {
    for (int any = 2023; any < 2031; any++) {
        cbAnys.addItem(any);
    }
}

Amb un for des de l’any actual fins l’any 2030, interactuant cada any, afegim l’any al ComboBox:

cbAnys.addItem(any);

Color

Per posar color als components de la vista:

JavaSwing22

La propietat background designa un color al fons del component. Foreground el color de les lletres. Border per posar una vora. Font per canviar l’estil, com la mida del text

Total despeses per any

Posem un botó, un ComBox cbAnys i un label on sortirà el resultat

Al clicar el botó btoTotal s’executa el següent codi:

private void btoTotalActionPerformed(java.awt.event.ActionEvent evt) {                                         
    int any = (int) cbAnys.getSelectedItem();
    float total = getTotalDespesesAny(any);
    lbTotal.setText(total + "");
}
Metode getTotalDespesesAny(any):
private float getTotalDespesesAny(int any) {
    List despeses = new ArrayList<>();
    despeses = controladorDespesa.findDespesaEntities();
    float total = 0;
    Calendar calendari = Calendar.getInstance();
    for (Despesa d : despeses) {
        Date data = d.getData();
        calendari.setTime(data);
        if (any == calendari.get(Calendar.YEAR)) {
            total = total + d.getTotal();
        }
    }
    return total;
}       

Obtenim totes les despeses amb:

despeses =controladorDespesa.findDespesaEntities();

Inicialitzem el total = 0

Per cada despesa en despeses, obtenim la data i si coincideix amb el any de l’argument agafem el seu total i el sumem:

total = total + d.getTotal();

Hem de convertir la data de la classe Date a Calendar per poder saber l’any:

Date data = d.getData();
calendari.setTime(data);
calendari.get(Calendar.YEAR) //retorna l’any

Contingut.


Nosaltres

vens1 vens2 vens3 vens4 vens5 vens6 vens7 vens8 vens9 vens10 vens11 vens12 vens13 vens14 processo calaTrons

Tags

Noves tecnologies WEB Arduino Domótica MycroPython NodeMCU IoT Java ESP8266 Lora C++ Programació Server-Client