Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18
  1. #1
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    42

    Modificare un oggetto attraverso l'editing di una jTable

    Salve a tutti,
    ho Una jTable Popolata attraverso l'elenco dei giocatori contenuti in un archivio.
    Come posso fare in modo che alla modifica della tabella, venga modificato L'oggetto a cui si riferisce?

    [EDIT]
    Chiedo scusa per la domanda un po' troppo generica… Magari potreste darmi qualche indicazione su del materiale da studiare
    Ultima modifica di MBdip; 14-06-2014 a 22:24

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da MBdip Visualizza il messaggio
    Come posso fare in modo che alla modifica della tabella, venga modificato L'oggetto a cui si riferisce?
    Per "modifica della tabella" intendi l'utilizzo dell'edit delle celle che è possibile in JTable? Se sì, quando il valore in una cella viene confermato, esso va a finire al table model tramite setValueAt. Quindi innanzitutto si tratta di valutare quale table model stai usando o intendi usare.
    E comunque servono un po' di dettagli in più per comprendere bene e meglio la tua problematica.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    42
    Allora, la mia tabella è costruita attraverso questo metodo:

    codice:
    public void print_table(String elenco, javax.swing.JTable table){
                    DefaultTableModel model = new DefaultTableModel();
                    if (table != null) {
                        table.setModel(model);
                        
                        String[] rows = elenco.split(System.getProperty("line.separator"));
                        String[] intestaz = rows[0].split("\t");
                                           
                        for (int x = 0; x < intestaz.length; x++) {
                            model.addColumn(intestaz[x]);
                        }
                        
                        for (int x = 1; x < rows.length; x++) {
                            String[] row = rows[x].split("\t");
                            model.addRow(row);
                        }
                    }
    
    
        }
    L'elenco è praticamente una stringa, riporto il metodo utilizzato
    codice:
    public  String elenco_giocatori(){
                String S = "";
                S+=Giocatore.GetIntestazione()+ System.getProperty("line.separator");//Nome\tCognome
                for(int i = 1; i <= giocatori.size(); i++) {
                    S+=giocatori.get(i-1).get_all()+ System.getProperty("line.separator");//Mario\tRossi
                }
                return S;
        }
    Quindi in pratica una volta confermato il valore basterebbe andarlo a prendere in un table model... Ma questo penso che debba definirlo in un'eventuale listner Per poi utilizzare qualcosa del tipo model.getValueAt....
    Ma quale listner E quale model usare?
    Ultima modifica di MBdip; 15-06-2014 a 01:05

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da MBdip Visualizza il messaggio
    L'elenco è praticamente una stringa, riporto il metodo utilizzato
    codice:
    public  String elenco_giocatori(){
                String S = "";
                S+=Giocatore.GetIntestazione()+ System.getProperty("line.separator");//Nome\tCognome
                for(int i = 1; i <= giocatori.size(); i++) {
                    S+=giocatori.get(i-1).get_all()+ System.getProperty("line.separator");//Mario\tRossi
                }
                return S;
        }
    Partiamo da una questione un po' prima del table model. Se stai gestendo delle entità "giocatore", sarebbe bene avere una classe Giocatore che "modella" solamente le caratteristiche di un giocatore, senza alcuna altra logica particolare specifica della applicazione. In pratica, a livello basilare, una classe con i campi di istanza per i dati e i relativi metodi getter e/o setter più altri di utilità (es. toString(), equals(), .....).
    E sarebbe poi bene avere un array o List di oggetti Giocatore, quindi es. un Giocatore[] o un List<Giocatore> .

    Hai queste cose? Nel codice che hai postato, vedo una classe Giocatore ma ..... ho la vaga sensazione che non sia come la intendo io.
    Quindi innanzitutto verifica e valuta quanto ho appena detto. Perché metterti a fare concatenazioni di stringhe per avere una "stringona" con i newline in mezzo e poi fare split da altre parti non è affatto una buona soluzione.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    42
    hai perfettamente ragione!
    Siccome avevo già il metodo per stampare l'elenco in una enorme stringa (perché prima avevo implementato il programma per la visualizzazione attraverso console), ho sfruttato il metodo già esistente.
    Capisco però che non è affatto una buona soluzione.
    Comunque sì, ho tutto ciò che dici! Ogni campo di un giocatore ha il metodo getter e setter. Tutti i giocatori sono raggruppati in una ArrayList <Giocatore> nella classe ArchivioGiocatori. quindi avevo pensato di recuperare il giocatore attraverso l'indice della riga ed il campo attraverso l'indice della colonna per poi utilizzare il metodo setter al momento della modifica.
    Comunque ho tutto quello che mi hai chiesto, effettivamente devo trovare un altro modo per popolare le tabelle.
    Comunque penso che possiamo partire… Nel frattempo mi metto a lavorare sul popolamento delle tabelle (suggerimenti sono ben accetti).

    in pratica l'unica cosa che dovrei fare è trovare il modo di sostituire nel metodo print_table la String elenco con un ArrayList lista... ma come? (intendo soprattutto il creare diverse colonne a seconda dei campi di ogni singola arraylist)
    Ultima modifica di MBdip; 17-06-2014 a 13:13

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da MBdip Visualizza il messaggio
    Comunque ho tutto quello che mi hai chiesto
    Ok, bene.

    Quote Originariamente inviata da MBdip Visualizza il messaggio
    effettivamente devo trovare un altro modo per popolare le tabelle.
    Comunque penso che possiamo partire… Nel frattempo mi metto a lavorare sul popolamento delle tabelle (suggerimenti sono ben accetti)
    Se vuoi che un edit in una cella vada poi a mutare direttamente il rispettivo campo nell'oggetto Giocatore relativo a quella riga, l'approccio migliore è quello di implementare un apposito table model. Si estende AbstractTableModel e si gestisce la struttura dati con un array o List di oggetti Giocatore e si implementano i vari metodi e in particolare i getValueAt/setValueAt.

    Se non hai mai fatto una cosa del genere, potrebbe essere un po' ostico all'inizio. Cerca sul forum, probabilmente se ne è già parlato e forse ho anche fornito risposte. Trovi anche qualche esempio tra i miei "vecchi" esempi qui.
    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
    Apr 2014
    Messaggi
    42
    I tuoi esempi sono stati illuminanti! Ti ringrazio
    il problema dell'oggetto di questa discussione è stato risolto.
    ora però avrei un problemino legato ai tuoi esempi e al modo in cui ho implementato l'interfaccia.

    praticamente ho due tabelle affiancate, la tabella di destra modifica un campo della tabella di sinistra cliccando su un bottone.
    Non posso ristampare la tabella altrimenti perdo la Riga selezionata.
    La tabella di sinistra viene aggiornata nel momento in cui cricco su una riga della stessa oppure nel momento in cui passo con il mouse sui tab del jTabbedPane... Eppure non ho nessun evento di tipo mousehover...
    Come faccio a tenere aggiornata la tabella dinamicamente? (Non so per quale motivo ma appena avevo implementato le tabelle, quando cliccavo sul bottone veniva aggiornata senza perdere la selezione)



    vi posto un po' di codice:

    modello per la tabella squadre
    codice:
    class SquadreTableModel extends AbstractTableModel {
        private final String[] columnNames = { "NOME", "CAPITANO" };
    
        private final  ArrayList<Squadra> squadre;
    
        public SquadreTableModel(ArrayList<Squadra> squadre) {
            this.squadre = squadre;
        }
        @Override
        public int getRowCount() {
            return squadre.size();
        }
        @Override
        public int getColumnCount() {
            return columnNames.length;
        }
    
        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }
    
        @Override
        public boolean isCellEditable(int row, int column) {
            return true;   
        }
        @Override
        public Object getValueAt(int row, int column) {
            Squadra squadra = squadre.get(row);
    
            switch (column) {
                case 0: return squadra.getNome();
                case 1: return squadra.getCapitano().getNome()+" "+squadra.getCapitano().getCognome();
            }
    
            return null;
        }
        @Override
         public void setValueAt(Object value, int row, int column) {
            Squadra squadra = squadre.get(row);
    
            switch (column) {
                case 0: squadra.setNome((String)value); break;   
            }
            fireTableCellUpdated(row, column);
        }
    }
    modello per la tabella componenti:
    codice:
    class ComponentiTableModel extends AbstractTableModel {
        private final String[] columnNames = { "NOME", "COGNOME", "CODICE FISCALE" };
    
        private final ArrayList<Giocatore> componenti;
    
        public ComponentiTableModel(ArrayList<Giocatore> componenti) {
            this.componenti = componenti;
        }
        @Override
        public int getRowCount() {
            return componenti.size();
        }
        @Override
        public int getColumnCount() {
            return columnNames.length;
        }
    
        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }
    
        @Override
        public boolean isCellEditable(int row, int column) {
            return false;   
        }
        @Override
        public Object getValueAt(int row, int column) {
            Giocatore giocatore = componenti.get(row);
    
            switch (column) {
                case 0: return giocatore.getNome();
                case 1: return giocatore.getCognome();
                case 2: return giocatore.getCF();   
            }
    
            return null;
        }
        
    }
    metodo per aggiornare le tabelle a seconda del tab scelto
    codice:
    private void AggiornaInterfaccia() {
            ArrayList lista_giocatori=database.get_ArchivioGiocatori().getGiocatori();
            ArrayList lista_squadre=database.get_ArchivioSquadre().getSquadre();
            ArrayList lista_partite=database.get_ArchivioPartite().getPartite();
    
            switch (tabMain.getSelectedIndex()) {
                case 0:
                    // Aggiorno elenco giocatori
                    GiocatoriTableModel model0= new GiocatoriTableModel(lista_giocatori);
                    jTableGio.setModel(model0);
                    break;
                case 1:
                    // Aggiorno elenco squadre
                    SquadreTableModel model1=new SquadreTableModel(lista_squadre);
                    jTableSqu.setModel(model1);
                    jButtonImpostaCapitano.setVisible(false);
                    update_componenti();
                    break;
                case 2:
                    // Aggiorno elenco partite
                    PartiteTableModel model2=new PartiteTableModel(lista_partite);
                    jTablePar.setModel(model2);
                    break;      
            }                
    
        }
    metodo per aggiornare i componenti della squadra
    codice:
    private void update_componenti(){
            int rowIndex = jTableSqu.getSelectedRow();
            ArrayList lista_componenti;
            if(rowIndex>=0){
                Squadra squadra = database.get_ArchivioSquadre().getSquadre().get(rowIndex);
                lista_componenti=squadra.get_componenti();
                ComponentiTableModel model0= new ComponentiTableModel(lista_componenti);
                jTableSquComponenti.setModel(model0);
                jButtonImpostaCapitano.setVisible(squadra.get_componenti().size()>0);
            }
    }
    pulsante per impostare il capitano
    codice:
    private void jButtonImpostaCapitanoActionPerformed(java.awt.event.ActionEvent evt) {                                                       
            int rowIndex=jTableSquComponenti.getSelectedRow();
            int rowSquadraIndex =jTableSqu.getSelectedRow();
    
            if(rowIndex<0)
                lblMessage.setText(Errori.errSelezionareRiga);
            else{
                Squadra s=database.get_ArchivioSquadre().getSquadre().get(rowSquadraIndex);
                Giocatore g=s.get_componenti().get(rowIndex);
                s.setCapitano(g);
            }
        }
    Ultima modifica di MBdip; 18-06-2014 a 12:39

  8. #8
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    42
    Scusate il doppio post, ho commesso un errore
    Ultima modifica di MBdip; 18-06-2014 a 13:16

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da MBdip Visualizza il messaggio
    praticamente ho due tabelle affiancate, la tabella di destra modifica un campo della tabella di sinistra cliccando su un bottone.

    codice:
    private void jButtonImpostaCapitanoActionPerformed(java.awt.event.ActionEvent evt) {                                                       
            int rowIndex=jTableSquComponenti.getSelectedRow();
            int rowSquadraIndex =jTableSqu.getSelectedRow();
    
            if(rowIndex<0)
                lblMessage.setText(Errori.errSelezionareRiga);
            else{
                Squadra s=database.get_ArchivioSquadre().getSquadre().get(rowSquadraIndex);
                Giocatore g=s.get_componenti().get(rowIndex);
                s.setCapitano(g);
            }
        }
    Il problema di questo codice sopra è che se modifichi solo e semplicemente l'oggetto Squadra, il tuo table model SquadreTableModel non ne "sa" nulla del fatto che hai aggiornato l'oggetto esternamente al table model che lo gestisce!

    Una cosa più bella che puoi fare è mettere in SquadreTableModel un nuovo metodo specifico per la tua applicazione:

    codice:
    public void setCapitano(int row, Giocatore capitano) {
        .......
    }

    In questo modo è il table model che "sa" e va ad aggiornare l'oggetto Squadra alla tal riga e inoltre può anche fare il fire appropriato per aggiornare visivamente il capitano.


    P.S. i tuoi table model mi sembrano corretti, perlomeno visti così in generale. Ci sarebbero alcune finezze che potresti migliorare, ad esempio:
    - in SquadreTableModel la colonna del capitano non è editabile (nel setValueAt non la gestisci), quindi isCellEditable potrebbe dare false per la colonna del capitano.
    - inoltre, giusto solo per efficienza, sarebbe meglio fare fireTableCellUpdated solo se veramente hai cambiato qualcosa. Quindi puoi mettere un default: return; così esce senza fare fireTableCellUpdated se non è una delle colonne settabili.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2014
    Messaggi
    42
    ma la cosa strana è che, non so per quale strano motivo, in una prima implementazione funzionava! Ad esempio se cancellavo un giocatore che era capitano, automaticamente veniva aggiornata la tabella squadre settando a "" il capitano.
    comunque, ho seguito il tuo consiglio e ho fatto ritornare (isCellEditable) false alla colonna capitano.


    Perdonami la domanda, ma per quale motivo (dopo aver impostato nuovo capitano o cancellato il giocatore capitano) se passo col mouse sui tab del jTabbedPane oppure se clicco sulla tabella, Quest'ultima viene aggiornata?

    come fa a "sapere" che è cambiato qualcosa? Eppure non ho inserito alcun eventHandler... e soprattutto lo fa senza perdere la selezione (nel caso di passaggio del mouse sui TAB).
    eppure all'inizio funzionava... Cioè la tabella veniva aggiornata in modo automatico...
    Non ci sarebbe un modo per rendere la tabella dinamica? Cioè, Se modifico qualcosa in un'altra finestra, viene modificata la tabella che legge direttamente le modifiche dell'arraylist.
    Ultima modifica di MBdip; 18-06-2014 a 15:18

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.