【问题标题】:JTable column stops working after a certain column numberJTable 列在某个列号后停止工作
【发布时间】:2021-07-04 04:00:11
【问题描述】:

我的印象是,在第 4 列 [索引 3] 之后,我的 jtable 的其余部分确实会对格式化或数据验证做出反应。

正如您在这张图片中看到的,颜色在第 4 列之后停止:

声明:

private final JTable table = new JTable(new TableModelDB("all"));
private final JScrollPane scrollPane = new JScrollPane(table);

这是我所有与 jtable 相关的代码:

    JFormattedTextField ftext = new JFormattedTextField();
    try {
        MaskFormatter mask = new MaskFormatter("####-##-##");
        mask.setPlaceholderCharacter('_');
        mask.setAllowsInvalid(false);
        mask.install(ftext);
    } catch (ParseException e) {
        System.out.println("error: " + e);
    }
    table.setDefaultEditor(Object.class, new MyCellEditor());
    table.getColumnModel().getColumn(3).setCellEditor(new MyCellEditor(ftext));
    table.setRowHeight(30);
    table.setFillsViewportHeight(true);
    table.getModel().addTableModelListener(this);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setDefaultRenderer(Object.class, cr);
    table.setAutoCreateColumnsFromModel(false);
    resizeColumnWidth();
    table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 20));
    table.setFont(new Font("Arial", Font.PLAIN, 20));

使用 CellEditor 进行数据验证(验证工作正常,直到 column=4,使用 println() 我发现 stopCellEditing 方法从未被调用过):

    private boolean editValidation(String data) {
    System.out.println("editValidation");
    int column = table.getSelectedColumn();

    if (data == null || data.trim().isEmpty()) {
        System.out.println("c0");
        JOptionPane.showMessageDialog(null, "Cannot leave a field blank");
        return false;
    }

    if (column == 1 && data.length() > 255) {
        JOptionPane.showMessageDialog(null, "The Income name is too long (Max 255 characters)");
        return false;
    }
    if (column == 2 && data.length() > 255) {
        JOptionPane.showMessageDialog(null, "The Category name is too long (Max 255 characters)");
        return false;
    }
    if (column == 3) {
        if (data.contains("_")) {
            JOptionPane.showMessageDialog(null, "Invalid date");
            return false;
        } else {
            try {
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                df.setLenient(false);
                df.parse(data);
            } catch (ParseException e) {
                JOptionPane.showMessageDialog(null, "Invalid date");
                return false;
            }
        }
    }
    if (column == 4) {
        System.out.println("c4");
        if (!data.matches("^[0-9]+")) {
            JOptionPane.showMessageDialog(null, "Amount contains non-number elements");
            return false;
        } else if (Integer.parseInt(data) <= 0) {
            JOptionPane.showMessageDialog(null, "Income cannot be less than or equal to zero");
            return false;
        }
    }

    return true;
}

public class MyCellEditor extends DefaultCellEditor {

    public MyCellEditor() {
        super(new JTextField());
    }

    MyCellEditor(JFormattedTextField ftext) {
        super(ftext);
    }

    @Override
    public boolean stopCellEditing() {
        System.out.println("stopCellEditing");
        final JTextField field = (JTextField) getComponent();
        if (editValidation(field.getText())) {
            System.out.println("case t");
            field.setBackground(Color.WHITE);
            return super.stopCellEditing();
        }
        System.out.println("case f");
        Toolkit.getDefaultToolkit().beep();
        field.setBackground(Color.RED);
        return false;
    }
}

单元格渲染器(即使我将所有内容都设为浅灰色,但未应用索引 3 之后的列):

public class CustomCellRenderer extends DefaultTableCellRenderer {

    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int col) {
        Component c = super.getTableCellRendererComponent(table, value,
                isSelected, hasFocus, row, col);

        c.setBackground(Color.LIGHT_GRAY);
//        if (col == 0) {
//            c.setBackground(Color.LIGHT_GRAY);
//        } else {
//            c.setBackground(Color.WHITE);
//        }
        return c;
    }
}

表模型:

public final class TableModelDB extends AbstractTableModel {

    private final WorkingClass wc = new WorkingClass();
    private final int startRows = 1;

    private final String[] columnNames = {"Income ID", "Income Name", "Category", "Entry Date", "Amount", "Delete"};
    private Object[][] data;

    public TableModelDB(String type) {
        try {
            ResultSet rs = wc.searchIncomeRS(type);
            int rowCount = wc.rowCount();
            int count = 0, amount, total = 0;
            Object[][] temp = new Object[rowCount + startRows][6];
            while (rs.next()) {
                temp[count][0] = rs.getString("ID");
                temp[count][1] = rs.getString("EntryName");
                temp[count][2] = rs.getString("Category");
                Date date = new Date(rs.getDate("EntryDate").getTime());
                temp[count][3] = wc.strDate(date);
                amount = rs.getInt("Amount");
                total += amount;
                temp[count][4] = amount;
                temp[count++][5] = false;
            }
            temp[count][4] = total;
            data = temp;
        } catch (SQLException ex) {
            System.out.println("error: " + ex);
        }
    }

    public int getColumnCount() {
        return columnNames.length;
    }

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

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

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

    public Class getColumnClass(int col) {
        for (int row = 0; row < getRowCount(); row++) {
            Object o = getValueAt(row, col);
            if (o != null) {
                return o.getClass();
            }
        }
        return Object.class;
    }

    public boolean isCellEditable(int row, int col) {
        return !(data[row][col] == null || data[row][0] == null || col == 0);
    }

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

}

如果有好心人能告诉我为什么专栏没有回应,将不胜感激,也欢迎任何其他错误或批评

非常感谢:)

【问题讨论】:

    标签: java swing jtable tablecellrenderer tablemodel


    【解决方案1】:

    在创建了几个测试类后,我意识到只有带有字符串的列才能获得格式和 DV,所以我将其更改为:

            table.setDefaultEditor(String.class, new MyCellEditor());//DV
            table.setDefaultEditor(Integer.class, new MyCellEditor());//DV
            table.setDefaultEditor(Boolean.class, new MyCellEditor());//DV
            table.getColumnModel().getColumn(3).setCellEditor(new MyCellEditor(ftext));//Mask
            table.setDefaultRenderer(String.class, new CustomCellRenderer());//color
            table.setDefaultRenderer(Integer.class, new CustomCellRenderer());//color
            table.setDefaultRenderer(Boolean.class, new CustomCellRenderer());//color
    

    现在一切正常

    【讨论】:

    • 要更改表格中所有行的背景,无需自定义渲染器。只需使用table.setBackground( Color.LIGHT_GRAY)。您还可以查看Table Row Rendering 了解更多创建行数据的渲染。
    • @camickr 非常感谢您的建议。我可以再问你一个问题吗?我不知道在哪里以及如何检查该人是否没有更改表中的数据。即他们只是单击了数据而不更改(我有一个确认对话框,会要求您确认是否要更改数据,即使数据保持不变也会弹出)。
    • 嗯,我不知道您是在询问更改单个单元格中的数据,还是单行中的多列,还是多行。无论如何,答案是您需要管理它。在进行比较之前/之后没有数据副本。查看Table Cell Listener 可能会有所帮助。使用此类,您可以在每次进行编辑时设置“更改”变量。然后你的弹出对话框需要在适当的时候检查这个变量。如果您需要更多帮助,请使用正确的 minimal reproducible example 提出单独的问题。
    • @camickr 非常感谢你,我会试试看 :)
    猜你喜欢
    • 2013-08-02
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 2022-10-20
    • 2016-09-27
    • 2021-09-08
    • 2017-03-20
    • 2016-10-14
    相关资源
    最近更新 更多