gpt4 book ai didi

java - JTable 排序表的选择间隔问题

转载 作者:行者123 更新时间:2023-11-30 03:44:11 27 4
gpt4 key购买 nike

我有一个使用 RowSorter 进行排序和过滤并实时更新的 JTable。当用户尝试使用鼠标(单击 + 拖动行)或通过键盘(SHIFT + 向下箭头多次)创建选择间隔时,我遇到问题。

一旦发生表模型更新事件,选择间隔的开始和结束就会被破坏。我发现,如果一张表已排序并且有多个选定行,则选择模型会触发多个列表选择事件,这些事件会清除然后在每次表模型更新时重新创建选择。

如果一次选择多行一行 - 一切都很好。用户选择的内容保持选中状态。但是,如果用户尝试通过在多行上单击并向下拖动鼠标来创建选择间隔,则在触发表模型更新事件之前,会正确选择行。然后从当前选定的行开始构建选择。

我附上了一个小型演示应用程序。尝试使用鼠标选择多行 - 每一秒选择都会被损坏......

这似乎是 Java 类中的错误(或不需要的行为)。我希望有人可以提供创造性的解决方案/解决方法。

    public class TableTest extends JFrame {
private static final long serialVersionUID = 1L;

public TableTest() {
super("Table Selection Problem");
setBounds(50, 50, 800, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);

// Create a table model
final DefaultTableModel tableModel = new DefaultTableModel(40,10);

// Create table row sorter sorted on column 1
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableModel);
sorter.setSortsOnUpdates(true);
sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(1,SortOrder.DESCENDING)));

// Create a table and bind the sorter
JTable table = new JTable(tableModel);
table.setRowSorter(sorter);

// Bind a list selection listener, this doesn't do anything besides showing the selection change(s) on every table model update
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
System.out.println(e);
}
});


// place the table in the frame
getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);

// Simulate some application events that trigger a table update...
new Thread() {
public void run() {
try {
final Random r = new Random();
for(int x = 0; x < 1000; x++) {
// update a table cell (not even an add or delete)
SwingUtilities.invokeLater(new Runnable() {
public void run() {
tableModel.setValueAt(r.nextInt(1000), r.nextInt(40), r.nextInt(10));
}
});
// wait 1 second before next table update
Thread.sleep(1000);
}
} catch(Throwable t) {
t.printStackTrace();
}
}
}.start();
}


public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
(new TableTest()).setVisible(true);
}
});
}
}

最佳答案

当我在 Windows 7 上使用 JDK7 运行您的代码时,我发现 setSortsOnUpdates(...) 导致表中的数据出现问题。也就是说,我让代码运行了一段时间,我注意到第 1 列中没有显示任何值。然后我增加了框架的宽度,突然这些值按排序顺序出现。因此,由于某种原因,即使数据发生了变化,表也没有被重新绘制。当我评论 setSortsOnUpdates(...) 时,对 TableModel 的更改立即出现。我不知道问题是什么。

因此,我更改了在数据更改时手动调用排序的方法。但是,我仅在 ListSelectionListener 未调整时才进行排序。这是代码:

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.Arrays;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;

public class TableTest5 extends JFrame {
private static final long serialVersionUID = 1L;

private boolean isAdjusting = false;
private boolean isModelChanged = false;
TableRowSorter<TableModel> sorter;
final Random r = new Random();

public TableTest5() {
super("Table Selection Problem");
setBounds(50, 50, 800, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);

// Create a table model
final DefaultTableModel tableModel = new DefaultTableModel(30,3);

// Create table row sorter sorted on column 1
// TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableModel);
sorter = new TableRowSorter<TableModel>(tableModel);
sorter.setSortsOnUpdates(true);
sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(1,SortOrder.DESCENDING)));

// Create a table and bind the sorter
JTable table = new JTable(tableModel);
table.setRowSorter(sorter);

// Bind a list selection listener, this doesn't do anything besides showing the selection change(s) on every table model update
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
isAdjusting = e.getValueIsAdjusting();

if (!isAdjusting && isModelChanged)
{
isModelChanged = false;
sorter.sort();
}
}
});


// place the table in the frame
getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);

// Simulate some application events that trigger a table update...
new Thread() {
public void run() {
try {
//final Random r = new Random();
for(int x = 0; x < 1000; x++) {
// update a table cell (not even an add or delete)
SwingUtilities.invokeLater(new Runnable() {
public void run() {

int value = r.nextInt(1000);
int row = r.nextInt(30);
int column = r.nextInt(5);
System.out.println(value + " : " + row + " : " + column);
tableModel.setValueAt(value, row, column);

if (!isAdjusting)
sorter.sort();
else
isModelChanged = true;
}
});
// wait 1 second before next table update
Thread.sleep(1000);
}
} catch(Throwable t) {
t.printStackTrace();
}
}
}.start();

}


public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
(new TableTest5()).setVisible(true);
}
});
}
}

您可能需要考虑使用 TableModelListener 来监听 TableModel 更改以手动调用排序。

关于java - JTable 排序表的选择间隔问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26151759/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com