在与 EDT 不同的线程中从 JList 中删除项目
Delete item from JList in a different thread than EDT
我试图在遍历 for 循环时从 JList 中删除一个元素。为了找出我要删除的元素,我比较了我定义的工具提示,然后只删除了那个元素。
public static void removeElement(JList list, String idx){
DefaultListModel model = (DefaultListModel)list.getModel();
JLabel actual;
for(int i = 0; i < model.getSize(); i++){
actual = (JLabel) model.get(i);
if(actual.getToolTipText().equals(idx)){
model.remove(i);
break;
}
}
}
这个函数在主class中声明,并访问swing元素,也声明为静态的。
然后该函数被另一个线程调用:
public class threadExample extends Thread{
//...
@Override
public void run() {
Main.removeElement(OIS.listElement, graphicalID);
}
}
执行时会出现这个异常,但只是偶尔出现。
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
t java.base/java.util.Vector.elementAt(Vector.java:497)
at java.desktop/javax.swing.DefaultListModel.getElementAt(DefaultListModel.java:90)
at java.desktop/javax.swing.plaf.basic.BasicListUI.paintCell(BasicListUI.java:265)
at java.desktop/javax.swing.plaf.basic.BasicListUI.paintImpl(BasicListUI.java:378)
at java.desktop/javax.swing.plaf.basic.BasicListUI.paint(BasicListUI.java:301)
at java.desktop/javax.swing.plaf.synth.SynthListUI.update(SynthListUI.java:78)
at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:797)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1074)
at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5255)
at java.desktop/javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:246)
at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1323)
at java.desktop/javax.swing.JComponent._paintImmediately(JComponent.java:5203)
at java.desktop/javax.swing.JComponent.paintImmediately(JComponent.java:5013)
at java.desktop/javax.swing.RepaintManager.run(RepaintManager.java:865)
at java.desktop/javax.swing.RepaintManager.run(RepaintManager.java:848)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:848)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:823)
at java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:772)
at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1890)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
据我所知,我无法像现在这样在 for 循环中进行删除,但我找不到任何替代方法。谁能帮帮我?
编辑
问题不在于删除过程,而是因为我在与 EDT 不同的线程中执行操作。
由于您似乎是在与 EDT 不同的线程中调用 removeElement,因此您应该使用:
SwingUtilities.invokeLater(() -> { removeElement(....); }
用于异步执行,或
SwingUtilities.invokeAndWait(() -> { removeElement(....); }
如果您想等待方法完成后再继续。
我试图在遍历 for 循环时从 JList 中删除一个元素。为了找出我要删除的元素,我比较了我定义的工具提示,然后只删除了那个元素。
public static void removeElement(JList list, String idx){
DefaultListModel model = (DefaultListModel)list.getModel();
JLabel actual;
for(int i = 0; i < model.getSize(); i++){
actual = (JLabel) model.get(i);
if(actual.getToolTipText().equals(idx)){
model.remove(i);
break;
}
}
}
这个函数在主class中声明,并访问swing元素,也声明为静态的。 然后该函数被另一个线程调用:
public class threadExample extends Thread{
//...
@Override
public void run() {
Main.removeElement(OIS.listElement, graphicalID);
}
}
执行时会出现这个异常,但只是偶尔出现。
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
t java.base/java.util.Vector.elementAt(Vector.java:497)
at java.desktop/javax.swing.DefaultListModel.getElementAt(DefaultListModel.java:90)
at java.desktop/javax.swing.plaf.basic.BasicListUI.paintCell(BasicListUI.java:265)
at java.desktop/javax.swing.plaf.basic.BasicListUI.paintImpl(BasicListUI.java:378)
at java.desktop/javax.swing.plaf.basic.BasicListUI.paint(BasicListUI.java:301)
at java.desktop/javax.swing.plaf.synth.SynthListUI.update(SynthListUI.java:78)
at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:797)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1074)
at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5255)
at java.desktop/javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:246)
at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1323)
at java.desktop/javax.swing.JComponent._paintImmediately(JComponent.java:5203)
at java.desktop/javax.swing.JComponent.paintImmediately(JComponent.java:5013)
at java.desktop/javax.swing.RepaintManager.run(RepaintManager.java:865)
at java.desktop/javax.swing.RepaintManager.run(RepaintManager.java:848)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:848)
at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:823)
at java.desktop/javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:772)
at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1890)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
据我所知,我无法像现在这样在 for 循环中进行删除,但我找不到任何替代方法。谁能帮帮我?
编辑
问题不在于删除过程,而是因为我在与 EDT 不同的线程中执行操作。
由于您似乎是在与 EDT 不同的线程中调用 removeElement,因此您应该使用:
SwingUtilities.invokeLater(() -> { removeElement(....); }
用于异步执行,或
SwingUtilities.invokeAndWait(() -> { removeElement(....); }
如果您想等待方法完成后再继续。