java - 知道为什么 AbstractTableModel 会导致空单元格添加到我的表格中吗? (Java Swing )

标签 java swing jtable abstracttablemodel

正如标题所示,当我向基础列表添加内容时,空单元格将被添加到我的表格中。

主类:

import javax.swing.SwingUtilities;

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MainFrame frame = new MainFrame();
            }
        });
    }
}

主框架类:

import java.awt.BorderLayout;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JTable;

public class MainFrame extends JFrame {
    private JTable table;
    private ArrayList<String> strings;
    
    public MainFrame() {
        setTitle("Stack Overflow");
        setSize(800, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        setVisible(true);
        
        strings = new ArrayList<String>();
        table = new JTable(new TableModel(strings));
        
        add(table,BorderLayout.CENTER);
        
        for (int i = 0; i < 10; i++) {
            strings.add("data");
        }
    }
}

AbstractTableModel 类:

import java.util.List;

import javax.swing.table.AbstractTableModel;

public class TableModel extends AbstractTableModel {
    private String[] colNames = {"Col1","Col2"};
    
    private List<String> strings;
    
    public TableModel(List<String> strings) {
        this.strings = strings;
    }
    
    @Override
    public String getColumnName(int column) {
        return colNames[column];
    }

    @Override
    public int getRowCount() {
        return strings.size();
    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    @Override
    public String getValueAt(int rowIndex, int columnIndex) {
        if (rowIndex*2 + columnIndex >= strings.size()) return "";
        return strings.get(rowIndex*2 + columnIndex);
    }
}

有没有更好的方法从我的一维数组中获取项目,以便从左到右、从上到下填充表格(没有额外的空单元格)?

为什么会出现这个问题?

结果: Extra empty rows added.

最佳答案

您拥有的数据和建模方式是两个不同的问题,不要害怕将它们分开以实现您的目标,例如:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.table.AbstractTableModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JTable table;
        private SequentialTableModel model;

        public TestPane() {
            setLayout(new BorderLayout());
            model = new SequentialTableModel();
            table = new JTable(model);
            add(new JScrollPane(table));

            Timer timer = new Timer(500, new ActionListener() {
                private int count = 0;
                @Override
                public void actionPerformed(ActionEvent e) {
                    model.add("Data " + (++count));
                }
            });
            timer.start();
        }

    }

    public class SequentialTableModel extends AbstractTableModel {

        private String[] colNames = {"Col1", "Col2"};

        private List<List<String>> rows = new ArrayList<>(32);

        public SequentialTableModel() {
        }

        @Override
        public String getColumnName(int column) {
            return colNames[column];
        }

        @Override
        public int getRowCount() {
            return rows.size();
        }

        @Override
        public int getColumnCount() {
            return 2;
        }

        @Override
        public String getValueAt(int rowIndex, int columnIndex) {
            List<String> values = rows.get(rowIndex);
            if (columnIndex >= values.size()) {
                return null;
            }
            return values.get(columnIndex);
        }

        public void add(String value) {
            if (rows.isEmpty()) {
                addNewRow(value);
                return;
            }

            List<String> lastRow = rows.get(rows.size() - 1);
            if (lastRow.size() < 2) {
                lastRow.add(value);
                fireTableCellUpdated(rows.size() - 1, lastRow.size() - 1);
            } else {
                addNewRow(value);
            }
        }

        protected void addNewRow(String value) {
            List<String> row = new ArrayList<>(2);
            row.add(value);
            rows.add(row);
            fireTableRowsInserted(rows.size() - 1, rows.size() - 1);
            return;
        }
    }
}

关于java - 知道为什么 AbstractTableModel 会导致空单元格添加到我的表格中吗? (Java Swing ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60747688/

相关文章:

java - 获取特定字符串 JAVA 的二进制大小

java - 如下图这种分数值怎么写?

java - 更改 Activity 时如何停止 PhoneStateListener

java - 一起使用 swing 和 awt 是不好的做法吗?

java - 有什么方法可以获取paintComponent中的参数吗?

java - 我应该在 Java 8 Streams 中使用共享可变变量更新吗

java - 如何将面板 1 中的文本宽度设置为等于面板 2 中的宽度

rendering - JTable 单元格渲染

java - 过滤 JTable

java - 我无法使用 JTable 从 SQL 数据库中删除