Java 同步对象从反向列表中删除[JList-SWING]
使用自定义AbstractListModel管理ArrayList时遇到问题。 这是我的模型: TradeslModel.classJava 同步对象从反向列表中删除[JList-SWING],java,multithreading,swing,jlist,Java,Multithreading,Swing,Jlist,使用自定义AbstractListModel管理ArrayList时遇到问题。 这是我的模型: TradeslModel.class package window; import java.util.ArrayList; import javax.swing.AbstractListModel; import main.Trade; public class TradesListModel extends AbstractListModel<Object>{ /**
package window;
import java.util.ArrayList;
import javax.swing.AbstractListModel;
import main.Trade;
public class TradesListModel extends AbstractListModel<Object>{
/**
*
*/
private static final long serialVersionUID = 1L;
private ArrayList<Trade> trades;
public TradesListModel(){
trades = new ArrayList<Trade>();
}
public void add(Trade trade){
trades.add(0, trade);
this.fireIntervalAdded(this, 0, 1);
}
public void remove(){
trades.remove(trades.size()-1);
this.fireIntervalRemoved(this, trades.size(), trades.size());
}
public void clear(){
trades.clear();
this.fireIntervalRemoved(this, 0, trades.size());
}
@Override
public int getSize() {
return trades.size();
}
@Override
public Object getElementAt(int index) {
return trades.get(index);
}
}
我还有另一个newSingleThreadScheduledExecutor
,它每30秒调用我的主类remove()
的方法,从自定义模型处理的列表中删除对象:
public boolean updateTrades(){
Iterator<Trade> it = trades.iterator();
try {
synchronized(this){
index = 0;
while(it.hasNext()){
Trade current = it.next();
if(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()-current.getTime())>TIME){
it.remove();
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
lm.remove(index);
}
});
}
index++;
}
}
return true;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
<代码> TracdField是我的主要类。
让我们考虑下面的例子:当清单中有三个交易:<代码> UpDeTeals:<代码> [T0,T1,T2] < /代码>,所有这些都应该被删除。
在这种情况下,您将调用lm.remove
方法三次:使用索引0
、1
和2
。第一个之后,列表将包含[t1,t2]
,第二个之后:[t2]
。当您第三次调用它时,没有索引为2
的元素,因此您将得到IndexOutOfBoundsException
要修复它,只需调用lm.remove(0)三次。这将删除预期的前三个元素。
让我们考虑下面的例子:在列表中有三个交易:<代码> UpDeTeals:<代码> [T0,T1,T2] < /代码>,所有这些都应该被删除。
在这种情况下,您将调用lm.remove
方法三次:使用索引0
、1
和2
。第一个之后,列表将包含[t1,t2]
,第二个之后:[t2]
。当您第三次调用它时,没有索引为2
的元素,因此您将得到IndexOutOfBoundsException
要修复它,只需调用lm.remove(0)三次。这将按预期删除前三个元素。列表的第i个(从零开始)最后一个元素具有索引
size-i-1
,因此您应该将-1
添加到trades.remove(trades.size()-index)代码>行。请注意,fireIntervalAdded
和fireIntervalRemoved
的范围不一致。例如,您将元素添加到列表的开头,而fireeintervaladded
报告将元素添加到末尾。这可能会导致错误的UI重画。无论如何,updateTrades方法仅由scheduledExecutor线程调用。如何修复fireIntervalAdded和fireIntervalRemoved?This.fireIntervalAdded(This,0,1)
和this.fireIntervalRemoved(this,trades.size()-index,trades.size()-index)
(请注意,该元素已在前一行删除,因此不再需要-1
)。列表的第i个(从零开始)最后元素具有索引size-i-1
,因此您应该将-1
添加到trades.remove(trades.size()-index))代码>行。请注意,fireIntervalAdded
和fireIntervalRemoved
的范围不一致。例如,您将元素添加到列表的开头,而fireeintervaladded
报告将元素添加到末尾。这可能会导致错误的UI重画。无论如何,updateTrades方法仅由scheduledExecutor线程调用。如何修复fireIntervalAdded和fireIntervalRemoved?This.fireIntervalAdded(This,0,1)
和this.fireIntervalRemoved(this,trades.size()-index,trades.size()-index)代码>(请注意,元素已在前一行中删除,因此不再需要-1
)。
public boolean updateTrades(){
Iterator<Trade> it = trades.iterator();
try {
synchronized(this){
index = 0;
while(it.hasNext()){
Trade current = it.next();
if(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()-current.getTime())>TIME){
it.remove();
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
lm.remove(index);
}
});
}
index++;
}
}
return true;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -6
at java.util.ArrayList.elementData(ArrayList.java:418)
at java.util.ArrayList.remove(ArrayList.java:495)
at window.TradesListModel.remove(TradesListModel.java:28)
at main.TradeFinder$2.run(TradeFinder.java:119)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)