2013-02-26 2 views
2

Ниже приведено изображение моего JTable. Моя проблема заключается в том, что синий фон в каждой другой строке отсутствует в четвертом столбце. Моя таблица и средство отображения ячеек также находятся ниже.JTable cell renderer skips Булевая колонка

enter image description here

Таблица Модель:

public class MyTableModel extends DefaultTableModel { 
    public int getColumnCount() { 
     return columnNames.length; 
    } 

    public String getColumnName(int column) { 
     return columnNames[column]; 
    } 

    public int getRowCount() { 
     return data.length; 
    } 

    public Object getValueAt(int row, int column) { 
     return data[row][column]; 
    } 

    public Class getColumnClass(int column) { 
     return (getValueAt(0, column).getClass()); 
    } 

    public void setValueAt(Object value, int row, int column) { 
     data[row][column] = value; 
    } 

    public boolean isCellEditable(int row, int column) { 
     return (column == 3); 
    } 
    } 

Cell Renderer:

private class CalendarRenderer extends DefaultTableCellRenderer { 
    private static final long serialVersionUID = 1L; 

    public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) { 
     super.getTableCellRendererComponent(table, value, selected, focused, row, column); 

     setBackground(new Color(0xFFFFFF)); 

     if (row % 2 == 1) { 
     setBackground(new Color(0xE8F2FE)); //light blue 
     } 

     setBorder(null); 
     setForeground(Color.black); 
     return this; 
    } 
    } 
+0

Редактор по умолчанию для 'Boolean' является редактором ячеек JCheckBox', это работает корректно. – MadProgrammer

+0

Когда Java не работает «правильно»? Мне интересно, как я могу получить четвертую колонку, чтобы иметь синий фон. –

+1

Вам понадобится предоставить свой собственный 'Boolean'' TableCellRenderer' – MadProgrammer

ответ

8

"по умолчанию" визуализации ячейки для Boolean является флажок. Если вы хотите изменить способ рендеринга этой ячейки, вам придется предоставить свой собственный TableCellRenderer, который реализует вашу собственную логику.

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.border.Border; 
import javax.swing.border.EmptyBorder; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.TableCellRenderer; 

public class TestTableCellRenderer { 

    public static void main(String[] args) { 
     new TestTableCellRenderer(); 
    } 

    public TestTableCellRenderer() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JTable table = new JTable(); 
       table.setModel(new TableModel()); 
       table.setDefaultRenderer(Boolean.class, new BooleanCellRenderer()); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new JScrollPane(table)); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TableModel extends AbstractTableModel { 

     private List<Boolean> values = new ArrayList<>(25); 

     public TableModel() { 
      for (int index = 0; index < 25; index++) { 
       values.add((((int) Math.round(Math.random() * 1)) == 0 ? false : true)); 
      } 
     } 

     @Override 
     public int getRowCount() { 
      return values.size(); 
     } 

     @Override 
     public int getColumnCount() { 
      return 1; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      return values.get(rowIndex); 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      return Boolean.class; 
     } 
    } 

    public static class BooleanCellRenderer extends JCheckBox implements TableCellRenderer { 

     private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); 

     public BooleanCellRenderer() { 
      setLayout(new GridBagLayout()); 
      setMargin(new Insets(0, 0, 0, 0)); 
      setHorizontalAlignment(JLabel.CENTER); 
     } 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
      if (value instanceof Boolean) { 
       setSelected((Boolean) value); 
      } 
      if (!isSelected) { 
       setBackground(new Color(0xFFFFFF)); 
       if (row % 2 == 1) { 
        setBackground(new Color(0xE8F2FE)); //light blue 
       } 
       setForeground(Color.black); 
      } else { 
       setForeground(table.getSelectionForeground()); 
       setBackground(table.getSelectionBackground()); 
      } 
      if (hasFocus) { 
       setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); 
      } else { 
       setBorder(noFocusBorder); 
      } 
      return this; 
     } 
    } 
} 
+0

Отлично, спасибо! –

+0

Это не работает для меня ... Я все равно получаю непеременные цвета фона, и когда я выбираю флажок, он обманывает все поля в столбце. Любая идея, если это может быть недействительным в новых версиях swing? –

+0

@AdamHughes Ну, так как пример кода демонстрирует работоспособное решение, все, что я предлагаю, было бы догадкой. Май, рассмотрите вопрос с кодом, который вы используете – MadProgrammer

3

См Table Row Rendering решение, которое не требует, чтобы создавать пользовательские Renderers каждый раз, когда у вас есть столбцы с различными данными.

JTable table = new JTable(model) 
{ 
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) 
    { 
     Component c = super.prepareRenderer(renderer, row, column); 

     // Alternate row color 

     if (!isRowSelected(row)) 
      c.setBackground(row % 2 == 0 ? getBackground() : Color.LIGHT_GRAY); 

     return c; 
    } 
}; 
+0

Очень приятное решение !!!!! – Andreas