Creare un modello personalizzato per una JTable
In Java, ogni tabella utilizza un modello per gestire i dati rappresentati.
Il modello in questione deve implementare i metodi definiti nell’interfaccia javax.swing.table.TableModel. Qualora non venisse specificato un modello, la classe JTable crea un’istanza di javax.swing.table.DefaultTableModel
Nell’esempio che segue, creeremo una classe Person che rappresenterà il dato da mostrare in una riga della tabella.
Estenderemo la classe import javax.swing.table.AbstractTableModel, che esonera il programmatore dal dover implementare tutti i metodi dell’interfaccia TableModel, effettuando l’overriding dei soli metodi necessari e utilizzeremo tale model in una JTable.
Verrà inoltre mostrato come creare una cella contenente una combo box (per la scelta del sesso):
Person.java
package test; public class Person { private String firstName; private String lastName; private String sex; public Person() { this("", "", ""); } public Person(String firstName, String lastName, String sex) { this.firstName = firstName; this.lastName = lastName; this.sex = sex; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
PersonTableModel.java
package test; import javax.swing.table.AbstractTableModel; import java.util.Vector; public class PersonTableModel extends AbstractTableModel { Vector<Person> content; String[] headers; public PersonTableModel() { content = new Vector<Person>(); headers = new String[]{"Nome", "Cognome", "Sesso"}; } // numero di righe public int getRowCount() { return this.content.size(); } // numero di colonne public int getColumnCount() { return headers.length; } // nome di una determinata colonna @Override public String getColumnName(int columnIndex) { return headers[columnIndex]; } // valore di una determinata cella public Object getValueAt(int rowIndex, int columnIndex) { Person row = content.elementAt(rowIndex); if(columnIndex == 0) { return row.getFirstName(); } else if(columnIndex == 1) { return row.getLastName(); } else if(columnIndex == 2) { return row.getSex(); } return null; } // setto il valore di una cella // viene richiamato subito dopo l'editing fatto attraverso la GUI @Override public void setValueAt(Object value, int rowIndex, int columnIndex) { Person row = this.content.elementAt(rowIndex); String strValue = (String)value; if(columnIndex == 0) { row.setFirstName(strValue); } else if(columnIndex == 1) { row.setLastName(strValue); } else if(columnIndex == 2) { row.setSex(strValue); } } // Sempre true indica che qualsiasi cella è editabile @Override public boolean isCellEditable(int rowIndex, int colIndex) { return true; } // utilizzata per differenziare la classe con cui è rappresentata // una colonna (usata per la nostra combo box) @Override public Class getColumnClass(int colIndex) { return this.getValueAt(0, colIndex).getClass(); } // aggiungo n persone public void addPeople(Person... persons) { for(Person person : persons) { this.content.add(person); } } }
Main.java
package test; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.JTable; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; public class Main extends JFrame { private JTable table; private PersonTableModel model; public Main() { super("JTable test"); // creo il modello model = new PersonTableModel(); model.addPeople( new Person("Antonio","Tancredi", "Uomo"), new Person("Maria", "Bianchi", "Donna"), new Person("Massimo", "Verdi", "Uomo") ); // setto il modello this.table = new JTable(model); this.table.setFillsViewportHeight(true); // creo la combobox JComboBox comboBox = this.createComboBox("Uomo", "Donna"); // setto, come editor della colonna 2, la combo box table.getColumnModel().getColumn(2).setCellEditor( new DefaultCellEditor(comboBox)); this.getContentPane().add(new JScrollPane(this.table)); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(300, 300); this.setLocationRelativeTo(null); } public JComboBox createComboBox(String... items) { JComboBox retv = new JComboBox(); for(String item : items) { retv.addItem(item); } return retv; } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new Main().setVisible(true); } } ); } }
Il risultato è il seguente: