2

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

在此处输入图像描述

表型号:

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

2 回答 2

8

“默认”单元格渲染器Boolean是一个复选框。如果你想改变这个单元格的渲染方式,你将不得不提供你自己的TableCellRenderer来实现你自己的逻辑。

在此处输入图像描述

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;
        }
    }
}
于 2013-02-26T04:21:40.523 回答
3

See Table Row Rendering for a solution that doesn't require you to keep creating custom renderers every time you have columns with different data.

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;
    }
};
于 2013-02-26T05:07:11.660 回答