编辑 JTable / TableModel 中列的单元格限制

huangapple go评论70阅读模式
英文:

Editing cell restrictions of a column in a JTable / TableModel

问题

我想修改在我的 JTable 中处理单元格输入的方式。目前我正在使用一个如下所示的 DefaultTableModel。

 DefaultTableModel model = new DefaultTableModel() {

                @Override
                public boolean isCellEditable(int row, int col) {
                    return col == 1 || col == 2 || col == 6;
                }

                @Override
                public Class getColumnClass(int col) {
                    if (col == 6) {
                        return Integer.class;
                    } else {
                        return String.class;
                    }
                }

            };

通过这段代码,第6列会强制用户输入一个整数。我希望进一步做得更多,不允许数字超出某个范围(例如1-100),并且还要求字段在用户交互之前不能是空的(在用户交互之前,该列将有数据)。我已阅读了文档,但似乎找不到可以管理列类型行为的任何内容。谢谢!

英文:

I am looking to modify the way cell input is handled in my JTable. Currently I am using a DefaultTableModel as seen below.

 DefaultTableModel model = new DefaultTableModel() {

                @Override
                public boolean isCellEditable(int row, int col) {
                    return col == 1 || col == 2 || col == 6;
                }

                @Override
                public Class getColumnClass(int col) {
                    if (col == 6) {
                        return Integer.class;
                    } else {
                        return String.class;
                    }
                }

            };

With this code column 6 forces the user to input an Integer. I would like to take this further by not allowing the number to be outside of a range (e.g. 1-100) and also for the field to never be empty (The column will have data in it prior to user interaction). I have read the docummentation but cannot seem to find anything that manages the behaviour of column types. Thanks!

答案1

得分: 1

你需要创建一个自定义编辑器。

以下示例演示了一个强制数据为5个字符的编辑器:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;

public class TableFiveCharacterEditor extends DefaultCellEditor
{
    private long lastTime = System.currentTimeMillis();

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

    public boolean stopCellEditing()
    {
        JTable table = (JTable)getComponent().getParent();

        try
        {
            String editingValue = (String)getCellEditorValue();

            if(editingValue.length() != 5)
            {
                JTextField textField = (JTextField)getComponent();
                textField.setBorder(new LineBorder(Color.red));
                textField.selectAll();
                textField.requestFocusInWindow();

                JOptionPane.showMessageDialog(
                    table,
                    "Please enter string with 5 letters.",
                    "Alert!", JOptionPane.ERROR_MESSAGE);
                return false;
            }
        }
        catch(ClassCastException exception)
        {
            return false;
        }

        return super.stopCellEditing();
    }

    public Component getTableCellEditorComponent(
        JTable table, Object value, boolean isSelected, int row, int column)
    {
        Component c = super.getTableCellEditorComponent(
            table, value, isSelected, row, column);
        ((JComponent)c).setBorder(new LineBorder(Color.black));

        return c;
    }

    private static void createAndShowUI()
    {
        JTable table = new JTable(5, 5);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);

        // 使用自定义编辑器

        TableCellEditor fce = new TableFiveCharacterEditor();
        table.setDefaultEditor(Object.class, fce);

        JFrame frame = new JFrame("Table Five Character Editor");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(scrollPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

你需要修改编辑器以确保:

  1. 数据是整数,使用 Integer.parseInt(...) 方法。
  2. 整数值在你所需的范围内。

编辑:

> 如何只影响一列而不是整个表格。

你可以将编辑器添加到 TableColumn

table.getColumnModel().getColumn(...).setCellEditor(...);
英文:

You would need to create a custom editor.

The following example demonstrates and editor that forces the data to be 5 characters:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class TableFiveCharacterEditor extends DefaultCellEditor
{
private long lastTime = System.currentTimeMillis();
public TableFiveCharacterEditor()
{
super( new JTextField() );
}
public boolean stopCellEditing()
{
JTable table = (JTable)getComponent().getParent();
try
{
String editingValue = (String)getCellEditorValue();
if(editingValue.length() != 5)
{
JTextField textField = (JTextField)getComponent();
textField.setBorder(new LineBorder(Color.red));
textField.selectAll();
textField.requestFocusInWindow();
JOptionPane.showMessageDialog(
table,
"Please enter string with 5 letters.",
"Alert!",JOptionPane.ERROR_MESSAGE);
return false;
}
}
catch(ClassCastException exception)
{
return false;
}
return super.stopCellEditing();
}
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column)
{
Component c = super.getTableCellEditorComponent(
table, value, isSelected, row, column);
((JComponent)c).setBorder(new LineBorder(Color.black));
return c;
}
private static void createAndShowUI()
{
JTable table = new JTable(5, 5);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
//  Use a custom editor
TableCellEditor fce = new TableFiveCharacterEditor();
table.setDefaultEditor(Object.class, fce);
JFrame frame = new JFrame("Table Five Character Editor");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( scrollPane );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}

You would need to modify the editor to make sure:

  1. the data is an Integer by using the Integer.parseInt(...) method
  2. that the Integer value is in your desired range

Edit:

> how can I apply this to influence one column rather than the entire table.

You can add the editor to the TableColumn:

table.getColumnModel().getColumn(...).setCellEditor(...);

答案2

得分: 0

覆盖DefaultCellEditor的行为可以实现所需的结果。

DefaultCellEditor editor = new DefaultCellEditor(new JTextField()) {
    @Override
    public boolean stopCellEditing() {
        JTable table = (JTable) getComponent().getParent();
        try {
            String value = (String) getCellEditorValue();
            if (Integer.parseInt(value) < 1) {
                JTextField textField = (JTextField) getComponent();
                textField.setBorder(new LineBorder(Color.red));
                textField.selectAll();
                textField.requestFocusInWindow();
                return false;
            }
        } catch (NumberFormatException ex) {
            return false;
        }
        return super.stopCellEditing();
    }
};

然后将其添加到表格的所需列。

table.getColumnModel().getColumn(6).setCellEditor(editor);

编辑:如果抛出NumberFormatException,则if语句内部的行为将不会发生,您可能希望在catch中放置相同的代码行。

英文:

Overriding the behaviour of the DefaultCellEditor achieves the desired outcome.

            DefaultCellEditor editor = new DefaultCellEditor(new JTextField()) {
@Override
public boolean stopCellEditing() {
JTable table = (JTable) getComponent().getParent();
try {
String value = (String) getCellEditorValue();
if (Integer.parseInt(value) &lt; 1) {
JTextField textField = (JTextField) getComponent();
textField.setBorder(new LineBorder(Color.red));
textField.selectAll();
textField.requestFocusInWindow();
return false;
}
} catch (NumberFormatException ex) {
return false;
}
return super.stopCellEditing();
}
};

Then added to the desired column of the table.

table.getColumnModel().getColumn(6).setCellEditor(editor);

Edit: The behaviour inside the if statement will not occur if a NumberFormatException is thrown, you may want to put the same lines of code within the catch.

huangapple
  • 本文由 发表于 2020年10月4日 02:53:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/64187867.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定