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

    Dubbio su JTable e su AbstractModelTable

    Salve. Qualcuno sa dirmi perchè non riesco a visualizzare i nomi delle colonne di questa JTable? E inoltre, come faccio a rendere le celle non modificabili oppure modificabili? E come faccio ad ottenere un valore di una cella appena modificata da un utente?

    codice:
    import javax.swing.JFrame;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    
    public class TestTable extends JFrame
    {
    	public TestTable()
    	{
    		super ("Test Table");
    		setSize (400, 300);
    		setLocationRelativeTo (null);
    		setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    		
    		JTable table = new JTable
    		(
    			new AbstractTableModel()
    			{
    				public int getColumnCount() { return 10; }
    				public int getRowCount() { return 10; }
    				public Object getValueAt (int row, int col) { return new Integer ((row + 1) * (col + 1)); }
    				public Class getColumnClass (int column) { return Object.class; }
    				public String getColumnName (int column) { return "Nome"; }
    			}
    		);
    		
    		add (table);
    		
    		setVisible (true);
    	}
    	
    	public static void main (String[] args)
    	{
    		new TestTable();
    	}
    }

  2. #2
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    8,013
    Prova ad inserire la tabella in uno JScrollPane, e questo nel tuo JFrame
    <´¯)(¯`¤._)(¯`»ANDREA«´¯)(_.¤´¯)(¯`>
    "The answer to your question is: welcome to tomorrow"

  3. #3
    Originariamente inviato da Andrea1979
    Prova ad inserire la tabella in uno JScrollPane, e questo nel tuo JFrame
    Grazie mille funziona. Però se elimino getColumnClass funziona lo stesso, perchè? Cos'è di preciso questa classe della colonna, e a cosa serve? Non sapresti rispondere anche alle altre domande? :P

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Dreamer89
    Però se elimino getColumnClass funziona lo stesso, perchè?
    Hai definito una anonymous class che estende AbstractTableModel e hai fatto l'override di getColumnClass(). Bene. Ma se togli il "tuo" getColumnClass viene ereditato quello già implementato da AbstractTableModel. E sai come è fatto quello di AbstractTableModel??

    codice:
        public Class<?> getColumnClass(int columnIndex) {
    	return Object.class;
        }
    ta-da.... praticamente come il tuo.

    Originariamente inviato da Dreamer89
    Cos'è di preciso questa classe della colonna, e a cosa serve?
    Serve a scegliere il "renderer" da usare per la visualizzazione della cella. Lo spiega molto bene qui:
    http://java.sun.com/docs/books/tutor...tml#editrender

    Originariamente inviato da Dreamer89
    E inoltre, come faccio a rendere le celle non modificabili oppure modificabili?
    Vedi isCellEditable() del table model, di cui devi fare l'override. (quello implementato in AbstractTableModel ritorna sempre false indipendentemente da riga/colonna).

    Originariamente inviato da Dreamer89
    E come faccio ad ottenere un valore di una cella appena modificata da un utente?
    Innanzitutto il tuo table model dovrebbe mantenere lo "stato" delle celle. Quindi devi avere una struttura dati "dietro le quinte" e implementare setValueAt() (che nota bene in AbstractTableModel è implementato "vuoto" ... non fa nulla).

    In ogni caso il valore di una cella lo puoi avere invocando getValueAt() sia dal JTable, sia direttamente dal table model.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Originariamente inviato da andbin
    Hai definito una anonymous class che estende AbstractTableModel e hai fatto l'override di getColumnClass(). Bene. Ma se togli il "tuo" getColumnClass viene ereditato quello già implementato da AbstractTableModel. E sai come è fatto quello di AbstractTableModel??

    codice:
        public Class<?> getColumnClass(int columnIndex) {
    	return Object.class;
        }
    ta-da.... praticamente come il tuo.

    Serve a scegliere il "renderer" da usare per la visualizzazione della cella. Lo spiega molto bene qui:
    http://java.sun.com/docs/books/tutor...tml#editrender

    Vedi isCellEditable() del table model, di cui devi fare l'override. (quello implementato in AbstractTableModel ritorna sempre false indipendentemente da riga/colonna).

    Innanzitutto il tuo table model dovrebbe mantenere lo "stato" delle celle. Quindi devi avere una struttura dati "dietro le quinte" e implementare setValueAt() (che nota bene in AbstractTableModel è implementato "vuoto" ... non fa nulla).

    In ogni caso il valore di una cella lo puoi avere invocando getValueAt() sia dal JTable, sia direttamente dal table model.
    Grazie mille! Comunque a me servirebbe un listener che ogni volta che una tabella viene modificata da un utente cliccando su una cella, dici che addTableModelListener vada bene?

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Dreamer89
    Comunque a me servirebbe un listener che ogni volta che una tabella viene modificata da un utente cliccando su una cella, dici che addTableModelListener vada bene?
    La questione però è che un evento TableModelEvent viene inviato ai TableModelListener quando viene invocato nel table model uno dei metodi fireXXX().

    La cosa funziona così: il table model implementa isCellEditable() per indicare se una cella è editabile o no. Se hai celle editabili, dovrai anche implementare setValueAt() così, quando l'utente ha inserito qualcosa, esso viene invocato. Il dato lo metterai nella "tua" struttura dati interna al table model e poi dovrai fare un fireTableCellUpdated(). È questo che fa sì che vengano notificati i TableModelListener registrati.

    Per dirla in altre parole, è il table model che si deve preoccupare di inviare le notifiche all'esterno.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Prima di tutto non mi è chiara una cosa... sul sito java dove c'è la documentazione, ad esempio il metodo isCellEditable è scritto in questo modo:

    isCellEditable(int rowIndex, int columnIndex)

    mentre io l'ho dichiarato così, con il nome dei parametri diverso:

    public boolean isCellEditable (int row, int col) { return true; }

    e mi funziona lo stesso! Io sapevo che un metodo che abbia solamente il nome dei parametri diverso da un altro fosse un metodo diverso, mi sa che ricordo male o_O

    Poi, ho dichiarato il metodo setValueAt:

    public void setValueAt (Object aValue, int rowIndex, int columnIndex) {}

    Ma le celle comunque non vengono modificate, mi sa che devo dichiarare un blocco di istruzioni all'interno, ma non ho idea di cosa scrivere...

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Dreamer89
    isCellEditable(int rowIndex, int columnIndex)

    mentre io l'ho dichiarato così, con il nome dei parametri diverso:

    public boolean isCellEditable (int row, int col) { return true; }

    e mi funziona lo stesso! Io sapevo che un metodo che abbia solamente il nome dei parametri diverso da un altro fosse un metodo diverso, mi sa che ricordo male o_O
    Conta la signature del metodo: nome del metodo e numero/tipo dei parametri. Non i nomi dei parametri!

    Originariamente inviato da Dreamer89
    Poi, ho dichiarato il metodo setValueAt:

    public void setValueAt (Object aValue, int rowIndex, int columnIndex) {}

    Ma le celle comunque non vengono modificate, mi sa che devo dichiarare un blocco di istruzioni all'interno, ma non ho idea di cosa scrivere...
    Qualcuno ti inserisce un valore .... dove lo metti??? Devi avere una "tua" struttura dati ... es. un array di array di String oppure un Vector di Vector di String oppure un array o Vector di un tuo tipo XYZ (che rappresenta un "record" cioè la riga) o altro. Insomma.... devi realizzare la struttura dati più comoda e utile per il tuo "modello". Quale e come lo puoi e devi stabilire solo tu.

    Quindi devi aggiornare tale struttura dati nel setValueAt e fare il fireXXX appropriato per notificare la modifica ai listener.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Allora, questo è il programma:

    codice:
    import javax.swing.JFrame;
    import javax.swing.JTable;
    import javax.swing.JScrollPane;
    import javax.swing.table.AbstractTableModel;
    
    public class TestTable extends JFrame
    {
    	private int[][] structure = new int[10][10];
    	
    	public TestTable()
    	{
    		super ("Test Table");
    		setSize (400, 300);
    		setLocationRelativeTo (null);
    		setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    		
    		for (int i = 0; i < 10; i++)
    			for (int j = 0; j < 10; j++)
    				structure[i][j] = i * j;
    		
    		JTable table = new JTable
    		(
    			new AbstractTableModel()
    			{
    				public int getColumnCount() { return 10; }
    				public int getRowCount() { return 10; }
    				public boolean isCellEditable (int row, int col) { return true; }
    				public void setValueAt (Object aValue, int rowIndex, int columnIndex) { structure[rowIndex][columnIndex] = ((Integer) aValue).intValue(); fireTableCellUpdated (rowIndex, columnIndex); }
    				public Object getValueAt (int row, int col) { return structure[row][col]; }
    				public String getColumnName (int column) { return "Nome"; }
    			}
    		);
    		
    		add (new JScrollPane (table));
    		
    		setVisible (true);
    	}
    	
    	public static void main (String[] args)
    	{
    		new TestTable();
    	}
    }
    Ma quando modifico una cella e premo invio, viene lanciata una ClassCastException... perchè? VVoVe:

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Dreamer89
    Ma quando modifico una cella e premo invio, viene lanciata una ClassCastException... perchè?
    Ovvio ... non hai fatto l'override di getColumnClass(), quindi rimane quello in AbstractTableModel che ritorna Object.class. In tal caso il renderer è una semplice JLabel che visualizza l'oggetto come stringa (toString()) mentre il renderer è un JTextField che gestisce una stringa. Quindi una stringa non la puoi "castare" a Integer.

    La soluzione più semplice? Fai ritornare Integer.class e vedrai che i campi saranno allineati a destra (per i numeri appunto) e l'oggetto gestito sarà davvero un Integer.
    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.