【问题标题】:How to gray-out non-editable cell in jtable?如何使jtable中的不可编辑单元格变灰?
【发布时间】:2011-10-02 19:19:11
【问题描述】:

我想将 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() {}
}

这可行,但有一个令人讨厌的伪影: 最初“复选框”是“左排列”,当我按下鼠标左键时,它会移动到“居中排列”,当我松开鼠标按钮时,它会回到“左排列”。

如何避免这种烦人的伪影,并且可能有更好更简单的解决方案来解决我的问题?

【问题讨论】:

    标签: java swing jtable


    【解决方案1】:

    TableCellEditor 中返回GrayableCheckboxCellRenderer 的实例。

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

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

    【讨论】:

    • 有一个相关的例子here
    • 示例作品。我们在那里使用自定义 CellRenderer。当用户选择表中的某些行时,它应该突出显示(在所有列中)。但它在所有列中突出显示,除了那些使用自定义 CellRenderer 的列,这仍然非常难看......
    • 您可能想要更改 UIManager 默认值;以上。
    【解决方案2】:

    使用preparedRenderer的最简单方法

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

    【讨论】:

    • +1 很高兴知道;我认为匹配的编辑器是唯一的方法。
    【解决方案3】:

    只需在 'getTableCellRendererComponent()' 方法中显式设置对齐方式即可解决问题。在从方法返回之前添加以下行。

     setHorizontalAlignment(SwingConstants.CENTER);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 2013-03-06
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      相关资源
      最近更新 更多