Nimbus TableHeader未突出显示为“已按下”

JTableHaeder默认没有“按下”突出显示。 (雨云)

NimbusDefaults表示它有一个默认的[Pressed]背景画家。

当我点击TableHeader时,我该怎么办?

NimbusDefaultPainter


更新1

NimbusStyle.getExtendedState正确返回mouseDown上的PRESSED。 但是NimbusStyle.getBackgroundPainter(SynthContext)返回null因为具有此状态的CacheKey “backgroundPainter $$实例”NimbusStyle.Values缓存中存在null

有什么问题?


更新2

我的示例显示了一个JTableHeader和一个带有“Pressed Behavior”的JScrollBar。

对于JScrollBar,我的putClientProperty( "Nimbus.State" )与重绘问题一起使用。

 public class Header extends JPanel{ public Header() { super(new BorderLayout()); JTableHeader header = new JTable(5, 3).getTableHeader(); JScrollBar scroll = new JScrollBar(JScrollBar.HORIZONTAL); add(header, BorderLayout.NORTH); add(scroll, BorderLayout.SOUTH); scroll.addMouseListener( new PressedBehavior() ); header.addMouseListener( new PressedBehavior() ); } static public void main( String[] s ) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); SwingUtilities.invokeLater( new Runnable() { @Override public void run() { JFrame f = new JFrame("Nimbus Pressed Example"); f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); f.setBounds( 150, 150, 300, 200 ); f.getContentPane().add( new Header() ); f.setVisible( true ); } }); } catch( Exception fail ) { /*ignore*/ } } private class PressedBehavior extends MouseAdapter { @Override public void mouseReleased( MouseEvent e ) { JComponent source = (JComponent)e.getComponent(); source.putClientProperty( "Nimbus.State", null ); } @Override public void mousePressed( MouseEvent e ) { JComponent source = (JComponent)e.getComponent(); source.putClientProperty( "Nimbus.State", "Pressed" ); //source.invalidate(); //source.repaint(); } } } 

从技术上讲,您需要渲染组件上的状态,而不是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太笨了……缺乏,说得温和;-)

事实certificate,默认设置确实具有按下的样式,缺少的是设置它的逻辑。 可能并非完全无关紧要,因为逻辑(又名:MouseListener)驻留在BasicTableHeaderUI中,它不知道子类的画家状态。 逻辑支持的唯一东西(热针修复)是翻滚意识,但不是按压。

虽然我们无法挂钩逻辑(好吧,我们可以…但这是另一个技巧:-)我们可以在JTableHeader中查找二次状态更改,例如draggingColumn / resizingColumn(not-bound)属性,并让自定义渲染器自行更新作为适当的。 这是一个方法的线索:

 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); } }