Java 如何灰显jtable中不可编辑的单元格?

Java 如何灰显jtable中不可编辑的单元格?,java,swing,jtable,Java,Swing,Jtable,我想将JTable中不可编辑的单元格设置为灰色。 我正在使用这样的TableCellRenderer: TableColumn column = table.getColumnModel().getColumn(0); column.setCellRenderer(new GrayableCheckboxCellRenderer()); public class GrayableCheckboxCellRenderer extends JCheckBox implements TableCel

我想将JTable中不可编辑的单元格设置为灰色。 我正在使用这样的TableCellRenderer:

TableColumn column = table.getColumnModel().getColumn(0);
column.setCellRenderer(new GrayableCheckboxCellRenderer());

public class GrayableCheckboxCellRenderer extends JCheckBox implements TableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int vRowIndex, int vColIndex) {           
            boolean editable = isEditable(vRowIndex, vColIndex);
        setBackground(editable ? UIManager.getColor("Label.background") : Color.LIGHT_GRAY);
        setSelected((Boolean) value);
                if (isSelected) {
                    // TODO: cell (and perhaps other cells) are selected, need to highlight it
                }
        return this;
    }
    // perfomance
    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
    public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
    public void revalidate() {}
    public void validate() {}
}
这是可行的,但有一件恼人的艺术品: 最初,“复选框”是“左排列”,当我按下鼠标左键时,它移动到“中心排列”,当我松开鼠标按钮时,它移回“左排列”


如何避免这种恼人的人工制品,并且可能有更好更简单的解决方案来解决我的问题?

TableCellEditor
中返回
GrayableCheckboxCellRenderer
的实例

附录:在美学上,您可能希望根据当前外观提供的颜色调整渲染器和编辑器的颜色,例如:

Color hilite = UIManager.getColor("Table.selectionBackground");

使用PreparedRender的最简单方法

import java.awt.*;
import java.util.Random;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;

public class Forum {

    private JFrame frame = new JFrame("Frame");
    private JPanel fatherCenter = new JPanel();
    private JScrollPane tableScroll = new JScrollPane();
    private myTableModel tableModel;
    private JTable dialogTable;
    private ListSelectionModel lsDialog;

    private void addComponentsToPane(Container pane) {
        tableModel = new myTableModel();
        dialogTable = new JTable(tableModel) {

            private static final long serialVersionUID = 1L;

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component comp = super.prepareRenderer(renderer, row, column);
                JComponent jc = (JComponent) comp;//for Custom JComponent
                if (!isRowSelected(row)) {
                    int modelRow = convertRowIndexToModel(row);
                    boolean type = (Boolean) getModel().getValueAt(modelRow, 2);
                    boolean type1 = (Boolean) getModel().getValueAt(modelRow, 3);
                    boolean type2 = (Boolean) getModel().isCellEditable(row, column);
                    comp.setForeground(Color.black);
                    if ((type) && (!type1)) {
                        comp.setBackground(Color.yellow);
                    } else if ((!type) && (type1)) {
                        comp.setBackground(Color.orange);
                    } else if ((!type) || (!type1)) {
                        comp.setBackground(Color.red);
                    //} else if ((!type2)) {
                        //comp.setForeground(Color.red);
                        //comp.setBackground(Color.magenta);
                    } else {
                        comp.setBackground(row % 2 == 0 ? getBackground() : getBackground().darker());
                    }
                    dialogTable.convertRowIndexToView(0);
                } else {
                    comp.setForeground(Color.blue);
                    comp.setBackground(Color.lightGray);
                }
                    if (!isCellEditable(row, column)) {
                    comp.setForeground(Color.red);
                    comp.setBackground(Color.magenta);
                }
                return comp;
            }
        };
        tableScroll = new JScrollPane(dialogTable, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        tableScroll.setBorder(null);
        dialogTable.getTableHeader().setReorderingAllowed(false);
        dialogTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        lsDialog = dialogTable.getSelectionModel();
        dialogTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
        dialogTable.setRowHeight(20);
        dialogTable.setRowMargin(2);
        fatherCenter = new JPanel();
        fatherCenter.setLayout(new BorderLayout(10, 10));
        fatherCenter.add(tableScroll, BorderLayout.CENTER);
        pane.add(fatherCenter);
    }

    private void addData() {
        Runnable doRun1 = new Runnable() {

            @Override
            public void run() {
                tableModel.resetTable();
                Vector<String> tbl = new Vector<String>();
                Vector<Object> tbl1 = new Vector<Object>();
                Random rnd = new Random();
                tbl.add("Integer");
                tbl.add("Double");
                tbl.add("Boolean");
                tbl.add("Boolean");
                tbl.add("String");
                tableModel.setColumnNames(tbl);
                for (int row = 0; row < 30; row++) {
                    tbl1 = null;
                    tbl1 = new Vector<Object>();
                    tbl1.addElement(row + 1);
                    tbl1.addElement(rnd.nextInt(25) + 3.14);
                    tbl1.addElement((row % 3 == 0) ? false : true);
                    tbl1.addElement((row % 5 == 0) ? false : true);
                    if (row % 7 == 0) {
                        tbl1.add(("Canc"));
                    } else if (row % 6 == 0) {
                        tbl1.add(("Del"));
                    } else {
                        tbl1.add(("New"));
                    }
                    tableModel.addRow(tbl1);
                }
                addTableListener();
            }
        };
        SwingUtilities.invokeLater(doRun1);
    }

    private void addTableListener() {
        tableModel.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent tme) {
                if (tme.getType() == TableModelEvent.UPDATE) {
                    System.out.println("Cell " + tme.getFirstRow() + ", "
                            + tme.getColumn() + " changed. The new value: "
                            + tableModel.getValueAt(tme.getFirstRow(),
                            tme.getColumn()));
                }
            }
        });
    }

    private void createAndShowGUI() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout(10, 10));
        addComponentsToPane(frame.getContentPane());
        addData();
        frame.setLocation(150, 150);
        frame.setPreferredSize(new Dimension(400, 646));
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Forum osFrame = new Forum();
    }

    public Forum() {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private class myTableModel extends AbstractTableModel {

        private static final long serialVersionUID = 1L;
        private Vector<Vector<Object>> data;
        private Vector<String> colNames;
        private boolean[] _columnsVisible = {true, true, true, true, true};

        myTableModel() {
            this.colNames = new Vector<String>();
            this.data = new Vector<Vector<Object>>();
        }

        myTableModel(Vector<String> colnames) {
            this.colNames = colnames;
            this.data = new Vector<Vector<Object>>();

        }

        public void resetTable() {
            this.colNames.removeAllElements();
            this.data.removeAllElements();

        }

        public void setColumnNames(Vector<String> colNames) {
            this.colNames = colNames;
            this.fireTableStructureChanged();
        }

        public void addRow(Vector<Object> data) {
            this.data.add(data);
            this.fireTableDataChanged();
            this.fireTableStructureChanged();
        }

        public void removeRowAt(int row) {
            this.data.removeElementAt(row);
            this.fireTableDataChanged();
        }

        @Override
        public int getColumnCount() {
            return this.colNames.size();
        }

        @Override
        public Class<?> getColumnClass(int colNum) {
            switch (colNum) {
                case 0:
                    return Integer.class;
                case 1:
                    return Double.class;
                case 2:
                    return Boolean.class;
                case 3:
                    return Boolean.class;
                default:
                    return String.class;
            }
        }

        @Override
        public boolean isCellEditable(int row, int colNum) {
            switch (colNum) {
                case 2:
                    return false;
                default:
                    return true;
            }
        }

        @Override
        public String getColumnName(int colNum) {
            return this.colNames.get(colNum);
        }

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

        @Override
        public Object getValueAt(int row, int col) {
            Vector<Object> value = this.data.get(row);
            return value.get(col);
        }

        @Override
        public void setValueAt(Object newVal, int row, int col) {
            Vector<Object> aRow = data.elementAt(row);
            aRow.remove(col);
            aRow.insertElementAt(newVal, col);
            fireTableCellUpdated(row, col);
        }

        public void setColumnVisible(int index, boolean visible) {
            this._columnsVisible[index] = visible;
            this.fireTableStructureChanged();
        }
    }
}
import java.awt.*;
导入java.util.Random;
导入java.util.Vector;
导入javax.swing.*;
导入javax.swing.event.TableModelEvent;
导入javax.swing.event.TableModelListener;
导入javax.swing.table.AbstractTableModel;
导入javax.swing.table.TableCellRenderer;
公开课论坛{
私有JFrame=新JFrame(“帧”);
private JPanel fatherCenter=新JPanel();
private JScrollPane tableScroll=new JScrollPane();
私有myTableModel tableModel;
专用JTable对话表;
私有列表选择模型对话框;
专用void addComponentsToPane(容器窗格){
tableModel=新的myTableModel();
dialogTable=新的JTable(tableModel){
私有静态最终长serialVersionUID=1L;
@凌驾
公共组件预渲染器(TableCellRenderer渲染器,int行,int列){
组件组件=super.prepareRenderer(渲染器、行、列);
JComponent jc=(JComponent)comp;//用于自定义JComponent
如果(!isRowSelected(世界其他地区)){
int modelRow=convertRowIndexToModel(行);
布尔类型=(布尔)getModel().getValueAt(modelRow,2);
布尔类型1=(布尔)getModel().getValueAt(modelRow,3);
布尔类型2=(布尔)getModel().isCellEditable(行、列);
组件设置前景(颜色为黑色);
如果((类型)和(!类型1)){
公司背景(颜色为黄色);
}如果((!type)和&(type1)){
公司背景(橙色);
}如果((!type)|(!type1)){
公司背景(颜色为红色);
//}如果((!类型2)){
//组件设置前景(颜色为红色);
//公司背景(颜色为洋红色);
}否则{
公司背景(第%2行==0?getBackground():getBackground().darker());
}
dialogTable.convertRowIndexToView(0);
}否则{
组件设置前景(蓝色);
公司背景(浅灰色);
}
如果(!isCellEditable(行、列)){
组件设置前景(颜色为红色);
公司背景(颜色为洋红色);
}
返回补偿;
}
};
tableScroll=新的JScrollPane(dialogTable,ScrollPaneConstants.VERTICAL\u SCROLLBAR\u根据需要,
ScrollPaneConstants.水平滚动条(根据需要);
tableScroll.setboorder(空);
dialogTable.getTableHeader().setReorderingAllowed(false);
dialogTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
lsDialog=dialogTable.getSelectionModel();
dialogTable.putClientProperty(“terminateEditOnFocusLost”,Boolean.TRUE);
dialogTable.setRowHeight(20);
dialogTable.setRowMargin(2);
父中心=新的JPanel();
父中心布局(新边界布局(10,10));
添加(tableScroll,BorderLayout.CENTER);
窗格。添加(父中心);
}
私有void addData(){
Runnable doRun1=新的Runnable(){
@凌驾
公开募捐{
tableModel.resetable();
向量tbl=新向量();
向量tbl1=新向量();
随机rnd=新随机();
tbl.添加(“整数”);
tbl.添加(“双”);
tbl.添加(“布尔”);
tbl.添加(“布尔”);
tbl.添加(“字符串”);
tableModel.setColumnNames(tbl);
对于(int行=0;行<30;行++){
tbl1=null;
tbl1=新向量();
tbl1.附录(第+1行);
tbl1.补充件(rnd.nextInt(25)+3.14);
tbl1.addElement((第%3行==0)?false:true);
tbl1.addElement((行%5==0)?false:true);
如果(第%7行==0){
tbl1.添加((“Canc”);
}else if(第%6行==0){
tbl1.添加((“删除”);
}否则{
tbl1.添加((“新”);
}
tableModel.addRow(tbl1);
}
addTableListener();
}
};
SwingUtilities.invokeLater(doRun1);
}
私有void addTableListener(){
tableModel.addTableModelListener(新的TableModelListener(){
@凌驾
公共作废表已更改(TableModelEvent tme){
if(tme.getType()==TableModelEvent.UPDATE){
System.out.println(“单元格”+tme.getFirstRow()+”,“
+tme.getColumn()+“已更改。新值:”
+tableModel.getValueAt(tme.getFirstRow(),
tme.getColumn());
}
}
});
}
私有void createAndShowGUI(){
frame.setDef
 setHorizontalAlignment(SwingConstants.CENTER);