|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
[JAVA] Aggiungere e modificare da una Jtable
Salve,
devo realizzare una matrice di tutte stringhe. c1 c2 c3 c4 c5 x x x x x x x x x x x x x x x Le prime informazioni che andrò ad inserire sono i primi due campi (c1 e c2) ma ogni volta che mi viene data una nuova informazione io devo aggiungerla. Come faccio ? ovviamente se c1 è la chiave primaria di questa matrice l'informazione che arriva in un secondo tempo mi verrà data assieme alla chiave ... mi aiutate? |
![]() |
![]() |
![]() |
#2 |
Member
Iscritto dal: Sep 2005
Messaggi: 274
|
Usa la classe TableModel!
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
e le ricerche ? i riposizionamenti ? come li faccio ?
|
![]() |
![]() |
![]() |
#4 | ||
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Proviamo a fare un esperimento di programmazione orientata agli oggetti: pieghiamo una tabella al nostro volere
![]() Come dice spv42, si tratta di creare un modello ad hoc per una tabella. Il fatto che si deva passare per il modello non c'entra nulla con l'orientamento agli oggetti, ovviamente. Semplicemente le tabelle Swing sono fatte così. Partiamo dallo scheletro. Codice:
import javax.swing.table.*; public class MyTableModel extends AbstractTableModel { } Codice:
import javax.swing.table.*; public class MyTableModel extends AbstractTableModel { private int numeroDiColonne = 5; public int getColumnCount() { return numeroDiColonne; } } Codice:
import javax.swing.table.*; import java.util.*; public class MyTableModel extends AbstractTableModel { private LinkedList<String[]> righe = new LinkedList<String[]>(); private int numeroDiColonne = 5; public int getColumnCount() { return numeroDiColonne; } public int getRowCount() { return righe.size(); } } Supponendo che ogni nodo della lista righe contenga un array di 5 componenti String, il nostro getValueAt diventa: Codice:
import javax.swing.table.*; import java.util.*; public class MyTableModel extends AbstractTableModel { private LinkedList<String[]> righe = new LinkedList<String[]>(); private int numeroDiColonne = 5; public int getColumnCount() { return numeroDiColonne; } public int getRowCount() { return righe.size(); } public Object getValueAt(int indiceRiga, int indiceColonna) { String[] riga = righe.get(indiceRiga); return riga[indiceColonna]; } } Quote:
Codice:
import javax.swing.table.*; import java.util.*; public class MyTableModel extends AbstractTableModel { private LinkedList<String[]> righe = new LinkedList<String[]>(); private int numeroDiColonne = 5; public int getColumnCount() { return numeroDiColonne; } public int getRowCount() { return righe.size(); } public Object getValueAt(int indiceRiga, int indiceColonna) { String[] riga = righe.get(indiceRiga); return riga[indiceColonna]; } public void aggiungiRiga(String c1, String c2) { String[] riga = new String[5]; riga[0] = c1; riga[1] = c2; righe.add(riga); fireTableRowsInserted(righe.size() - 1, righe.size() - 1); } } ![]() Codice:
import javax.swing.*; import javax.swing.table.*; public class Main { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new Main().start(); } }); } private final MyTableModel tableModel = new MyTableModel(); private void start() { JTable table = new JTable(tableModel); JScrollPane scroller = new JScrollPane(table); JFrame window = new JFrame("MyTableModel Sample"); window.add(scroller); window.pack(); window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); window.setVisible(true); } } Codice:
import javax.swing.*; import javax.swing.table.*; public class Main { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new Main().start(); } }); } private final MyTableModel tableModel = new MyTableModel(); private void start() { tableModel.aggiungiRiga("1", "Pippo"); tableModel.aggiungiRiga("2", "Gianni"); JTable table = new JTable(tableModel); JScrollPane scroller = new JScrollPane(table); JFrame window = new JFrame("MyTableModel Sample"); window.add(scroller); window.pack(); window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); window.setVisible(true); } } specificando i suoi due valori iniziali. A questo punto c'è un inghippo di intrepretazione. Quote:
valore della chiave primaria, il nome della colonna a cui corriponde il valore ed il valore da inserire. Ma qui occorrerà poi stabilire cosa deve succedere nel caso in cui manchi una riga con quella chiave primaria. Comunque, restando alla prima parte, potremmo pensare all'introduzione di un metodo di questo genere: setValore(String chiavePrimaria, String nomeColonna, String valore) realizzato ad esempio in questo modo: Codice:
import javax.swing.table.*; import java.util.*; public class MyTableModel extends AbstractTableModel { private String[] nomiColonne = { "ID", "NOME", "CF", "P.IVA", "TEL" }; private Map<String, Integer> mappaNomiColonne = new HashMap<String, Integer>(); private LinkedList<String[]> righe = new LinkedList<String[]>(); private int numeroDiColonne = 5; public MyTableModel() { for(int i = 0; i < nomiColonne.length; i++) { mappaNomiColonne.put(nomiColonne[i], i); } } public String getColumnName(int column) { return nomiColonne[column]; } public int getColumnCount() { return numeroDiColonne; } public int getRowCount() { return righe.size(); } public Object getValueAt(int indiceRiga, int indiceColonna) { String[] riga = righe.get(indiceRiga); return riga[indiceColonna]; } public void aggiungiRiga(String c1, String c2) { String[] riga = new String[5]; riga[0] = c1; riga[1] = c2; righe.add(riga); fireTableRowsInserted(righe.size() - 1, righe.size() - 1); } public void setValore(String chiavePrimaria, String nomeColonna, String valore) throws Exception { int indiceRiga = getIndiceRiga(chiavePrimaria); if(indiceRiga < 0) { throw new Exception("Manca una riga per la chiave primaria: " + chiavePrimaria); } String[] riga = righe.get(indiceRiga); int indiceColonna = getIndiceColonna(nomeColonna); if(indiceColonna < 0) { throw new Exception("Manga una colonna di nome: " + nomeColonna); } riga[indiceColonna] = valore; fireTableRowsUpdated(indiceRiga, indiceRiga); } private int getIndiceRiga(String chiavePrimariaCercata) { int indice = -1; for(int i = 0; i < righe.size() && indice == -1; i++) { String chiavePrimariaRiga = righe.get(i)[0]; if(chiavePrimariaRiga.equals(chiavePrimariaCercata)) { indice = i; } } return indice; } private int getIndiceColonna(String nomeColonna) { Integer indice = mappaNomiColonne.get(nomeColonna); return indice != null ? indice : -1; } } Codice:
tableModel.aggiungiRiga("1", "Pippo"); tableModel.aggiungiRiga("2", "Gianni"); Codice:
try { tableModel.setValore("2", "TEL", "555-9191"); } catch(Exception ex) { ex.printStackTrace(); }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
||
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
Quote:
|
|
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
Riguardo la questione del TableModel l'ho fatto così :
Codice:
import javax.swing.table.*; import java.util.*; public class MyTableModel extends AbstractTableModel { Vector canali_mod = null; public MyTableModel(Vector canali) { canali_mod = canali; } public int getRowCount() { return canali_mod.size(); } public int getColumnCount() { Vector appoggio = (Vector) canali_mod.get(0); return appoggio.size(); } public Object getValueAt(int rowIndex, int columnIndex) { Vector appoggio = (Vector) canali_mod.get(rowIndex); return appoggio.get(columnIndex); } } |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Vector è una classe "legacy": esiste per questioni di retrocompatibilità. Al suo posto dovresti usare ArrayList.
ArrayList<ArrayList<String>> canaliMod eccetera... Una tabella estrai i nomi delle colonne dal suo modello, invocando il metodo getColumnName(int index) di quest'ultimo. Fai restituire a questo metodo le stringhe opportune e avrai i nomi che desideri. Per colorare le righe devi creare un TableCellRenderer. Se vuoi posso farti un esempio (stavolta breve, lo prometto ![]()
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
Quote:
|
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Per l'aspetto la questione può diventare intricata ma ai minimi termini si riduce a:
Codice:
import java.awt.*; import javax.swing.*; import javax.swing.table.*; public class MyTableRenderer extends DefaultTableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component original = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); Color background = isSelected ? table.getSelectionBackground() : row % 2 == 0 ? Color.LIGHT_GRAY : table.getBackground(); original.setBackground(background); return original; } } Per applicare il renderer ad una tabella devi semplicemente invocare: tabella.setDefaultRenderer(Object.class, new MyTableRenderer());
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
Quote:
|
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
![]() L'espressione: NomeDiUnTipo.class Restituisce un riferimento al tipo nominato. Cioè: Object.class è un'espressione che restituisce un valore di tipo Class<Object>. String.class è un'espressione che restituisce un valore di tipo Class<String>. e così via per ogni Tipo. Il metodo setDefaultRenderer richiede un riferimento di tipo Class. Il riferimento di tipo Class specifica quale colonna userà quel renderer. Ogni colonna di una tabella è associata ad un tipo di oggetti. La tabella usa il renderer specificato per disegnare le celle della colonna il cui tipo è quello usato nel metodo setDefaultRenderer. Nel nostro caso, per ogni colonna le cui celle contengono valori di tipo Object sarà usato il renderer MyTableRenderer.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
Mi sono creato la MyTableRenderer in modo che le celle di una certa colonna cambino colore in funzione del dato contenute in esse. Però vorrei fare che tutta la riga mi cambi dello stesso colore in funzione del dato contenuto in quella cella.
Codice:
public class MyTableRenderer extends DefaultTableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component original = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); Color background = table.getBackground(); Color grid = Color.YELLOW; if (column == 6) { String valore = String.valueOf(value); Long secondi = Long.valueOf(valore)*1000; Long now = System.currentTimeMillis(); if ((now-secondi > 120000)&&(now-secondi<=600000)) { background = Color.ORANGE; } else if (now-secondi > 600000) { background = Color.RED; } else { background = Color.GREEN; } } original.setBackground(background); return original; } |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Puoi usare il parametro table (e il suo metodo getValueAt(row, col)) per collegare la proiezione di una cella di una riga al valore di un'altra cella in quella riga.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
Meno male che me l'hai detto guarda cosa mi ero inventato :
Codice:
public class MyTableRenderer extends DefaultTableCellRenderer { Vector canali = null; Vector riga_colore=new Vector(); public MyTableRenderer(Vector canals) { canali=canals; for (int i=0;i<canali.size();i++) { Vector appoggio = (Vector) canali.get(i); String valore = String.valueOf(appoggio.get(6)); Long secondi = Long.valueOf(valore)*1000; Long now = System.currentTimeMillis(); if ((now-secondi > 120000)&&(now-secondi<=600000)) { Vector temp = new Vector(); temp.addElement(i); temp.addElement(Color.ORANGE); riga_colore.addElement(temp); } else if (now-secondi > 600000) { Vector temp = new Vector(); temp.addElement(i); temp.addElement(Color.RED); riga_colore.addElement(temp); } else { Vector temp = new Vector(); temp.addElement(i); temp.addElement(Color.GREEN); riga_colore.addElement(temp); } } } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component original = super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column); Color background = table.getBackground(); Color grid = Color.YELLOW; /* if (column == 6) { String valore = String.valueOf(value); Long secondi = Long.valueOf(valore)*1000; Long now = System.currentTimeMillis(); if ((now-secondi > 120000)&&(now-secondi<=600000)) { background = Color.ORANGE; } else if (now-secondi > 600000) { background = Color.RED; } else { background = Color.GREEN; } }*/ Vector appoggio = (Vector) riga_colore.get(row) ; background = (Color) appoggio.get(1); original.setBackground(background); return original; } } |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Jul 2002
Città: Napoli
Messaggi: 1964
|
Ma per il ridimensionamento automatico delle celle ? Nel senso che : voglio che la larghezza delle colonne si adatti al contenuto delle stesse ...
|
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Devi farlo a mano. Le API ti danno la possibilità (TableColumn) di adattare la larghezza delle colonne alla larghezza dell'intestazione. Non prevedono, invece, l'adattamento alla larghezza del contenuto della cella (genere "assumi la larghezza della cella col contenuto più largo).
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Ciao,
volevo sapere una cosa. Ho sempre usato JTable (magari non a livello molto avanzato) per mostrare dati e per farli visualizzare ho sempre passato come argomento delle matrici contenenti i dati. Per fare ciò, mi sono scritto un metodo che fa la query e restituisce la matrice... che poi passerò a JTable. E' questa la procedura corretta o ne esiste una migliore? |
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Una volta che hai per le mani una tabella hai già toccato il fondo dell'interazione utente.
Questo rende più o meno irrilevante tutto il resto. In ogni caso, non vedo controindicazioni al tuo metodo. Teoricamente potresti usare TableModel per nascondere la provenienza dei dati ma si tratta di un mezzo meno immediato di quanto possa sembrare. La tabella richiede al modello i dati riga per riga, colonna per colonna. Per creare un TableModel che prelevi i dati direttamente dal database occorre creare un qualche genere di "caching" delle informazioni, onde evitare di fare una query per ogni richiesta getValueAt. Dovendo scegliere tra questo modo e il tuo, io sceglierei il tuo ![]()
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#19 | |
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Quote:
![]() Il tuo parere è stato molto utile per me, ottimo thread questo, e soprattutto molto utile. Ciao!!! ![]() |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:34.