2011-04-27 38 views
6

默認情況下,JTableHaeder沒有「已按下」高亮顯示。 (Nimbus)Nimbus TableHeader未被高亮顯示爲「已按下」

NimbusDefaults說它有一個默認[按]後臺畫家。

當我點擊TableHeader時,該怎麼辦?

NimbusDefaultPainter


UPDATE 1

NimbusStyle.getExtendedState返回按壓在鼠標按下正確。但NimbusStyle.getBackgroundPainter(SynthContext)返回null原因有nullNimbusStyle.Values高速緩存中的CacheKey 「backgroundPainter $$實例」與此狀態。

那裏有什麼問題?


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

回答

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

問題則是,(渲染組件)相同的實例用於所有列,所以如果拖動一列都出現壓...

編輯:忍不住要挖一個有點...雨雲被SOOOO ......缺乏,說得客氣一點;-)

原來默認值確實具有用於按下的樣式,缺少的是設置它的邏輯。可能不是完全微不足道的,因爲邏輯(aka: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); 
    } 
} 
+0

我的情況,這是不可拖動的。 yay – oliholz 2011-05-04 14:34:20

+0

@oliholz拖動只是重新使用渲染器在按下列之外進行繪畫的一個示例;-)無論出於何種原因都可能發生。爲了讓它中途穩定,你需要在我編輯的答案中使用類似wrappingRenderer的東西 – kleopatra 2011-05-04 15:22:42