Nimbus TableHeader未突出显示为“已按下” [英] Nimbus TableHeader was not highlighted as 'pressed'
问题描述
默认情况下,JTableHaeder没有按下突出显示。 (Nimbus)
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
因为 null
在具有此状态的CacheKey backgroundPainter $$实例的 NimbusStyle.Values
缓存中。
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.
那里有什么问题?
UPDATE 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是soooo ......缺乏,说得温和; - )
couldn't resist to dig a bit ... Nimbus is soooo ... lacking, to put it mildly ;-)
原来,默认情况确实有按下的样式,缺少的是设置它的逻辑。可能并非完全无关紧要,因为逻辑(又名:MouseListener)驻留在BasicTableHeaderUI中,它不知道子类的画家状态。逻辑支持的唯一东西(热针修复)是翻滚意识,但不是按压。
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.
虽然我们无法挂钩逻辑(好吧,我们可以...但这是另一个技巧:-)我们可以寻找二次状态更改,如draggingColumn / resizingColumn JTableHeader中的(未绑定)属性,并让自定义渲染器根据需要自行更新。以下是操作方法的输出:
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未突出显示为“已按下”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!