Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2013
    Messaggi
    5

    Modifica valore celle JTable

    Salve a tutti, sono nuovo del Forum quindi chiedo scusa in anticipo se per caso dovessi fare qualcosa che non va bene

    Mi sto cimentando per la prima volta nella realizzazione di un software Java con interfaccia grafica. Sono giorni che sbatto la testa sulla gestione degli eventi di una JTable e ancora non riesco a venirne a capo

    Il problema è il seguente:
    Ho una JTable con 3 colonne e N righe(in base al risultato della query) sulla quale visualizzo dei dati prelevati da un DB e sin qua tutto ok. Cambiando il valore all'interno di una cella mi servirebbe recuperare tale valore con il quale poi implementare una formula aritmetica e modificare i valori presenti nelle altre celle.
    Qualche idea su come poter gestire questa cosa?

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    1,123
    Se postassi del codice sarebbe meglio.

    Comunque non mi è chiaro se non sai come gestire la cosa, o non sai come prelevare il valore da una cella.
    Nel secondo caso devi ottenere dalla tabella il numero di riga ed il numero di colonna clickata.
    Il tutto ovviamente deve avvenire dopo alla generazione dell'evento (il clik):

    codice:
    int r = table.getSelectedRow();
    int c = table.getSelectedColumn();
    
    String value = (String) table.getValueAt(r,c);
    Dovresti anche definire un tuo table model.

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2013
    Messaggi
    5
    Tabella.getModel().addTableModelListener(new TableModelListener() {

    codice:
                @Override
                public void tableChanged(TableModelEvent e) {
                    
                    int col = e.getColumn(); 
                    int row = e.getFirstRow(); 
                    String ValoreInserito = Tabella.getValueAt(row,col).toString();
                    float Valore = Float.parseFloat(ValoreInserito);
                
                    int i = d.TotRow(Query);
                    for(int k=0;k<i;k++){
                    Object Obj = Tabella.getValueAt(k,e.getColumn());
                    float ValoreDaCambiare = Float.parseFloat(String.valueOf(Obj));
    
    
                    if(ValoreDaCambiare != Valore){
                           ….   // operazione con cui verra poi cambiato il valore delle altre celle
                           Obj = String.valueOf(ValoreDaCambiare);
                           Tabella.setValueAt(Obj, k, e.getColumn());
                    }  
                    }
                }
            });
    Questo è il pezzo di codice incriminato Essendo la prima volta che mi trovo di fronte a una cosa del genere è molto probabile che sia completamente sbagliata come logica.
    Il problema comunque non sta nel fatto di prevalere il valore della cella editata come vedi, ma piuttosto riuscire e effettuare l'operazione sui valori delle altre celle e successivamente modificare i vecchi
    Ultima modifica di LeleFT; 11-11-2013 a 19:18 Motivo: Inserimento tag CODE

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    @finkgud: quando posti del codice, racchiudilo all'interno degli appositi tag CODE, così viene formattato e risulta più facilmente leggibile.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2013
    Messaggi
    5
    Si scusami, sarà fatto perdonami

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da finkgud Visualizza il messaggio
    Essendo la prima volta che mi trovo di fronte a una cosa del genere è molto probabile che sia completamente sbagliata come logica.
    Il problema comunque non sta nel fatto di prevalere il valore della cella editata come vedi, ma piuttosto riuscire e effettuare l'operazione sui valori delle altre celle e successivamente modificare i vecchi
    Il punto è che bisognerebbe capire meglio la logica del tuo aggiornamento dei valori.
    È meglio che faccio un esempio, per chiarire, altrimenti potresti non afferrare la mia questione che ho posto: immagina di avere una tabella in cui in ogni riga gestisci dei "prodotti" con prezzo, quantità e totale. Una cosa del tipo:
    prodotto1 | prezzo1 | quantità1 | totale1
    prodotto2 | prezzo2 | quantità2 | totale2

    Immagina di voler fare in modo che se l'utente varia il campo della quantità (potrebbe essere un textfield numerico o un combobox ... non ha importanza) su una riga, vuoi aggiornare la quantità E anche il totale (come prezzo x quantità). Una logica del genere è più appropriato farla dentro il table model, che dovrebbe essere "custom" ovvero sviluppato ad hoc.

    Gestire un TableModelListener in genere è più critico. Innanzitutto bisognerebbe testare e/o gestire i vari tipi di cambiamenti che TableModelEvent può notificare. Inoltre se non si sta attenti è possibile che la gestione vada in "loop", perché una modifica del model fa causare un ulteriore tableChanged.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2013
    Messaggi
    5
    Esattamente, ci sono arrivato poco fa. Praticamente io ho una tabella di questo tipo:

    ingrediente1 | quantità1 | costo1
    ingrediente2 | quantità2 | costo2
    ingrediente3 | quantità3 | costo3

    e così via.
    Effettuando una modifica per esempio a quantità1 dovrei aggiornare quantità2 e quantità3 in quanto sono legati in percentuale a quantità1, e di conseguenza aggiornare i costi in base alla quantità, come se fosse per esempio una ricetta. Il problema è che una volta recuperati i valori delle celle che mi interessano e modificati non saprei sinceramente come aggiornare la tabella in quanto come hai detto la gestione mi va in loop.
    Ti posto un po' di codice:

    codice:
    ...
    model = new MyTableModel();
            model.setDataTable(Query);
            model.addTableModelListener(new TableModelListener() {
                @Override
                public void tableChanged(TableModelEvent e) {
                    int col = e.getColumn(); 
                    int row = e.getFirstRow();
                    String valoreInserito = model.getValueAt(row,col).toString();
                    System.out.println(valoreInserito);
                    float valore = Float.parseFloat(valoreInserito);
                    System.out.println(valore);
                    int i = d.TotRow(Query);
                    String prova = null;
                    for(int k=0;k<i;k++){
                    String uno = model.getValueAt(k, col);
                    float tre = Float.parseFloat(String.valueOf(uno));
                    if(tre != valore){
                        tre += 1;
                        prova = String.valueOf(tre);
                        model.setValueAt(prova, k, col);
                    }
                    }
                }
            });
    ...
    
    //MyTableModel
    
    import DAO.ConnectionDAO;import java.awt.*;
    import java.sql.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import javax.swing.event.*;
    
    
    import java.util.Vector;
    
    
    class MyTableModel extends AbstractTableModel {
      // Variabili di istanza
      // -----------------------------------------------------------------------
      private Vector<Vector<String>> data;
      private Vector<String> columnName;
      private PreparedStatement SQLPreparedStatement;
      // -----------------------------------------------------------------------
      
      MyTableModel() {
        data = new Vector<Vector<String>>();
        columnName = new Vector<String>();
      }
      
      public int getColumnCount() {
        if(columnName == null) return -1;
        return columnName.size();
      }
      
      public int getRowCount() {
        return data.size();
      }
      
      public String getColumnName(int col) {
        if(col >= columnName.size()) return null;
        return columnName.elementAt(col);
      }
      
      public Class getColumnClass(int c) {
        return String.class;
      }
      
      // La prima colonna non e' modificabile
      public boolean isCellEditable(int row, int col) {
        if(col == 0) return false;
        else return true;
      }
      
      public String getValueAt(int row, int col) {
        Vector<String> v = data.elementAt(row);
        return v.elementAt(col);
      }
      
      public void setValueAt(Object value, int row, int col) {
        Vector<String> v = data.elementAt(row);
        v.setElementAt((String)value, col);
        fireTableCellUpdated(row,col); 
      }
      
      public void setDataTable(String Query){
          final ConnectionDAO d = new ConnectionDAO();
            Connection cn = null;
              try {
              Class.forName("com.mysql.jdbc.Driver");
              cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Miscele?user=root&password=m4c3nro3");
              SQLPreparedStatement = cn.prepareStatement(Query);
              ResultSet rsQuery = SQLPreparedStatement.executeQuery();
              ResultSetMetaData rsmt = rsQuery.getMetaData();
              int column = rsmt.getColumnCount();
              for(int i=1;i<=column;i++){
                  columnName.add(rsmt.getColumnName(i));
              }
              while(rsQuery.next()){
                  Vector row = new Vector(column);
                  for(int i=1;i<=column;i++){
                      row.addElement(rsQuery.getObject(i));
                  }
                  data.add(row);
              }
              cn.close();
              }catch(Exception e){
              }
      }
      
    }

  8. #8
    Utente di HTML.it
    Registrato dal
    Nov 2013
    Messaggi
    5
    Stavo proprio cercando di creare un table model custom come dici tu. Ti posto il codice:

    codice:
    ...
    model = new MyTableModel();        model.setDataTable(Query);
            model.addTableModelListener(new TableModelListener() {
                @Override
                public void tableChanged(TableModelEvent e) {
                    int col = e.getColumn(); 
                    int row = e.getFirstRow();
                    String valoreInserito = model.getValueAt(row,col).toString();
                    System.out.println(valoreInserito);
                    float valore = Float.parseFloat(valoreInserito);
                    System.out.println(valore);
                    int i = d.TotRow(Query);
                    String prova = null;
                    for(int k=0;k<i;k++){
                    String uno = model.getValueAt(k, col);
                    float tre = Float.parseFloat(String.valueOf(uno));
                    if(tre != valore){
                        tre += 1;
                        prova = String.valueOf(tre);
                        model.setValueAt(prova, k, col);
                    }
                    }
                }
            });
    
    //MyTableModel
    
    import DAO.ConnectionDAO;
    import java.awt.*;
    import java.sql.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import javax.swing.event.*;
    
    
    import java.util.Vector;
    
    
    class MyTableModel extends AbstractTableModel {
      // Variabili di istanza
      // -----------------------------------------------------------------------
      private Vector<Vector<String>> data;
      private Vector<String> columnName;
      private PreparedStatement SQLPreparedStatement;
      // -----------------------------------------------------------------------
      
      MyTableModel() {
        data = new Vector<Vector<String>>();
        columnName = new Vector<String>();
      }
      
      public int getColumnCount() {
        if(columnName == null) return -1;
        return columnName.size();
      }
      
      public int getRowCount() {
        return data.size();
      }
      
      public String getColumnName(int col) {
        if(col >= columnName.size()) return null;
        return columnName.elementAt(col);
      }
      
      public Class getColumnClass(int c) {
        return String.class;
      }
      
      // La prima colonna non e' modificabile
      public boolean isCellEditable(int row, int col) {
        if(col == 0) return false;
        else return true;
      }
      
      public String getValueAt(int row, int col) {
        Vector<String> v = data.elementAt(row);
        return v.elementAt(col);
      }
      
      public void setValueAt(Object value, int row, int col) {
        Vector<String> v = data.elementAt(row);
        v.setElementAt((String)value, col);
        fireTableCellUpdated(row,col); 
      }
      
      public void setDataTable(String Query){
          final ConnectionDAO d = new ConnectionDAO();
            Connection cn = null;
              try {
              Class.forName("com.mysql.jdbc.Driver");
              cn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Miscele?user=root&password=m4c3nro3");
              SQLPreparedStatement = cn.prepareStatement(Query);
              ResultSet rsQuery = SQLPreparedStatement.executeQuery();
              ResultSetMetaData rsmt = rsQuery.getMetaData();
              int column = rsmt.getColumnCount();
              for(int i=1;i<=column;i++){
                  columnName.add(rsmt.getColumnName(i));
              }
              while(rsQuery.next()){
                  Vector row = new Vector(column);
                  for(int i=1;i<=column;i++){
                      row.addElement(rsQuery.getObject(i));
                  }
                  data.add(row);
              }
              cn.close();
              }catch(Exception e){
              }
      }
      
    }
    Sostanzialmente la mia tabella è di questo tipo:

    ingrediente1 | quantità1 | costo1
    ingrediente2 | quantità2 | costo2
    ingrediente3 | quantità3 | costo3

    e così via.
    Immagina di aver una ricetta e poterne modificare le dosi. Modificando quantità1 mi serve aggiornare quantità2 e quantità3 poiché sono legati in percentuale a quantità1, e di conseguenza vanno aggiornati anche i costi in base alla quantità di ingrediente utilizzato. Purtroppo però proprio come dicevi tu una volta recuperati i valori delle celle e modificati, non riesco ad aggiornare la tabella con i nuovi valori poiché la gestione va in loop.

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da finkgud Visualizza il messaggio
    Stavo proprio cercando di creare un table model custom come dici tu.
    Purtroppo però proprio come dicevi tu una volta recuperati i valori delle celle e modificati, non riesco ad aggiornare la tabella con i nuovi valori poiché la gestione va in loop.
    Rispondo purtroppo solo ora. Come ho detto prima, la soluzione migliore è fare quella logica nel table model, perché in un TableModelListener puoi appunto avere i problemi che hai già sperimentato e descritto.
    Il punto è che quel MyTableModel che hai implementato è molto "generico", ovvero funziona in modo generale per una query arbitraria. Insomma, MyTableModel non "sa" nulla, a priori, di quante/quali sono le colonne. Per fare una logica come quella che hai descritto, invece il table model dovrebbe sapere quali sono le colonne e a quali indici (es, che la quantità è la colonna di indice 1).

    Quindi o fai table model distinti/slegati e specializzati, oppure cambi un pochino architettura e realizzi un table model "generico" che può essere esteso da sotto-classi che "sanno" quale è la query, che campi fornisce e in che ordine. E a quel punto puoi realizzare la logica descritta.

    E già che ci sono, ti segnalo che il MyTableModel non è nemmeno corretto dal punto di vista della "tipizzazione". Infatti hai un:
    Vector<Vector<String>> data

    Ma poi nel while sul ResultSet istanzi un Vector non parametrizzato. Quindi innanzitutto hai sicuramente dei warning di unchecked conversion che dovrebbero essere il campanello di allarme del fatto che la tipizzazione è "dubbia" e potrebbe causare problemi.
    Ma la cosa più grave è che usi getObject che restituisce un qualunque Object. E puoi metterli nel Vector<Vector<String>> proprio perché hai saltato la parametrizzazione del Vector interno.
    Il problema è che quando poi vai a estrarre il dato dal Vector<String>, c'è un cast implicito a String .... e se il getObject aveva fornito es. un Integer .... si schianta!!
    Quindi il MyTableModel è comunque da rivedere molto bene in ogni caso sul fronte della tipizzazione.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.