0

我在带有自定义 TableModel 的 JScrollPane 中使用 JTable,禁用了单元格/列选择并且仅启用了行选择(单选)。如果我不时选择一行,我执行单击的单元格中的值也会出现在相邻列中(并覆盖那里的值)。任何人都可以给我一个提示,我做错了什么或其他人面临这个问题吗?

提前感谢您的帮助!

编辑:我添加了一个 SSCCE。几次选择后,应该会出现问题。您可以通过在将鼠标悬停在行上时按住鼠标来加速它的发生。如果它出现一次,它会在每次选择期间出现。

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;

public class TableIssueSSCCE {

    public TableIssueSSCCE() {
        JFrame frame = new JFrame();
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        JTable table = new JTable(new DefaultTableModel());
        DefaultTableModel model = (DefaultTableModel) table.getModel();
        model.addColumn("Test1");
        model.addColumn("Test2");
        model.addColumn("Test3");
        model.addColumn("Test4");
        for (int i = 0; i < 1000; i++) {
            model.addRow(new String[]{
                "Column1" + i, "Column2" + i, "Column3" + i, "Column4" + i});
        }

        table.setFillsViewportHeight(true);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        table.setCellSelectionEnabled(false);
        table.setColumnSelectionAllowed(false);
        table.setRowSelectionAllowed(true);
        table.setAutoCreateRowSorter(true);
        JScrollPane tableContainer = new JScrollPane(table);
        tableContainer.setVerticalScrollBar(new JScrollBar(JScrollBar.VERTICAL));
        tableContainer.setHorizontalScrollBar(new JScrollBar(JScrollBar.HORIZONTAL));
        frame.add(tableContainer, BorderLayout.CENTER);

        frame.setVisible(true);
    }

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

2 回答 2

1

通过更改为 Oracle 的 JRE,我能够避免该问题。所以这个问题似乎与 OpenJDK 有关。

于 2016-04-05T16:40:53.740 回答
1

一些观察:

  • 每当 Swing 程序间歇性地出现异常行为时,我就会开始寻找不正确的同步,有时会求助于此处显示的方法。另请参见初始线程。因为此类错误可能难以重现,所以最好是安全的:

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new TableIssueSSCCE();
        });
    }
    
  • 而不是setSize(),覆盖getPreferredScrollableViewportSize(),如建议这里

于 2016-04-06T02:02:59.383 回答