5

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

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

当我单击 TableHeader 时,我应该怎么做才能看到这个?

NimbusDefaultPainter


更新 1

正确返回 mouseDown 上的NimbusStyle.getExtendedStatePRESSED。但是NimbusStyle.getBackgroundPainter(SynthContext)返回null原因是缓存中有一个null缓存NimbusStyle.Values“backgroundPainter$$instance”具有这种状态。

那里有什么问题?


更新 2

我的示例显示了一个 JTableHeader 和一个具有“按下行为”的 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();
        }
    }
}
4

1 回答 1

3

从技术上讲,您需要呈现组件上的状态,而不是 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);
    }
}
于 2011-05-04T14:27:04.493 回答