1

我有以下代码:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.DefaultTableModel;

public class NewClass1 extends JFrame {
    private JTable table;
    private JScrollPane scrollPane;
    private DefaultTableModel defaultTableModel;

    public NewClass1() {
        setLocationByPlatform(true);
        setLayout(new BorderLayout());
        setPreferredSize(new Dimension(600, 400));
        setTitle("Table Issues");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        createTableModel();
        table = new JTable(defaultTableModel);

        scrollPane = new JScrollPane(table);

        getContentPane().add(scrollPane, BorderLayout.CENTER);

        pack();
    }

    private void createTableModel() {
        Vector cols = new Vector();
        cols.add("A");

        Vector rows = new Vector();
        for (int i = 0; i < 50; i++) {
            Vector row = new Vector();
            row.add((i + 1) + "");
            rows.add(row);
        }

        defaultTableModel = new DefaultTableModel(rows, cols) {
            Class[] types = new Class[]{
                String.class
            };

            @Override
            public Class getColumnClass(int columnIndex) {
                return types[columnIndex];
            }

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(new NimbusLookAndFeel());
        } catch (Exception e) {
        }

        final NewClass1 nc = new NewClass1();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                nc.setVisible(true);
            }
        });

        while (true) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    int row = (int) (Math.random() * 50);
                    int move = (int) (Math.random() * 50);

                    nc.defaultTableModel.moveRow(row, row, move);
                }
            });
            try{
                Thread.sleep(1000);
            }catch(Exception e){
            }
        }
    }
}

请运行上面的代码并选择行。

我的问题是行移动,行选择没有移动。它停留在固定位置。假设我选择了列值为 25 的行,在行移动后,所选行的列值必须为 25。

请帮助我。

我真正的问题是,用户将选择行并单击菜单来执行操作,同时其他线程可能已经移动了行,并且执行的操作将在与实际行不同的行上。

4

1 回答 1

2

最简单的方法是记住选定行之外的某处,ListSelectionModel并在更改时调整选择TableModel。例如,您可以这样做:

public class NewClass1 extends JFrame {
    private JTable table;
    private DefaultTableModel defaultTableModel;
    private JScrollPane scrollPane;

    private class SelectionHelper implements ListSelectionListener, TableModelListener {
        private Object selectedRow;

        @Override
        public void valueChanged(ListSelectionEvent event) {
            if (!event.getValueIsAdjusting()) return;
            int selectedIndex = table.getSelectedRow();
            if (selectedIndex >= 0) {
                selectedRow = defaultTableModel.getDataVector().get(selectedIndex);
            } else {
                selectedRow = null;
            }
        }

        @Override
        public void tableChanged(TableModelEvent event) {
            if (selectedRow == null) return;
            int selectedIndex = defaultTableModel.getDataVector().indexOf(selectedRow);
            table.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex);
        }
    }

    public NewClass1() {
        // ...
        createTableModel();
        table = new JTable(defaultTableModel);

        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        SelectionHelper helper = new SelectionHelper();
        table.getModel().addTableModelListener(helper);
        table.getSelectionModel().addListSelectionListener(helper);
        // ...
    }
    // ...
}

但是请注意,您应该调整此代码以供生产使用,例如在线程安全或可移植性方面(在内部类中使用tableand属性是不好的风格)。defaultTableModel

于 2013-05-03T16:18:41.447 回答