2012-02-20 2 views
4

У меня есть флажок в заголовке JTable, я использую Nimbus L & F и настраиваю фон заголовка, но фон флажка занимает серый серый цвет по умолчанию, а не настройку в качестве другого столбца делать.Флажок в заголовке JTable визуализируется по-разному с Nimbus L & F

После класс CheckboxRenderer

public class CheckBoxHeader extends JCheckBox implements TableCellRenderer{ 

public CheckBoxHeader(ItemListener itemListener) {  
    addItemListener(itemListener); 
    setHorizontalAlignment(SwingConstants.CENTER); 
    setOpaque(true);   
} 

public Component getTableCellRendererComponent(JTable table, Object value, 
     boolean isSelected, boolean hasFocus, int row, int column) {      
     JTableHeader header = table.getTableHeader();   
     Color bg = header.getBackground(); 
     setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue()));  
    return this; 
} 

И в таблице

TableColumn tc = getColumnModel().getColumn(0); 
tc.setCellEditor(getDefaultEditor(Boolean.class)); 
tc.setCellRenderer(getDefaultRenderer(Boolean.class));  
((JComponent)getDefaultRenderer(Boolean.class)).setOpaque(true);   
tc.setHeaderRenderer(new CheckBoxHeader()); 

AFAIK, чтобы получить надлежащее предоставление заголовка он должен сделать с DefaultTableCellRenderer, но я не получаю путь к нему. Какие-либо предложения?

ответ

4

Я не уверен, если он работает на всех ЛНФ (тестирование только Windows 7, Java 1.7.0_03):

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.table.*; 
public class NimbusHeaderCheckBox { 
    public JComponent makeUI() { 
    Object[] columnNames = {Status.INDETERMINATE, "Integer", "String"}; 
    Object[][] data = {{true, 1, "b"}, {false, 9, "a"}, {true, 5, "c"}}; 
    DefaultTableModel model = new DefaultTableModel(data, columnNames) { 
     @Override public Class<?> getColumnClass(int column) { 
     return getValueAt(0, column).getClass(); 
     } 
    }; 
    JTable table = new JTable(model); 
    model.addTableModelListener(new HeaderCheckBoxHandler(table)); 

    TableCellRenderer r = new HeaderRenderer(table.getTableHeader(), 0); 
    table.getColumnModel().getColumn(0).setHeaderRenderer(r); 
    //<ins> 
    TableCellRenderer leftAlign = new LeftAlignHeaderRenderer(); 
    table.getColumnModel().getColumn(1).setHeaderRenderer(leftAlign); 
    table.getColumnModel().getColumn(2).setHeaderRenderer(leftAlign); 
    //</ins> 
    table.getTableHeader().setReorderingAllowed(false); 
    return new JScrollPane(table); 
    } 
    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { createAndShowGUI(); } 
    }); 
    } 
    public static void createAndShowGUI() { 
    try { 
     //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) 
     if ("Nimbus".equals(laf.getName())) UIManager.setLookAndFeel(laf.getClassName()); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    frame.getContentPane().add(new NimbusHeaderCheckBox().makeUI()); 
    frame.setSize(320, 240); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
    } 
} 
class HeaderRenderer extends JCheckBox implements TableCellRenderer { 
    public HeaderRenderer(JTableHeader header, final int targetColumnIndex) { 
    super((String)null); 
    setOpaque(false); 
    setFont(header.getFont()); 
    header.addMouseListener(new MouseAdapter() { 
     @Override public void mouseClicked(MouseEvent e) { 
     JTableHeader header = (JTableHeader)e.getSource(); 
     JTable table = header.getTable(); 
     TableColumnModel columnModel = table.getColumnModel(); 
     int vci = columnModel.getColumnIndexAtX(e.getX()); 
     int mci = table.convertColumnIndexToModel(vci); 
     if(mci == targetColumnIndex) { 
      TableColumn column = columnModel.getColumn(vci); 
      Object v = column.getHeaderValue(); 
      boolean b = Status.DESELECTED.equals(v)?true:false; 
      TableModel m = table.getModel(); 
      for(int i=0; i<m.getRowCount(); i++) m.setValueAt(b, i, mci); 
      column.setHeaderValue(b?Status.SELECTED:Status.DESELECTED); 
     } 
     } 
    }); 
    } 
    @Override public Component getTableCellRendererComponent(
     JTable tbl, Object val, boolean isS, boolean hasF, int row, int col) { 
    if(val instanceof Status) { 
     switch((Status)val) { 
     case SELECTED: 
     setSelected(true); setEnabled(true); break; 
     case DESELECTED: 
     setSelected(false); setEnabled(true); break; 
     case INDETERMINATE: 
     setSelected(true); setEnabled(false); break; 
     } 
    } else { 
     setSelected(true); setEnabled(false); 
    } 
    TableCellRenderer r = tbl.getTableHeader().getDefaultRenderer(); 
    JLabel l=(JLabel)r.getTableCellRendererComponent(tbl, null, isS, hasF, row, col); 

    l.setIcon(new CheckBoxIcon(this)); 
    l.setText(null); //XXX Nimbus LnF ??? 
    ////This block has no effect at all as all the columns are center aligned 
    ////(pointed out by rcnpl) 
    //if(tbl.convertColumnIndexToModel(col)==0) { 
    // l.setHorizontalAlignment(SwingConstants.CENTER); 
    //} else { 
    // l.setHorizontalAlignment(SwingConstants.LEFT); 
    //} 
    //<ins> 
    l.setHorizontalAlignment(SwingConstants.CENTER); 
    //</ins> 
    return l; 
    } 
} 
//<ins> 
class LeftAlignHeaderRenderer implements TableCellRenderer { 
    @Override public Component getTableCellRendererComponent(
    JTable t, Object v, boolean isS, boolean hasF, int row, int col) { 
    TableCellRenderer r = t.getTableHeader().getDefaultRenderer(); 
    JLabel l=(JLabel)r.getTableCellRendererComponent(t, v, isS, hasF, row, col); 
    l.setHorizontalAlignment(SwingConstants.LEFT); 
    return l; 
    } 
} 
//</ins> 
enum Status { SELECTED, DESELECTED, INDETERMINATE } 
class CheckBoxIcon implements Icon { 
    private final JCheckBox check; 
    public CheckBoxIcon(JCheckBox check) { 
    this.check = check; 
    } 
    @Override public int getIconWidth() { 
    return check.getPreferredSize().width; 
    } 
    @Override public int getIconHeight() { 
    return check.getPreferredSize().height; 
    } 
    @Override public void paintIcon(Component c, Graphics g, int x, int y) { 
    SwingUtilities.paintComponent(
     g, check, (Container)c, x, y, getIconWidth(), getIconHeight()); 
    } 
} 
class HeaderCheckBoxHandler implements TableModelListener { 
    private final JTable table; 
    public HeaderCheckBoxHandler(JTable table) { 
    this.table = table; 
    } 
    @Override public void tableChanged(TableModelEvent e) { 
    if(e.getType()==TableModelEvent.UPDATE && e.getColumn()==0) { 
     int mci = 0; 
     int vci = table.convertColumnIndexToView(mci); 
     TableColumn column = table.getColumnModel().getColumn(vci); 
     Object title = column.getHeaderValue(); 
     if(!Status.INDETERMINATE.equals(title)) { 
     column.setHeaderValue(Status.INDETERMINATE); 
     } else { 
     int selected = 0, deselected = 0; 
     TableModel m = table.getModel(); 
     for(int i=0; i<m.getRowCount(); i++) { 
      if(Boolean.TRUE.equals(m.getValueAt(i, mci))) { 
      selected++; 
      } else { 
      deselected++; 
      } 
     } 
     if(selected==0) { 
      column.setHeaderValue(Status.DESELECTED); 
     } else if(deselected==0) { 
      column.setHeaderValue(Status.SELECTED); 
     } else { 
      return; 
     } 
     } 
     table.getTableHeader().repaint(); 
    } 
    } 
} 
+0

Благодаря @aterai. Приведенный вами пример работал. Ну, я сначала попробовал ваш пример, который отлично работал. А также в моем источнике я добавил CheckBoxIcon и сделал необходимые изменения в методе getTableCellRendererComponent, который отлично работал. Поскольку я только реализую его для Nimbus, поэтому я не пробовал с другими L & F. Cheers – rcnpl

+0

Hi @aterai Кажется, у вас есть одна проблема с предоставленным вами ответом. 'if (tbl.convertColumnIndexToModel (col) == 0) { l.setHorizontalAlignment (SwingConstants.CENTER); } else { l.setHorizontalAlignment (SwingConstants.LEFT); } ' Этот блок не имеет никакого эффекта, поскольку все столбцы выровнены по центру. – rcnpl

+0

Спасибо @rcnpl, что вы правы. Мне нужно будет удалить блоки кода ... – aterai

Смежные вопросы