【问题标题】:JTable - How to set text mask for cells in a specific column?JTable - 如何为特定列中的单元格设置文本掩码?
【发布时间】:2014-05-28 23:12:40
【问题描述】:

我有一个 JTable,用户可以添加、编辑和删除单元格(除了 JTable 之外,所有这些都不需要额外的组件)。我想为特定列中的所有单元格设置一个自定义掩码(类似于 JFormattedTextField)。

示例: JTable 有 2 列:时间和描述。 Time 列中的所有单元格都有 HH:MM 掩码,Description 列中的单元格没有掩码。

我怎样才能做到这一点?

谢谢。

【问题讨论】:

    标签: java swing jtable cell mask


    【解决方案1】:

    here 有一个关于验证 IP 地址的 JTable 字段的问题。在接受的答案中,SO User (peeskillet) 展示了如何使用正则表达式作为“掩码”来验证 JTable 的输入。如果您可以使正则表达式适应您的面具并研究他慷慨贡献的代码,那应该会让您朝着正确的方向前进。

    祝你好运!

    编辑

    我指的代码:

    import javax.swing.DefaultCellEditor;
    import javax.swing.InputVerifier;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellEditor;
    
    public class TableVerifyInput {
    
    //The 'mask' as you say for the fields
    private static final String IP_REGEX = "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$";
    
    public TableVerifyInput() {
        final InputVerifier verifier = getInputVerifier();
        final DefaultCellEditor editor = getTableCellEditor(verifier);
    
        String[] cols = {"IP address", "Column 2"};
        Object[][] data = {{null, null}, {null, null}};
        DefaultTableModel model = new DefaultTableModel(data, cols);
    
        JTable table = new JTable(model) {
            public TableCellEditor getCellEditor(int row, int column) {
                int modelColumn = convertColumnIndexToModel(column);
    
                if (modelColumn == 0) {
                    return editor;
                } else {
                    return super.getCellEditor(row, column);
                }
            }
        };
    
        JFrame frame = new JFrame("Table Cell Verify");
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    private InputVerifier getInputVerifier() {
        InputVerifier verifier = new InputVerifier() {
    
            @Override
            public boolean verify(JComponent input) {
                JTextField field = (JTextField) input;
                String text = field.getText();
                return text.matches(IP_REGEX) || text.isEmpty();
            }
    
            @Override
            public boolean shouldYieldFocus(JComponent input) {
                boolean valid = verify(input);
                if (!valid) {
                    JOptionPane.showMessageDialog(null, "Invalid IP address");
                }
                return valid;
            }
    
        };
        return verifier;
    }
    
    private DefaultCellEditor getTableCellEditor(final InputVerifier verifier) {
        DefaultCellEditor editor = new DefaultCellEditor(new JTextField()) {
            {
                getComponent().setInputVerifier(verifier);
            }
    
            @Override
            public boolean stopCellEditing() {
                if (!verifier.shouldYieldFocus(getComponent())) {
                    return false;
                }
                return super.stopCellEditing();
            }
    
            @Override
            public JTextField getComponent() {
                return (JTextField) super.getComponent();
            }
    
        };
        return editor;
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TableVerifyInput();
            }
        });
    }
    }
    

    再次感谢 SO User peeskillet 的贡献。

    【讨论】:

    • 如果我正确理解了他的代码,它会验证用户是否以指定的正则表达式格式输入了文本,如果错误则给出错误。但我真正想要的是一个编辑掩码,因为我不想用错误消息来打扰用户。
    • 编辑掩码具体是什么意思?它只允许你输入某些字符或类似的东西?
    • 是的,特定格式的特定字符。示例:HH:MM(时间)、mm/dd/yyyy(日期)。换句话说,我想要一个 JFormattedTextField 作为每个单元格的编辑器。用户必须不可能在单元格内以任何错误格式输入任何错误字符。
    • 我猜想这样做的方法是获取您在表中选择的 textField,然后使用键侦听器/适配器来监视该字段的输入,只允许您需要的内容。
    • 是的,这可能是一个解决方案,但我试图避免对 JFormattedTextField 中已经存在的所有输入逻辑进行编程。我认为 Swing 可能有办法覆盖默认文本容器,但很难找到它。
    【解决方案2】:

    好的,看来我找到了一个很好的解决方案。 在这个线程上:Changing JTable Cell's Font while editing it解决答案上有这个代码:

    DefaultCellEditor dce = new DefaultCellEditor( textField );
    myTable.getColumnModel().getColumn(1).setCellEditor(dce);
    

    然后我适应了使用 MaskFormatter:

    table.setModel(new DefaultTableModel(new String[][] { } , new String[] {"Time", "Description"} ) );
    JFormattedTextField ftext = new JFormattedTextField();
    MaskFormatter mask;
    try {
        mask = new MaskFormatter("##:##");
        mask.install(ftext);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    table.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(ftext));
    

    这基本上就是我想要的。感谢您的回答。

    【讨论】:

    • 我一直在尝试实现相同的目标,但是当我尝试您的实现时,只有我在列中单击的第一个单元格会受到掩码的影响。你有同样的问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 2014-09-24
    • 1970-01-01
    • 2011-09-17
    • 2014-06-06
    • 2012-02-21
    相关资源
    最近更新 更多