è possibile modificare una proprietà della JTable tramite il metodo setDefaultRenderer(). Nel caso dello screenshot sopra, la tabella è divisa in un numero indeterminato di righe, e n° 6 colonne. La colonna interessata a visualizzare le celle con una checkbox è la prima, quindi il mio interesse è di modificare la colonna in questione. Per prima cosa definiamo la classe CheckBoxTableCellRenderer, ovvero una classe che eredita da JCheckBox e che si appoggià all'interfaccia JTableCellRenderer. Quest'ultima contiene solamente un metodo: getTableCellRendererComponent(), che noi definiamo a nostro piacere e che deve ritornare il componente (oggetto grafico) che vogliamo visualizzare nella casella, dunque il JCkeckBox
import javax.swing.JCheckBox; import javax.swing.table.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.SwingConstants; import java.awt.Component; import java.awt.Insets; import javax.swing.JTable; import javax.swing.UIManager; class CheckBoxTableCellRenderer extends JCheckBox implements TableCellRenderer { Border noFocusBorder; Border focusBorder; public CheckBoxTableCellRenderer() { super(); setContentAreaFilled(true); // sfondo opaco setBorderPainted(true); setHorizontalAlignment(SwingConstants.CENTER); (allineamento orizzontale centrato) setVerticalAlignment(SwingConstants.CENTER); (allineamento verticale centrato) } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if(table == null) { //operazioni da fare nel caso la tabella non contenga alcun record } else { if (isSelected) { //variabile locale che è vera se la riga è selezionata setForeground(table.getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); } setEnabled(table.isEnabled()); //questo pezzo di codice agisce sul bordo, per eliminare l'effetto "tasto" if (hasFocus) { if (focusBorder == null) { focusBorder = UIManager.getBorder("Table.focusCellHighlightBorder"); } setBorder(focusBorder); } else { if (noFocusBorder == null) { if (focusBorder == null) { focusBorder = UIManager.getBorder("Table.focusCellHighlightBorder"); } if (focusBorder != null) { Insets n = focusBorder.getBorderInsets(this); noFocusBorder = new EmptyBorder(n); } } setBorder(noFocusBorder); } //seleziona o meno il JCheckBox, in base al valore della cella (riga selezionata o meno) setSelected(Boolean.TRUE.equals(value)); } //ritorna il JCheckBox return this; } }
Definita la classe CheckBoxTableCellRenderer, dobbiamo adesso adottarla nella JTable.
Supponiamo di avere una JTable di nome "table", quindi:
TableColumnModel tcm = table.getColumnModel(); TableColumn tc = tcm.getColumn(0); //la prima colonna è quella che ci interessa, in questo esempio tc.setCellRenderer(new CheckBoxTableCellRenderer());
Fatto ciò, la prima colonna dunque apparirà come una lista di JCheckBox ordinati in verticale, proprio come nello screenshot sopra. Ma c'è ancora una cosa che manca: l'editor. Infatti se proviamo a modificare il valore di una JCheckBox (quindi il selezionare/deselezionare una riga), notiamo un'anomalia: compare la scritta "true" o "false". Perché? Perchè una JTable di default implementa una DefaultCellEditor, che mostra le celle come dei JTextBox, quindi mostra "true" o "false", in modo testo. Dunque un piccolo passaggio è doveroso:
tc.setCellEditor(new DefaultCellEditor(new JCheckBox())); this.setCellSelectionEnabled(false);
Infatti (pace all'anima nostra), DefaultCellEditor prevede un costruttore con una JCheckBox. Mentre setCellSelectionEnabled() evita che si selezionino (con conseguente cambiamento del colore) le righe intere, infatti a noi interessa distinguere se una riga è selezionata o meno guardando il JCheckBox.
Ricapitolando, i due passaggi fondamentali da compiere sulla colonna sono 2: modificare il suo renderer, e modificare il suo editor . Il renderer viene eseguito solamente quando la tabella viene disegnata, mentre il comportamento (editor) viene eseguito ogni qual volta modifichiamo il valore di una JCheckBox.
E' tutto.
Alberto
Nessun commento:
Posta un commento