gpt4 book ai didi

java - 当我使用removeAll(且 e.getValueIsAdjusting == false)从列表中删除多个项目时,为什么我的 ListSelectionListener 会看到多个事件?

转载 作者:行者123 更新时间:2023-12-01 15:10:06 25 4
gpt4 key购买 nike

我在下面的示例中使用 GlazedLists 的 EventListEventTableModel。我不确定这会有所不同。我有一张 table ,我正在观察选择的变化。当我删除多个项目时,ListSelectionListener 会看到多个事件,并且在处理程序内部时,表报告的选定索引与删除发生之前的模型状态相匹配虽然模型已经改变了。

当我运行下面的示例时,列表中添加了 7 个项目。如果我选择最后两项,控制台上将出现以下输出:

Selected row count: 2
Item list size: 7
Selected index: 5
Selected index: 6

这正是我所期望的,但是当我删除这两个项目时,我得到以下输出:

Selected row count: 1
Item list size: 5
Selected index: 5

Selected row count: 0
Item list size: 5

由于我使用列表上的 removeAll 删除连续 block 中的项目,因此我认为这是一个事件,但 ListSelectionListener 似乎收到了通知,就好像它是两个独立的事件。如果我删除 4 个项目,监听器会看到 4 个事件。

表格和模型不同步,但我不确定为什么。如果从列表末尾删除项目,则表报告的选定索引可能大于基础列表大小。基本上,从 JTable.getSelectedRows 返回的索引直到由调用底层模型上的 removeAll 引起的最后一个选择事件才可靠。

在列表选择稳定并且 JTable 将报告正确的选定索引后,如何获得有关选择更改的通知?

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.gui.AdvancedTableFormat;
import ca.odell.glazedlists.impl.sort.ComparableComparator;
import ca.odell.glazedlists.swing.EventTableModel;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import static javax.swing.WindowConstants.EXIT_ON_CLOSE;

public class MultiDeleteMain {
// The number of items that should be added to the model.
@SuppressWarnings("FieldCanBeLocal")
private final int itemCount = 7;

private EventList<Item> itemList;
private JTable itemTable;

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

public MultiDeleteMain() {
SwingUtilities.invokeLater(new Runnable() {
@SuppressWarnings("ConstantConditions")
@Override
public void run() {
// The delete function needs access to the list and table, so
// they are stored as instance variables.
itemList = createItemList();
itemTable = createItemTable(itemList);

addListSelectionListenerToItemTable(itemTable);

JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(createDeleteButton(), BorderLayout.NORTH);
mainPanel.add(new JScrollPane(itemTable), BorderLayout.CENTER);

JFrame mainFrame = new JFrame("Multi-deletion in list test.");
mainFrame.setContentPane(mainPanel);
mainFrame.pack();
mainFrame.setSize(300, mainFrame.getHeight());
mainFrame.setLocationRelativeTo(null);
mainFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
mainFrame.setVisible(true);
}
});
}

private EventList<Item> createItemList() {
EventList<Item> itemList = new BasicEventList<>();
for (int i = 0; i < itemCount; i++) {
itemList.add(new Item("Item " + i));
}
return itemList;
}

@SuppressWarnings("ConstantConditions")
private JTable createItemTable(EventList<Item> itemList) {
JTable itemTable = new JTable(new EventTableModel<>(itemList, new EventTableModelFormat()));
itemTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
return itemTable;
}

private void addListSelectionListenerToItemTable(final JTable itemTable) {
ListSelectionListener listener = new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()) {
System.out.println("Selected row count: " + itemTable.getSelectedRowCount());
System.out.println("Item list size: " + itemList.size());
for(Integer index : itemTable.getSelectedRows()) {
System.out.println("Selected index: " + index);
}
System.out.println();
}
}
};

itemTable.getSelectionModel().addListSelectionListener(listener);
}

private JButton createDeleteButton() {
JButton deleteButton = new JButton("Delete");
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deleteSelectedItems();
}
});
return deleteButton;
}

@SuppressWarnings("ConstantConditions")
private void deleteSelectedItems() {
List<Item> itemsToDelete = new ArrayList<>();
for (Integer rowIndex : itemTable.getSelectedRows()) {
int convertedIndex = itemTable.convertRowIndexToModel(rowIndex);
itemsToDelete.add(itemList.get(convertedIndex));
}

itemList.removeAll(itemsToDelete);
itemTable.revalidate();
itemTable.repaint();
}

// Enum for managing table columns
private static enum Columns {
NAME("Name", String.class, new ComparableComparator());

private final String name;
private final Class type;
private final Comparator comparator;

private Columns(String name, Class type, Comparator comparator) {
this.name = name;
this.type = type;
this.comparator = comparator;
}
}

// Each table holds a list of items.
private static class Item {
private final String name;

private Item(String name) {
this.name = name;
}
}

// Table format for use with the EventTableModel
private static class EventTableModelFormat implements AdvancedTableFormat<Item> {
@Override
public int getColumnCount() {
return 1;
}

@Override
public String getColumnName(int i) {
return Columns.values()[i].name;
}

@Override
public Object getColumnValue(Item item, int i) {
return item.name;
}

@Override
public Class getColumnClass(int column) {
return Columns.values()[column].type;
}

@Override
public Comparator getColumnComparator(int column) {
System.out.println("Asked for comparator.");
return Columns.values()[column].comparator;
}
}
}

最佳答案

我们必须知道 EventList 和 EventTableModel 是什么样子的。我敢打赌,EventTableModel 不能保证 deleteAll 方法只传递连续的元素。因此,唯一的选择就是将它们一一删除,为每个事件触发一个单独的事件。

关于java - 当我使用removeAll(且 e.getValueIsAdjusting == false)从列表中删除多个项目时,为什么我的 ListSelectionListener 会看到多个事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12451198/

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