Tôi hiện đang xây dựng một JTable nhỏ và muốn đánh dấu tiêu đề cột (và tiêu đề hàng - phần tiêu đề hàng thực sự hoạt động) khi một ô được chọn để giúp dễ dàng hơn tìm tên được liên kết với ô này. Dưới đây là một hình ảnh:Làm nổi bật tiêu đề cột của JTable
Tôi đã cố gắng chuyển đổi ra các renderer cho tiêu đề với điều này:
table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer());
Nhưng nó chỉ được gọi khi tôi nhấp vào tiêu đề và luôn nói isSelected là sai .
Đây là mã tôi sử dụng cho hàng-tên, bao gồm các điểm nhấn bên trong renderer - Mã không phải là của tôi, tôi chỉ cần sửa đổi nó một chút:
/*
* 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;
}
}
}
Và ở đây chúng tôi có một phần liên quan để tạo ra bảng:
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);
Và costTableModel lớp, chỉ cho đầy đủ vì:
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();
}
}
Cảm ơn sự giúp đỡ của bạn trước!
Trước hết, cảm ơn! Điều đó trông khá giống với những gì tôi cần, tôi hiện không có thời gian để thực hiện nó vào mã của tôi, nhưng tôi sẽ làm điều đó tối nay và báo cáo lại ở đây. – wlfbck
Được rồi, tôi đã tạo nó ngay bây giờ! Nó hoạt động hoàn hảo, ngoại trừ một điều nhỏ (đánh dấu một số tiêu đề cột), nhưng tôi sẽ cố gắng tìm ra điều đó và tự tìm hiểu thêm về JTables :) – wlfbck
hmm ... không hiểu cách nghe lựa chọn _row_ giúp vẽ lại các thay đổi lựa chọn _column_. Trên thực tế, nó không: chọn một ô, sau đó di chuyển vùng chọn trong cùng hàng và điểm nổi bật của cột không được cập nhật. – kleopatra