Nimbus TableHeader was not highlighted as "clicked"

JTableHaeder does not highlight selection by default. (Halo)

NimbusDefaults says it has a default background artist [clicked].

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

NimbusDefaultPainter


UPDATE 1

NimbusStyle.getExtendedState returns the PRESSED value on mouseDown correctly. But NimbusStyle.getBackgroundPainter(SynthContext) returns null because there is null in the NimbusStyle.Values cache for the "backgroundPainter $$ instance" CacheKey cache.

What is wrong there?


UPDATE 2

My example shows a JTableHeader and a JScrollBar with "clicked behavior".

For JScrollBar, my putClientProperty( "Nimbus.State" ) works with a redraw 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(); } } } 
+6
source share
1 answer

technically, you need this state on the rendering component, and 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"); } } 

The problem is that the same instance (rendering component) is used for all columns, so if you drag a column, everyone appears clicked ...

Edit: couldn't resist to dig a little ... Nimbus is soooo ... not enough, to say the least ,-)

It turns out that by default there really are styles for clicking, that there is no logic for setting it. Probably not entirely trivial, because the logic (aka: MouseListener) is in BasicTableHeaderUI, which does not know about the states of the subclass. The only thing that logic supports (hot-needle correction) is rollover awareness, but not tapping.

While we can’t connect to the logic (well, we could ... but this is another trick :-), we can look for secondary state changes, such as draggingColumn / resizingColumn (unrelated) properties in the JTableHeader, and allow user rendering to update itself by oneself. Here is a usage example:

 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); } } 
+3
source

Source: https://habr.com/ru/post/886794/


All Articles