java - 允许我只输入单个数字的JTable单元格/列

use*_*568 3 java swing jtable tablecelleditor

java - 我想要一个JTable单元格/列,只允许我输入一位数字(如1到9).我怎样才能做到这一点?

我试过这个,但我按下的数字在单元格中出现了两次.

table.addKeyListener(new KeyAdapter() {         
        public void keyPressed(KeyEvent e) {
            System.out.println("pressed..."+e.getKeyChar());
            char key = e.getKeyChar();
            int selectedColumn = table.getSelectedColumn();
            int selectedRow = table.getSelectedRow();
            if(table.getValueAt(selectedRow, selectedColumn) == null)
            table.setValueAt(key, selectedRow, selectedColumn);
        }
   });
Run Code Online (Sandbox Code Playgroud)

Pau*_*tha 5

不要使用KeyListener.你可以做的,而不是为使用JTextFieldTableCellEditor,只是添加DocumentFilterJTextField只允许数字.

这是一个运行的例子

import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellEditor;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;

public class JTableNumberColumn {

    public JTableNumberColumn() {
        JFrame frame = new JFrame();
        JTextField field = createTextField();
        frame.add(new JScrollPane(createTable(field)));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JTextField createTextField() {
        JTextField field = new JTextField();
        ((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
            @Override
            public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
                    throws BadLocationException {
                fb.insertString(off, str.replaceAll("\\D++", ""), attr);  // remove non-digits
            }

            @Override
            public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
                    throws BadLocationException {
                fb.replace(off, len, str.replaceAll("\\D++", ""), attr);  // remove non-digits
            }
        });
        return field;
    }

    private JTable createTable(final JTextField field) {
        String[] cols = {"Only Numbers", "Col 2", "Col 3"};
        String[][] data = {{null, null, null}, {null, null, null}, {null, null, null}};
        final TableCellEditor editor = new DefaultCellEditor(field);
        JTable table = new JTable(data, cols) {
            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                int modelColumn = convertColumnIndexToModel(column);

                if (modelColumn == 0) {
                    return editor;
                } else {
                    return super.getCellEditor(row, column);
                }
            }
        };
        return table;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JTableNumberColumn();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑1

我可能误读了你的问题.如果您只想允许一个号码.然后你可以使用JFormattedTextFielda MaskFormatter作为TableCellEditor.这是一个例子

import javax.swing.DefaultCellEditor;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellEditor;
import javax.swing.text.MaskFormatter;

public class JTableNumberColumn {

    public JTableNumberColumn() {
        JFrame frame = new JFrame();
        JFormattedTextField field = createFormattedTextField();
        frame.add(new JScrollPane(createTable(field)));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }


    private JFormattedTextField createFormattedTextField() {
        JFormattedTextField field = new JFormattedTextField(createFormatter("#"));
        return field;
    }

    protected MaskFormatter createFormatter(String s) {
        MaskFormatter formatter = null;
        try {
            formatter = new MaskFormatter(s);
        } catch (java.text.ParseException exc) {
            System.err.println("formatter is bad: " + exc.getMessage());
            System.exit(-1);
        }
        return formatter;
    }

    private JTable createTable(final JFormattedTextField field) {
        String[] cols = {"Only Numbers", "Col 2", "Col 3"};
        String[][] data = {{null, null, null}, {null, null, null}, {null, null, null}};
        final TableCellEditor editor = new DefaultCellEditor(field);
        JTable table = new JTable(data, cols) {
            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                int modelColumn = convertColumnIndexToModel(column);

                if (modelColumn == 0) {
                    return editor;
                } else {
                    return super.getCellEditor(row, column);
                }
            }
        };
        return table;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JTableNumberColumn();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑2

它引起了我的注意,我也忽略了你只想要1-9而不是0-9的事实.在这种情况下,我只想坚持的第一个选项JTextFieldDocumentFilter,但在过滤器,检查输入的长度,改变正则表达式只允许1-9.

这是一个例子

import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellEditor;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;

public class JTableNumberColumn {

    public JTableNumberColumn() {
        JFrame frame = new JFrame();
        JTextField field1 = createTextField();
        frame.add(new JScrollPane(createTable(field1)));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JTextField createTextField() {
        final JTextField field = new JTextField();
        ((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
            @Override
            public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
                    throws BadLocationException {
                int length = field.getDocument().getLength();
                if (length + str.length() <= 1) {
                    fb.insertString(off, str.replaceAll("[^1-9]", ""), attr);  // remove non-digits
                }
            }

            @Override
            public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
                    throws BadLocationException {
                int length = field.getDocument().getLength();
                if (length + str.length() <= 1) {
                    fb.replace(off, len, str.replaceAll("[^1-9]", ""), attr);  // remove non-digits
                }
            }
        });
        return field;
    }


    private JTable createTable(final JTextField field) {
        String[] cols = {"Only Numbers", "Col 2", "Col 3"};
        String[][] data = {{null, null, null}, {null, null, null}, {null, null, null}};
        final TableCellEditor editor = new DefaultCellEditor(field);
        JTable table = new JTable(data, cols) {
            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                int modelColumn = convertColumnIndexToModel(column);

                if (modelColumn == 0) {
                    return editor;
                } else {
                    return super.getCellEditor(row, column);
                }
            }
        };
        return table;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JTableNumberColumn();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)