Attualmente sto creando un piccolo JTable e voglio evidenziare l'intestazione di colonna (e le intestazioni di riga - la parte di intestazione di riga è effettivamente funzionante) quando viene selezionata una cella per rendere più facile trova i nomi associati con questa cella. Ecco una foto:Evidenziando un'intestazione di colonna di un JTable
Ho già provato la commutazione fuori il renderer per l'intestazione con questo:
table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer());
Ma è chiamato solo quando scatto sopra l'intestazione e dice sempre isSelected è falso .
Questo è il codice che uso per la riga-nomi, tra cui l'evidenziazione all'interno del renderer - codice non è da me, ho appena modificato un po ':
/*
* Use a JTable as a renderer for row numbers of a given main table.
* This table must be added to the row header of the scrollpane that
* contains the main table.
*/
public class RowNameTable extends JTable
implements ChangeListener, PropertyChangeListener {
private JTable main;
public RowNameTable(JTable table) {
main = table;
main.addPropertyChangeListener(this);
setFocusable(false);
setAutoCreateColumnsFromModel(false);
setModel(main.getModel());
setSelectionModel(main.getSelectionModel());
TableColumn column = new TableColumn();
column.setHeaderValue(" ");
addColumn(column);
column.setCellRenderer(new RowNameRenderer(main));
getColumnModel().getColumn(0).setPreferredWidth(table.getColumnModel().getColumn(0).getPreferredWidth());
setPreferredScrollableViewportSize(getPreferredSize());
}
@Override
public void addNotify() {
super.addNotify();
Component c = getParent();
// Keep scrolling of the row table in sync with the main table.
if (c instanceof JViewport) {
JViewport viewport = (JViewport) c;
viewport.addChangeListener(this);
}
}
/*
* Delegate method to main table
*/
@Override
public int getRowCount() {
return main.getRowCount();
}
@Override
public int getRowHeight(int row) {
return main.getRowHeight(row);
}
/*
* This table does not use any data from the main TableModel,
* so just return a value based on the row parameter.
*/
@Override
public Object getValueAt(int row, int column) {
return Integer.toString(row + 1);
}
/*
* Don't edit data in the main TableModel by mistake
*/
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
//
// Implement the ChangeListener
//
public void stateChanged(ChangeEvent e) {
// Keep the scrolling of the row table in sync with main table
JViewport viewport = (JViewport) e.getSource();
JScrollPane scrollPane = (JScrollPane) viewport.getParent();
scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
}
//
// Implement the PropertyChangeListener
//
public void propertyChange(PropertyChangeEvent e) {
// Keep the row table in sync with the main table
if ("selectionModel".equals(e.getPropertyName())) {
setSelectionModel(main.getSelectionModel());
}
if ("model".equals(e.getPropertyName())) {
setModel(main.getModel());
}
}
/*
* Borrow the renderer from JDK1.4.2 table header
*/
private static class RowNameRenderer extends DefaultTableCellRenderer {
private JTable main;
public RowNameRenderer(JTable main) {
this.main = main;
setHorizontalAlignment(JLabel.CENTER);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (table != null) {
JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
}
if (isSelected) {
setFont(getFont().deriveFont(Font.BOLD));
}
setText((value == null) ? "" : main.getColumnName(row));
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
}
}
E qui abbiamo la parte pertinente per creare la tabella:
costTableModel = new CostTableModel(costCalc);
table = new JTable(costTableModel);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setCellSelectionEnabled(true);
scrollPane = new JScrollPane(table);
RowNameTable nameTable = new RowNameTable(table);
scrollPane.setRowHeaderView(nameTable);
E il costTableModel di classe, solo per completezza:
public class CostTableModel extends AbstractTableModel {
private CostCalculator costCalc;
public CostTableModel(CostCalculator costCalc) {
this.costCalc = costCalc;
}
@Override
public int getRowCount() {
return costCalc.getPersonsList().size();
}
@Override
public int getColumnCount() {
return costCalc.getPersonsList().size();
}
@Override
public String getColumnName(int col) {
return costCalc.getPersonsList().get(col).getName();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Person debtor = costCalc.getPersonsList().get(rowIndex);
Person debtee = costCalc.getPersonsList().get(columnIndex);
return costCalc.getAmountOwed(debtor, debtee);
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}
Grazie per il vostro aiuto in anticipo!
Prima di tutto, grazie! Mi sembra proprio quello di cui ho bisogno, al momento non ho il tempo di implementarlo nel mio codice, ma lo farò stasera e riferirò qui. – wlfbck
Va bene, ora lo costruisco! Funziona perfettamente, tranne che per una piccola cosa (segnando diverse intestazioni di colonne), ma cercherò di capirlo da solo e di saperne di più su JTables :) – wlfbck
hmm ... non capisco come ascoltare la selezione _row_ aiuta a ridipingere su _column_ cambiamenti di selezione. In realtà, non lo fa: seleziona una cella, quindi sposta la selezione nella stessa riga e l'evidenziazione della colonna non viene aggiornata. – kleopatra