RowSorter를 사용하여 정렬되고 필터링 된 JTable이 있으며 실시간 방식으로 업데이트됩니다. 사용자가 마우스 (클릭 + 행 위로 끌기) 또는 키보드 (Shift + 아래쪽 화살표 여러 번)를 사용하여 선택 간격을 만들려고 할 때 문제가 있습니다.정렬 테이블의 JTable 선택 간격 문제
테이블 모델 업데이트 이벤트가 발생하면 선택 간격 시작 및 끝이 손상됩니다. 테이블이 정렬되고 둘 이상의 선택된 행이있는 경우 선택 모델은 모든 테이블 모델 업데이트에서 선택을 다시 지우는 여러 목록 선택 이벤트를 발생시키는 것을 발견했습니다.
한 번에 여러 행을 선택하면 모두 정상입니다. 사용자가 선택한 항목이 선택된 상태로 유지됩니다. 그러나 사용자가 마우스를 여러 행에 걸쳐 클릭 한 채 드래그하여 선택 간격을 만들려고하면 표 모델 업데이트 이벤트가 발생할 때까지 행이 올바르게 선택됩니다. 그런 다음 선택 항목은 현재 선택된 행에서 빌드를 시작합니다.
작은 데모 응용 프로그램을 첨부했습니다. 마우스를 사용하여 여러 행을 선택해보십시오. 선택이 손상 될 때마다 ....
이것은 Java 클래스에서 버그 (또는 원하지 않는 동작) 인 것 같습니다. 누군가가 창의적인 솔루션/해결 방법을 제공 할 수 있기를 바랍니다. 나는 윈도우 7에 JDK7를 사용하여 코드를 실행
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);
}
});
}
}
문제가 발생하지 않았습니다. 관점에서 보았을 때 선택은 일종의 정렬이었습니다. 즉 행 1-5를 선택하고 그 앞에 새로운 행이 삽입되면 해당 행이 아래로 이동합니다. 새로운 행이 그들 사이의 어딘가에 삽입된다면, 선택은 데이터가 아니라 행 (높은 레벨의 관점)을 기반으로하기 때문에 나의 기대가 될 것입니다. – MadProgrammer
이것이 코드가 작동하는 방식입니다. 선택 간격을 확장하면서 테이블 모델을 업데이트합니다. 내 테스트 응용 프로그램을 실행하면 매초마다 테이블 모델 업데이트가 전송됩니다. 표의 행 2를 클릭하고 마우스를 위/아래로 드래그하여 행을 선택하십시오. 2를 누르십시오. 7을 누르고 나서 행을 2부터 4까지 선택하고 다시 2를 선택하여 행 2에서 10을 선택하십시오. 테이블 모델 업데이트는 선택 프로세스 중에 발생합니다. 앵커 선택 (행 2)이 휴지통으로 바뀌고 이제는 마우스가있는 곳 (업데이트가 발생했을 때)부터 어디로 이동했는지 선택이 확대되기 시작합니다. –
좋아요, 어쩌면 당신은 목록 선택 업데이트가 진행되는 동안 업데이트가 목록 선택이 완료 될 때까지 대기하도록 예를 들어 어떤 식 으로든 업데이트를 격리해야 할 수도 있습니다 ... – MadProgrammer