Nimbus TableHeader未突出显示为&#pressed'. [英] Nimbus TableHeader was not highlighted as 'pressed'

查看:45
本文介绍了Nimbus TableHeader未突出显示为&#pressed'.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

默认情况下,JTableHaeder没有按下"突出显示.(雨云)

The JTableHaeder has no 'pressed' highlighting by default. (Nimbus)

NimbusDefaults 说它具有默认值[Pressed]背景画家.

NimbusDefaults says it has a default [Pressed] background painter.

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

What should I do, to see this when i click on the TableHeader?

更新1

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

The NimbusStyle.getExtendedState returns the PRESSED on mouseDown correctly. But the NimbusStyle.getBackgroundPainter(SynthContext) returns null cause there is an null in the NimbusStyle.Values cache for the CacheKey "backgroundPainter$$instance" with this state.

那是怎么了?

更新2

我的示例显示了一个JTableHeader和一个带有'Pressed Behavior'的JScrollBar.

My example shows a JTableHeader and a JScrollBar with an 'Pressed Behavior'.

对于JScrollBar,我的 putClientProperty("Nimbus.State")可以解决重画问题.

For the JScrollBar my putClientProperty( "Nimbus.State" ) works with a repaint problem.

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本身上使用该状态:

technically, you need that state on the rendering component, not on the JTableHeader itself:

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

然后的问题是,所有列都使用(渲染组件的)相同实例,因此如果拖动列,则所有列都显示为已按下...

Problem then is that the same instance (of rendering component) is used for all columns, so if you drag a column all appear pressed ...

忍不住要挖了一点……Nimbus太糟糕了……缺乏,温和地说;-)

couldn't resist to dig a bit ... Nimbus is soooo ... lacking, to put it mildly ;-)

结果表明,默认值确实具有按下的样式,缺少的是设置它的逻辑.可能并非完全无关紧要,因为逻辑(aka:MouseListener)驻留在BasicTableHeaderUI中,该UI不了解子类的绘制器状态.逻辑所支持的唯一问题(热针固定)是翻转意识,而不是紧迫感.

Turns out that the defaults indeed have the styles for pressed, what's missing is the logic to set it. Probably not entirely trivial, because the logic (aka: MouseListener) resides in BasicTableHeaderUI which doesn't know about subclass' painter states. The only thingy the logic is supporting (hot needle fix) is rollover-awareness, but not pressed-ness.

虽然我们无法了解逻辑(嗯,我们可以...但是那是另一把戏:-),但我们可以在JTableHeader中查找次要状态更改,例如draggingColumn/resizingColumn(未绑定)属性,然后让自定义渲染器会根据需要自行更新.以下是操作方法的概述:

While we can't hook into the logic (well, we could ... but that's another trick :-) we can look for secondary state changes like draggingColumn/resizingColumn (not-bound) properties in JTableHeader and let a custom renderer update itself as appropriate. Here's a line-out of how-to:

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

这篇关于Nimbus TableHeader未突出显示为&#pressed'.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆