JTable单元格渲染器跳过布尔列

时间:2013-02-26 04:05:46

标签: java swing jtable tablemodel tablecellrenderer

以下是我JTable的照片。我的问题是第4列中没有每隔一行的蓝色背景。我的表格模型和单元格渲染器也在下面。

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

细胞渲染器:

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

2 个答案:

答案 0 :(得分: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;
        }
    }
}

答案 1 :(得分:3)

请参阅Table Row Rendering,了解每次拥有包含不同数据的列时不需要继续创建自定义渲染器的解决方案。

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