5

デフォルトでは、JTableHaeder には「押された」強調表示がありません。(ニンバス)

NimbusDefaultsは、デフォルトの [Pressed] バックグラウンド ペインターがあると言います。

TableHeader をクリックしたときにこれを表示するにはどうすればよいですか?

NimbusDefaultPainter


更新 1

mouseDownNimbusStyle.getExtendedStateで PRESSED を正しく返します。しかし、この状態の CacheKey "backgroundPainter$$instance"のキャッシュがNimbusStyle.getBackgroundPainter(SynthContext)返さnullれる原因となります。nullNimbusStyle.Values

何が問題なのですか?


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

問題は、(レンダリング コンポーネントの) 同じインスタンスがすべての列に使用されるため、列をドラッグするとすべてが押されたように見えることです ...

編集:少し掘るのに抵抗できませんでした...ニンバスはすっごく...欠けています、控えめに言っても;-)

デフォルトには実際に押されたスタイルがあることがわかりました。欠けているのは、それを設定するロジックです。ロジック (別名: MouseListener) は、サブクラスのペインタの状態を認識しない BasicTableHeaderUI に存在するため、おそらく完全に自明ではありません。ロジックがサポートしている唯一のもの (ホット ニードル フィックス) は、ロールオーバー認識ですが、押された状態ではありません。

ロジックにフックすることはできませんが (まあ、できます... しかし、それは別のトリックです :-) JTableHeader の dragColumn/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 に答える