根据数据类型使用不同类型的单元格的JTable

8
我该如何实现一个JTable,根据每一行所显示的输入类型,使用不同类型的单元格编辑器?
例如:
- 一些行可以是复选框(对于布尔类型)。 - 一些行可以是下拉列表(如果我想提供一组固定的选项供选择)。 - 一些行可以是文本字段(如果我允许任意数据)。
目前,我已经实现了AbstractTableModel,它从我的对象中获取一组自定义字段对象并将其添加到表中。我希望通过设置特定类型的单元格来进一步自定义我的表格。我可以根据该行包含的字段类型确定要使用哪种单元格类型。
表模型在运行时动态创建。

对于 TableCellRenderer 创建 EachRowRenderer 没有问题,但从未尝试过(如果存在)与 TableCellEditor 一起使用。无论 JTable 的值是存储在 DefaultTableModel 还是 AbstractTableModel 中都没有关系。 - mKorbel
2个回答

17
  • 某些行可以是复选框(用于布尔类型)
  • 某些行可以是下拉框(如果我想提供一组固定的选项供选择)
  • 某些行可以是文本字段(如果我允许任意数据)。

例如

输入图像说明

import java.awt.EventQueue;
import java.util.Date;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;


public class EachRowRendererEditor {

    private JFrame frame = new JFrame("EachRowRendererEditor");
    private  String[] columnNames = {"Type", "Value"};
    private     Object[][] data = {
            {"String", "I'm a string"},
            {"Date", new Date()},
            {"Integer", new Integer(123)},
            {"Double", new Double(123.45)},
            {"Boolean", Boolean.TRUE}};
   private  JScrollPane scrollPane;
   private  JTable table;

    public EachRowRendererEditor() {
        table = new JTable(data, columnNames) {

            private static final long serialVersionUID = 1L;
            private Class editingClass;

            @Override
            public TableCellRenderer getCellRenderer(int row, int column) {
                editingClass = null;
                int modelColumn = convertColumnIndexToModel(column);
                if (modelColumn == 1) {
                    Class rowClass = getModel().getValueAt(row, modelColumn).getClass();
                    return getDefaultRenderer(rowClass);
                } else {
                    return super.getCellRenderer(row, column);
                }
            }

            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                editingClass = null;
                int modelColumn = convertColumnIndexToModel(column);
                if (modelColumn == 1) {
                    editingClass = getModel().getValueAt(row, modelColumn).getClass();
                    return getDefaultEditor(editingClass);
                } else {
                    return super.getCellEditor(row, column);
                }
            }
            //  This method is also invoked by the editor when the value in the editor
            //  component is saved in the TableModel. The class was saved when the
            //  editor was invoked so the proper class can be created.

            @Override
            public Class getColumnClass(int column) {
                return editingClass != null ? editingClass : super.getColumnClass(column);
            }
        };
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        scrollPane = new JScrollPane(table);
        frame.add(scrollPane);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

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

            @Override
            public void run() {
                EachRowRendererEditor eeee = new EachRowRendererEditor();
            }
        });
    }
}

1
使用JTable.getDefaultRenderer非常简单,可以直接提供一个示例。 - TT.
利用这个作为参考,我可能可以相对容易地使用类似 http://www.javaworld.com/javaworld/javatips/jw-javatip102.html 的东西来实现组合框吗? - MxLDevs
这里提供一个符合本文所述方法的例子:https://dev59.com/b1zUa4cB1Zd3GeqPzAQW#7701420。 - trashgod
您的索引转换不完整且不必要:只需使用表格 API 访问单元格值(而不是查询底层模型)table.getValueAt(row, column),该值在视图坐标中。 - kleopatra
@mKorbel:哇,太棒了:-),刚看到JTable,现在的日子,从未想过,甚至这个也可以做到 :-) +1 - nIcE cOw
显示剩余3条评论

0
创建一个自定义类,实现javax.swing.table.TableCellRenderer接口,根据数据类型使用你想要显示的控件来显示值。将该类的实例用作单元格渲染器(TableColumn.setCellRenderer)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接