Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1

    Tabella che si aggiorna a seconda di filtri

    Ciao a tutti,
    volevo chiedervi un piccolo (forse) aiuto. Devo consegnare un progetto a breve e sto sbattendo la testa al muro perché alcune cose non le ho capite proprio. Il professore e le sue direttive ambigue (e la sua scarsa reperibilità per chiarimenti) non contribuiscono.

    PREMESSA: non sto chiedendo la soluzione totale del esercizio

    La specifica del progetto (per una buona parte risolto, spero) sono:


    Il gruppo dovrà realizzare una applicazione swing, con classe avviabile ClientGrafico.
    [..]
    Il client ha lo scopo di visualizzare, modificare e utilizzare i contenuti forniti dalla libreria.
    [..]
    Il gruppo dovrà realizzare una applicazione swing, con classe avviabile ClientGrafico.

    La classe concreta TabellaDati rappresenta una tabella, che avrà la prima riga vuota ed editabile. Modificando la prima riga (tramite i metodi richiamati dal Client) il contenuto della tabella potrà variare. Esempio: se ho i risultati di una giornata calcistica, e scrivo Milan nella prima cella, potrebbe mostrarmi solo la riga relativa al risultato del Milan.



    codice:
    import javax.swing.event.ChangeListener;
    import javax.swing.table.TableModel;
    
    public abstract class AbstractTabellaDati implements TableModel 
    {
    	/* Da utilizzare per creare oggetti (no costruttori) */
    	public static AbstractTabellaDati getTabellaDati() 
    	{
    		throw new UnsupportedOperationException();
    	};
    
    	/** 
    	 * Restituisce true se la cella in posizione (rowIndex,columnIndex) è modificabile. 
    	 * Deve restituire sempre true per tutte le celle con rowIndex == 0 
    	 */
    	abstract public boolean isCellEditable(int rowIndex, int columnIndex);
    	
    	/** 
    	 * Implementazione da documentazione in TableModel. Inoltre, ogni volta che viene chiamato, 
    	 * anche su celle non editabili, deve verificare che non siano stati modificati i dati nella 
    	 * sorgente dati (dipendente da progetto) ed eventualmente gestire il Listener per informare il 
    	 * client dell'aggiornamento dei dati.In questo modo sul client ci saranno tutti i dati aggiornati 
    	 * ogni volta che si prova a modificare una cella con setValueAt.
    	 */
    	abstract public void setValueAt(Object aValue, int rowIndex, int columnIndex);
    }
    Quel che ho fatto, è stato creare un TabellaDati così (molti metodi sono implementazioni "standard" dei metodi di TableModel)

    codice:
    import java.util.ArrayList;
    
    import javax.swing.event.TableModelListener;
    
    public class TabellaDati extends AbstractTabellaDati
    {
    	private static TabellaDati istanza = null;
    	
    	private static ArrayList<Squadra> serieA = null;
    	private static String filter_col0 = null;
    	private static int[] order_int = {0,0,0,0,0,0,0,0,0};
    	
    	private static String[] columnNames = {"Squadra", "Posizione", "Punti", "Giocate", "Vittorie", "Pareggi", 
    		"Sconfitte", "Reti Segnate", "Reti Subite", "Differenza Reti"};
    	
    	private static ArrayList<TableModelListener> listeners = new ArrayList<TableModelListener>();
    
    	private TabellaDati(){}
    	
    	public static AbstractTabellaDati getTabellaDati() 
    	{
    		if(istanza == null)
    		{
    			TabellaDati.istanza = new TabellaDati();
    			TabellaDati.serieA = SerieA.getSerieA();
    		}
    		return istanza;
    	}
    	
    	@Override
    	public void addTableModelListener(TableModelListener arg0) 
    	{
    		listeners.add(arg0);
    	}
    
    	@Override
    	public Class<?> getColumnClass(int arg0) 
    	{
    		switch(arg0)
    		{
    			case 0: 
    				return String.class; 
    				
    			case 1:
    			case 2:
    			case 3:
    			case 4:
    			case 5:
    			case 6:
    			case 7:
    			case 8:
    			case 9:
    				return Integer.class;
    			
    			default:
    				return Object.class;
    		}
    	}
    
    	@Override
    	public int getColumnCount() 
    	{
    		return columnNames.length;
    	}
    
    	@Override
    	public String getColumnName(int arg0) 
    	{
    		return columnNames[arg0];
    	}
    
    	@Override
    	public int getRowCount() 
    	{
    		return serieA.size() + 1;
    	}
    
    	@Override
    	/**
    	 * Questo metodo, data una cella restituisce l'oggetto che la occupa in quel dato momento. La prima riga è
    	 * speciale, essendo quella editabile e che quindi contiene i valori inseriti dall'utente, e viene quindi
    	 * trattata a parte.
    	 * @param int arg0 La riga della cella
    	 * @param int arg1 La colonna della cella
    	 */
    	public Object getValueAt(int arg0, int arg1) 
    	{
    		if(arg0 == 0)
    		{
    			if(arg1 == 0)
    			{
    				return TabellaDati.filter_col0;
    			}
    			else
    			{
    				return TabellaDati.order_int[arg1-1];
    			}
    		}
    		else
    		{
    			return TabellaDati.serieA.get(arg0-1).getColonna(arg1);
    		}
    	}
    
    	@Override
    	public void removeTableModelListener(TableModelListener arg0) 
    	{
    		listeners.remove(arg0);
    	}
    
    	@Override
    	/**
    	 * Metodo per rendere permanenti le modifiche ad una cella
    	 */
    	public void setValueAt(Object arg0, int arg1, int arg2) 
    	{
    		if(isCellEditable(arg1, arg2))
    		{
    			if(arg2 == 0)
    			{
    				filter_col0 = (String) arg0;
    				serieA = SerieA.getSquadrePerFiltro((String) arg0);
    			}
    			else
    			{
    				order_int[arg2-1] = (int) arg1;
    			}
    		}
    		
    	}
    
    	@Override
    	public boolean isCellEditable(int rowIndex, int columnIndex) 
    	{
    		if(rowIndex == 0)
    		{
    			return true;
    		}
    		
    		return false;
    	}
    
    }
    Le classi SerieA e Persona hanno metodi che funzionano e che non toccano la tabella, ma solo la struttura dati. Cioè leggono i dati da internet ed eventualmente li filtra.

    Il mio progetto dovrebbe fare un filtro sulla prima colonna, a seconda del parametro string che gli si scrive. Gli altri valori sono int e ci inventeremo dei filtri anche per quello.

    Quello che mi chiedo io è: ho visto in altri esempi in giro che per rendere permanenti delle modifiche alla tabella si usano i metodi fireCellTableUpdate e simili che sono di AbstractTableModel ma noi non possiamo usarli, perché Java non ha ereditarietà multipla... quindi, posto che il programma così scritto riesce a leggere i dati da internet e a mostrarmi una tabella con i dati giusti, con una prima riga vuota ed editabile, come faccio a imporgli un refresh dei dati? Non ho proprio capito come dovrei usare i TableModelListener e, soprattutto, e perché lui mi importa l'interfaccia ChangeListener.

    Grazie a tutti quelli che risponderanno, mi rendo conto che è un post lungo e noioso...

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Se si tratta di Swing (e in particolare di table/table model) entro in gioco io che me ne intendo.

    Partiamo da una questione, che vorrei più che altro capire se è stata una tua scelta o ti è stata imposta. Anche se hai una classe astratta di mezzo, hai comunque optato per implementare completamente la interfaccia TableModel, che è tutta a tuo carico. Questo certo .. è tecnicamente possibile ma più lungo.
    Quando si vuole creare un table model custom e/o con caratteristiche abbastanza particolari (come il tuo caso), generalmente, nella (quasi) totalità dei casi, si estende di norma AbstractTableModel ... non si va ad implementare al 100% TableModel.

    Questo perché AbstractTableModel ha già "di serie" la gestione dei listener (registrazione/deregistrazione) e offre alle sottoclassi (in realtà a chiunque, visto che sono public) una serie di metodi fireXXX che compongono (senza che il programmatore si preoccupi dei dettagli in TableModelEvent) e inviano gli eventi ai listener registrati.

    Rifare da zero questo, non è impossibile ma richiede anche la conoscenza di cosa ci deve essere nei campi di un TableModelEvent. E siccome tutto questo è un surplus di lavoro che non cambia rispetto alle necessità di un table model custom ... ecco perché si estende in genere AbstractTableModel.

    Se vuoi rifare la gestione dei listener, devi prestare attenzione a una serie di cose: innanzitutto la (de)registrazione dei listener, secondo le convenzioni di Swing, dovrebbe essere fatta in modo thread-safe (qualunque thread deve poter (de)registrare un listener in modo corretto). AbstractTableModel infatti non usa un ArrayList (che non è synchronized) ma usa bensì una classe apposita javax.swing.event.EventListenerList che è thread-safe per l'aggiunta/rimozione dei listener.
    Guarda la documentazione javadoc di questa classe, c'è anche l'esempio d'uso e capirai meglio!

    Inoltre non basta gestire add/removeTableModelListener. Quando cambia qualcosa nei dati o nella struttura dei dati nel table model, bisogna notificare tutti i listener. Quando dall'esterno "qualcuno" (del tuo codice o JTable o altri) invoca setValueAt, ci sono 2 cose da fare: aggiornare la struttura dati nel model (e qui appunto se la struttura dati è tua, devi sapere tu come aggiornarla!) e poi notificare tutti listener per segnalare le notifiche. Quando agganci un table model a JTable ... uno degli "ascoltatori" è proprio quel JTable.
    Le notifiche servono proprio a segnalare che qualcosa va fatto, JTable appunto rinfresca le celle sfruttando renderer ecc...

    Se non estendi AbstractTableModel i "fire" devi farteli tu, poi chiamali come vuoi, non è quello il punto, ma sta di fatto che devi creare un TableModelEvent e darlo in pasto a tutti i listener registrati. E devi sapere come popolarlo questo TableModelEvent.

    Se hai altri dubbi, chiedi pure.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Per rispondere alla tua domanda, mi è stato imposto. Anche senza che durante il corso si sia accennato a cosa voglia dire thread-safe, e cosa sia una classe synchronized. Per fortuna non sono uno sprovveduto totale e anche se sicuramente non bene come te, ho capito cosa intendi grazie a conoscenze che vanno oltre l'Università. Tutto ciò verrà aggiunto alla superficialità con il quale il professore ha gestito il corso...

    Ma per parlare di cose serie, il tuo post è manna dal cielo e ti ringrazio moltissimo! Avevo visto il tuo sito di esempi, sappi che ti stimo molto per l'aiuto che da (e speravo in una tua risposta...)i! Purtroppo, ho ancora dei dubbi. Devo dire la verità, credo che questi dubbi svaniranno quando capirò BENE cosa succede all'interno di JTable, che per me è ancora un po' una "scatola chiusa".

    CREDO di aver capito che quando passo un TableModel a JTable lui utilizzi i metodi getValueAt, getRowCount, getColumnCount ecc. per creare e popolare la Tabella. E fin qui ci siamo.
    A questo punto mettiamo che l'utente clicchi su una cella editabile e scriva qualcosa. JTable cosa fa? Richiama setValueAt()? E quindi poi giustamente tu dici che io devo crearmi un TableModelEvent e notificarlo a tutti i listener, sarà questo a dire in qualche modo a JTable di ricaricarsi e rileggere la struttura perché è cambiata (anche del tutto, non solo la cella editabile)?

    Scusa per le tante domande, ma la differenza tra argomenti del corso e argomenti del progetto è tanta che ci sentiamo pesci in una vasca di squali.

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Darkobra
    Per rispondere alla tua domanda, mi è stato imposto.
    Ok, allora prendiamo questo per buono. Cioè se è così che va fatto, allora vediamo di ragionare in tal senso!

    Originariamente inviato da Darkobra
    Anche senza che durante il corso si sia accennato a cosa voglia dire thread-safe, e cosa sia una classe synchronized.
    Vabbé ... prendiamo per buono anche questo.

    Originariamente inviato da Darkobra
    ho capito cosa intendi

    il tuo post è manna dal cielo e ti ringrazio moltissimo! Avevo visto il tuo sito di esempi, sappi che ti stimo molto per l'aiuto che da
    Grazie di cuore.

    Originariamente inviato da Darkobra
    CREDO di aver capito che quando passo un TableModel a JTable lui utilizzi i metodi getValueAt, getRowCount, getColumnCount ecc. per creare e popolare la Tabella. E fin qui ci siamo.
    Sì, il table model "espone" queste informazioni come "ho n colonne", "ho m righe", "la colonna x si chiama così", ecc... JTable è il primo che usa appunto queste informazioni per strutturare visivamente la tabella.

    Originariamente inviato da Darkobra
    A questo punto mettiamo che l'utente clicchi su una cella editabile e scriva qualcosa. JTable cosa fa? Richiama setValueAt()?
    Sì, quando l'utente ha terminato/confermato l'editing (in genere con un invio, es. su un editor che è un text-field), allora alla fine JTable invoca setValueAt per impostare il valore nel model.
    Se la modifica era originata da un editor, la cella è già (come caso particolare) aggiornata quando il setValueAt viene invocato ma se il setValueAt viene invocato programmaticamente da te in qualunque altro contesto allora no, la cella è da aggiornare. Comunque il table model non "sa" chi lo sta invocando e da dove arriva il valore. Ecco perché comunque il table model deve notificare i listener.

    Originariamente inviato da Darkobra
    E quindi poi giustamente tu dici che io devo crearmi un TableModelEvent e notificarlo a tutti i listener, sarà questo a dire in qualche modo a JTable di ricaricarsi e rileggere la struttura perché è cambiata (anche del tutto, non solo la cella editabile)?
    Sì, esatto. TableModelEvent con i suoi campi può descrivere svariate cose: cambiamento di una cella, di una o più righe, ecc...
    Guarda la documentazione javadoc di TableModelEvent, all'inizio c'è un pezzo di codice vari tipi di chiamate al costruttore.

    Originariamente inviato da Darkobra
    Scusa per le tante domande, ma la differenza tra argomenti del corso e argomenti del progetto è tanta che ci sentiamo pesci in una vasca di squali.
    No prob, capisco.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Grazie Andbin, con il tuo aiuto ho finito il progetto della mia parte.

    Il problema è questo: il mio Client Grafico deve funzionare con ogni libreria e la mia libreria deve funzionare con ogni Client Grafico (siamo diversi gruppi).

    Controllando quello che ho fatto, ho capito che bene o male mi manca una cosa sola il metodo TableChanged, che deve essere implementato in modo "universale". Inutile dire che non so neanche da dove cominciare o quasi... (ma può dipendere dal fatto che devo presentare anche un altro progetto, la stessa data, e sto impazzendo).

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Darkobra
    Il problema è questo: il mio Client Grafico deve funzionare con ogni libreria e la mia libreria deve funzionare con ogni Client Grafico (siamo diversi gruppi).
    Sì, ho intuito quello che stai dicendo (almeno credo ...). Altri fanno una interfaccia grafica e devono poter usare il tuo table model, giusto?
    Se hai implementato TableModel al 100%, implementando i suoi 9 metodi in modo sensato e consistente (intendo dire es. se getColumnCount() indica 4, devi permettere gli indici di colonna fino a 3, sei tu che devi assicurare queste cose) ... allora è (quasi) fatta, nel senso che di per sé il table model è corretto.

    Poi se il tuo table model deve essere usabile da altri bisogna vedere cosa gli altri si aspettano. Si aspettano un classe chiamata espressamente TabellaDati?

    Ora ho riguardato meglio il tuo codice postato prima. Ci sono diverse cose che non mi piacciono. Non mi piace quel metodo statico getTabellaDati in AbstractTabellaDati che lancia deliberatamente UnsupportedOperationException. Non ha senso ... se si invoca un metodo statico sul nome di una classe astratta generalmente è perché ci si aspetta di ricevere una istanza di una implementazione "concreta" (singleton o creata ogni volta è un altro discorso).
    Prendi per esempio java.util.Calendar (classe astratta). Puoi invocare i metodi statici getInstance(), getInstance(Locale), ecc... e ti danno una istanza di una implementazione concreta (qui nella maggior parte dei casi, salvo per Locale "particolari", sono dei GregorianCalendar, sottoclasse concreta).

    Quindi quel tuo metodo statico ha poco senso. Poi l'hai messo anche in TabellaDati, ma non è un overriding!! (per essere precisi è un "hiding") Quindi non centra nulla direttamente con quello in AbstractTabellaDati.

    Inoltre il fatto che la struttura dati è "di classe" e non di istanza non è proprio molto bello, se puoi ripensaci sopra.
    E il fatto che l'assegnazione dei dati veri e propri è "cablata" con quel SerieA.getSerieA(), beh, potrebbe essere sensato (per quello che vi siete posti) ma sarebbe stato più bello se fosse stato stabilito uno standard più appropriato per assegnare i dati.

    Originariamente inviato da Darkobra
    il metodo TableChanged, che deve essere implementato in modo "universale".
    Che vuol dire??
    tableChanged è il metodo in TableModelListener e lo implementa solo chi vuole ricevere notifiche dei cambiamenti nel table model. JTable in primis lo implementa e gli serve appunto per riceve le notifiche e aggiornarsi in modo tempestivo/appropriato di conseguenza.

    Se tu vuoi implementare un TableModelListener e registrarlo sul table model per qualche motivo, es. logging, notifica all'utente con una dialog che dica es. "Riga X modificata", ecc... sei libero di farlo.
    Ma non capisco cosa vuol dire "universale", visto che appunto chiunque lo può implementare e per farci quello che vuole.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Originariamente inviato da andbin
    Poi se il tuo table model deve essere usabile da altri bisogna vedere cosa gli altri si aspettano. Si aspettano un classe chiamata espressamente TabellaDati?
    Sì, si aspettano espressamente una classe chiamata TabellaDati, che estenda AbstractTabellaDati. Direttive del professore...

    Ora ho riguardato meglio il tuo codice postato prima. Ci sono diverse cose che non mi piacciono. Non mi piace quel metodo statico getTabellaDati in AbstractTabellaDati che lancia deliberatamente UnsupportedOperationException. Non ha senso ... se si invoca un metodo statico sul nome di una classe astratta generalmente è perché ci si aspetta di ricevere una istanza di una implementazione "concreta" (singleton o creata ogni volta è un altro discorso).
    Prendi per esempio java.util.Calendar (classe astratta). Puoi invocare i metodi statici getInstance(), getInstance(Locale), ecc... e ti danno una istanza di una implementazione concreta (qui nella maggior parte dei casi, salvo per Locale "particolari", sono dei GregorianCalendar, sottoclasse concreta).

    Quindi quel tuo metodo statico ha poco senso. Poi l'hai messo anche in TabellaDati, ma non è un overriding!! (per essere precisi è un "hiding") Quindi non centra nulla direttamente con quello in AbstractTabellaDati.
    La classe AbtractTabellaDati non è modificabile, è scritta dal professore e deve rimanere identica...

    Inoltre il fatto che la struttura dati è "di classe" e non di istanza non è proprio molto bello, se puoi ripensaci sopra.
    E il fatto che l'assegnazione dei dati veri e propri è "cablata" con quel SerieA.getSerieA(), beh, potrebbe essere sensato (per quello che vi siete posti) ma sarebbe stato più bello se fosse stato stabilito uno standard più appropriato per assegnare i dati.
    Ci ripenseremo su... non piace troppo nemmeno a me, ma non sono il solo nel gruppo.

    Che vuol dire??
    tableChanged è il metodo in TableModelListener e lo implementa solo chi vuole ricevere notifiche dei cambiamenti nel table model. JTable in primis lo implementa e gli serve appunto per riceve le notifiche e aggiornarsi in modo tempestivo/appropriato di conseguenza.

    Se tu vuoi implementare un TableModelListener e registrarlo sul table model per qualche motivo, es. logging, notifica all'utente con una dialog che dica es. "Riga X modificata", ecc... sei libero di farlo.
    Ma non capisco cosa vuol dire "universale", visto che appunto chiunque lo può implementare e per farci quello che vuole.
    È esattamente quello che mi chiedo anche io, ma non saprei dire di più. Questo è quello che ho capito! Il client deve occuparsi di fornire un TableModelListener da registrare sulla propria tabella, e la libreria si occupa di notificarlo con un TableModelEvent.
    Io personalmente, dovendomi attenere a queste specifiche ho fatto così:
    la classe ClientGrafico (di cui una versione vecchia è lì sopra) implementa TableModelListener, e quindi definisce un metodo TableChanged.... VUOTO. Non sarebbe la prima volta che il professore richieda escamotage del genere giusto per far vedere che hai capito come dovrebbe funzionare (cosa che, a dire il vero, non è proprio vera... il mio progetto FUNZIONA, ma sono ancora confuso). La soluzione PER LA MIA LIBRERIA è perfetta. Nel senso che per come volevo io il progetto, funziona tutto. La libreria si aggiorna correttamente, e non esiste valore da inserire nelle celle editabili che metta in difficoltà la tabella.
    Ma, a parola del professore, devo pensare a implementare il metodo tableChanged() in modo che funzioni con qualsiasi altra libreria, qualsiasi tipo di TableModelEvent gli venga passato insomma, anche se tutto ciò per la mia libreria è completamente inutile.
    Se non mi sono spiegato bene è perché anche io non ho capito bene...

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Darkobra
    Sì, si aspettano espressamente una classe chiamata TabellaDati, che estenda AbstractTabellaDati. Direttive del professore...
    Ok, l'avevo pensato.

    Originariamente inviato da Darkobra
    La classe AbtractTabellaDati non è modificabile, è scritta dal professore e deve rimanere identica...
    Non ero certo al 100% che l'avesse fatta il prof. Comunque, per precisare sul getTabellaDati(), in un certo modo è utile. Cioè se nella tua classe TabellaDati tu non avessi messo il getTabellaDati, allora invocare TabellaDati.getTabellaDati() effettivamente invoca quello del prof. (che è visibile perché ereditato) che lancia UnsupportedOperationException.

    Ma non è comunque quello il modo più appropriato per "imporre" a qualcuno di implementare un metodo, visto che appunto è un hiding e non un overriding.
    Ma ok, prendiamolo per buono.

    Originariamente inviato da Darkobra
    Ci ripenseremo su... non piace troppo nemmeno a me, ma non sono il solo nel gruppo.
    Ok, ma la soluzione per rendere la cosa almeno un po' più "pulita" concettualmente esiste ed è semplice: lo stato del model lo fai diventare "di istanza" e al costruttore (che può anche restare privato) nessuno vieta di fargli ricevere il ArrayList<Squadra> e quindi invocherai il costruttore nel metodo "factory" passando l'array.
    Non cambia niente all'esterno (e non fa diventare tutto rose e fiori) ... ma è già un passo in avanti.


    Originariamente inviato da Darkobra
    Ma, a parola del professore, devo pensare a implementare il metodo tableChanged() in modo che funzioni con qualsiasi altra libreria, qualsiasi tipo di TableModelEvent gli venga passato insomma, anche se tutto ciò per la mia libreria è completamente inutile.
    Per la tua libreria è inutile ... perché non è il tuo table model che ha bisogno di ricevere notifiche sui cambiamenti (a meno che ci sia qualcosa che non so io e che non hai detto).

    Se intendi dire che nel client grafico bisogna ricevere le notifiche E capire/distinguere cosa sta dicendo un TableModelEvent (es. "cella modificata", "righe n-m inserite", ecc..), allora è ok, nel senso che la documentazione di TableModelEvent c'è e descrive credo sufficientemente bene quali sono i casi e le combinazioni di flag/valori.
    Ma dovresti anche precisare a cosa servono queste informazioni nel client grafico. Cioè oltre a JTable (che già le riceve e per motivi ovvi, sensati), a te o al client grafico a cosa altro servono? Questo è il punto.
    Se è solo per il prof. per fargli capire che sai come distinguere le informazioni ... beh, ok.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Originariamente inviato da andbin

    Per la tua libreria è inutile ... perché non è il tuo table model che ha bisogno di ricevere notifiche sui cambiamenti (a meno che ci sia qualcosa che non so io e che non hai detto).

    Se intendi dire che nel client grafico bisogna ricevere le notifiche E capire/distinguere cosa sta dicendo un TableModelEvent (es. "cella modificata", "righe n-m inserite", ecc..), allora è ok, nel senso che la documentazione di TableModelEvent c'è e descrive credo sufficientemente bene quali sono i casi e le combinazioni di flag/valori.
    Ma dovresti anche precisare a cosa servono queste informazioni nel client grafico. Cioè oltre a JTable (che già le riceve e per motivi ovvi, sensati), a te o al client grafico a cosa altro servono? Questo è il punto.
    Se è solo per il prof. per fargli capire che sai come distinguere le informazioni ... beh, ok.
    Uhm, non credo di aver capito.

    Io credo di avere sufficientemente chiaro il fatto che JTable ha un SUO TableModelListener, che aggiunge al table model tramite il metodo apposito. E quindi, a me non serve altro. Questo è per me sufficientemente chiaro dal fatto che io anche se non definisco nessun TableModelListener, il solo fatto di aver implementato add\removeTableModelListener più un metodo che gli passa l'evento corretto al momento giusto mi fa funzionare bene le cose.

    Tuttavia a detta del professore questo non sarà sufficiente per far sì che il mio client grafico (che usa JTable, ma per altri potrebbe non essere così) funzioni con altre librerie (cioè delle classi TabellaDati.java fatta da altri, con altre funzioni... alcuni leggono dati da Twitter, ecc, io leggo dei dati da una classifica con HtmlUnit per esempio...), e quindi dovrò implementare un mio TableModelListener da aggiungere tramite addTableModelListener alla lista degli ascoltatori e far sì che sia questo a gestire i cambiamenti nella mia JTable. Tuttavia non ho capito, a. se è necessario davvero..., b. se è necessario, non ho la minima idea di come si faccia. Cioè, ho capito che la documentazione di TableModelEvent mi darà una grossa mano in questo senso... ma dopo, come faccio a manipolare la mia JTable? E soprattutto, la cosa non genererà qualche "conflitto" con ciò che in modo concorrente cercherà di fare il listener di JTable?

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Darkobra
    dovrò implementare un mio TableModelListener da aggiungere tramite addTableModelListener alla lista degli ascoltatori e far sì che sia questo a gestire i cambiamenti nella mia JTable.
    Ma è questo che non capisco .... "gestire" come? Non c'è bisogno di implementare TableModelListener per gestire (qualunque cosa intendi: modificare, rimuovere, ecc...) la tabella!

    Originariamente inviato da Darkobra
    ma dopo, come faccio a manipolare la mia JTable?
    I dati in un JTable li si manipola in 2 modi, tipicamente:

    a) Se qualcosa nella tabella è editabile, è l'utente che edita i dati e "pilota" insomma i cambiamenti. Questo chiaramente riguarda solo i valori delle celle, di per sé e solo tramite JTable l'utente non ha possibilità di aggiungere, rimuovere, spostare righe, ecc.... Perché non c'è alcuna convenzione e/o API standard per fare questo.

    b) Programmaticamente, tipicamente andando ad agire direttamente sul table model. In questo caso è necessario che il table model sia (ovviamente) "mutabile" ed esponga una API specifica. Se un table model gestisce ad esempio una collezione di oggetti Persona, potrebbe esporre metodi es. addPersona(Persona p), removeRow(int row), insertPersona(int row, Persona p), ecc...
    Questa sarebbe una "interfaccia di programmazione" extra, un po' come DefaultTableModel che è un table model specializzato nel gestire una struttura dati basata su Vector, mutabile, e offre metodi come es. addRow, moveRow, ecc...
    Una interfaccia grafica quindi potrebbe avere un pulsante "Elimina riga", l'utente seleziona una riga e poi potrebbe o premere questo pulsante o es. usare il tasto "canc".

    Ma tutto questo che ho detto non centra nulla con una implementazione di TableModelListener. Non è con questo che "modifichi" una tabella.
    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.