从技术上讲,您需要渲染组件上的状态,而不是 JTableHeader 本身上的状态:
@Override
public void mousePressed( MouseEvent e ) {
JComponent source = (JComponent)e.getComponent();
source.putClientProperty( "Nimbus.State", "Pressed" );
if (source instanceof JTableHeader) {
((JComponent) ((JTableHeader) source).getDefaultRenderer())
.putClientProperty("Nimbus.State", "Pressed");
}
}
那么问题是所有列都使用同一个实例(渲染组件),因此如果您拖动一列,所有列都会显示为按下状态......
编辑:忍不住要挖掘一下...... Nimbus 太......缺乏,温和地说;-)
事实证明,默认值确实具有按下的样式,缺少的是设置它的逻辑。可能并不完全微不足道,因为逻辑(又名:MouseListener)驻留在 BasicTableHeaderUI 中,它不知道子类的画家状态。逻辑支持的唯一事情(热针修复)是翻转意识,而不是压力意识。
虽然我们无法挂钩逻辑(好吧,我们可以......但这是另一个技巧:-),我们可以寻找辅助状态更改,例如 JTableHeader 中的 DraggingColumn/resizingColumn (未绑定)属性,并让自定义渲染器自行更新作为适当的。以下是操作方法的概述:
public static class WrappingRenderer implements TableCellRenderer {
private DefaultTableCellHeaderRenderer delegate;
private JTableHeader header;
public WrappingRenderer(JTableHeader header) {
this.header = header;
this.delegate = (DefaultTableCellHeaderRenderer) header.getDefaultRenderer();
header.setDefaultRenderer(this);
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component comp = delegate.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
TableColumn draggedColumn = table.getTableHeader().getDraggedColumn();
if (draggedColumn != null) {
if (table.convertColumnIndexToModel(column) == draggedColumn.getModelIndex()) {
setNimbusState("Pressed");
} else {
setNimbusState(null);
}
} else {
setNimbusState(null);
}
// do similar for resizing column
return comp;
}
public void setNimbusState(String state) {
delegate.putClientProperty("Nimbus.State", state);
}
}