Java 行选择不随JTable中的行移动而移动
我有以下代码:Java 行选择不随JTable中的行移动而移动,java,swing,jtable,local-variables,listselectionlistener,Java,Swing,Jtable,Local Variables,Listselectionlistener,我有以下代码: 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 ja
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){
}
}
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.util.Vector;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.SwingUtilities;
导入javax.swing.UIManager;
导入javax.swing.plaf.nimbus.NimbusLookAndFeel;
导入javax.swing.table.DefaultTableModel;
公共类NewClass1扩展了JFrame{
专用JTable表;
私有JScrollPane滚动窗格;
私有DefaultTableModel DefaultTableModel;
公共服务类别1(){
setLocationByPlatform(真);
setLayout(新的BorderLayout());
setPreferredSize(新尺寸(600400));
setTitle(“表格发行”);
setDefaultCloseOperation(关闭时退出);
createTableModel();
table=新的JTable(defaultTableModel);
scrollPane=新的JScrollPane(表);
getContentPane().add(滚动窗格,BorderLayout.CENTER);
包装();
}
私有void createTableModel(){
向量cols=新向量();
列加(“A”);
向量行=新向量();
对于(int i=0;i<50;i++){
向量行=新向量();
行。添加((i+1)+“”);
行。添加(行);
}
defaultTableModel=新的defaultTableModel(行、列){
类[]类型=新类[]{
String.class
};
@凌驾
公共类getColumnClass(int columnIndex){
返回类型[列索引];
}
@凌驾
公共布尔值可编辑(int行,int列){
返回false;
}
};
}
公共静态void main(字符串[]args){
试一试{
setLookAndFeel(新的NimbusLookAndFeel());
}捕获(例外e){
}
最终NewClass1 nc=新NewClass1();
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
nc.setVisible(真);
}
});
while(true){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
int行=(int)(Math.random()*50);
int move=(int)(Math.random()*50);
nc.defaultTableModel.moveRow(行,行,移动);
}
});
试一试{
睡眠(1000);
}捕获(例外e){
}
}
}
}
请运行上述代码并选择行
我的问题是行移动,行选择不移动。它保持在固定的位置。假设我选择了列值为25的行,则在行移动后,所选行的列值必须为25
请帮我做这个
我真正的问题是,用户将选择行并单击菜单来执行操作,同时其他线程可能已经移动了行,并且执行的操作将在实际行以外的其他行上。最简单的方法是在
列表选择模型
之外的某个位置记住所选行,并在表格模型
更改时调整所选行。例如,您可以这样做:
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);
// ...
}
// ...
}
但是请注意,您应该调整此代码以供生产使用,例如在线程安全性或可移植性方面(使用内部类中的
表和defaultTableModel
属性是不好的样式)。,作者@GuillaumePolet@mKorbel这里的问题是模型的内容在变化,因此,convertRowIndexToModel
本身并不能完成这项工作,但我同意如果javax.swing.table.DefaultTableModel.moveRow
是正在发生的一切,那么使用javax.swing.RowSorter
将是一个更好的方法——我理解这是一个通用模型更改的示例。请回答一个问题,为什么使用if(!event.getValueIsAdjusting())返回;这实际上不是必需的,但更为简洁:选择新行时会触发两次“valueChanged”事件:一次让您知道旧行未被选中,一次让您知道新行已被选中。只需将行注释出来,并在其中放入一条print
语句,它就会变得清晰。