我有一个LinkedList<JLabel>
并在线程上使用它来添加或删除它们JPanel
,问题是有时会发生异常并且应用程序崩溃。在他们谈论同步我的列表的一些帖子中,其他人说我应该有一个迭代器,所以我有点困惑。
我将添加一些代码以使其易于理解:
public class MyPanel extends JPanel {
(...)
private LinkedList<JLabel> labels;
(...)
public MyPanel(Color corLabel, Color back, Font text) {
(...)
labels = new LinkedList<>();
(...)
}
这是链接列表被初始化的地方,现在我有 1 个方法和 1 个线程使用它:
public void addMensagem(MensagemParaEcra msg) {
JLabel lbl = new JLabel();
lbl.setText(("- " + msg.getTexto() + " -"));
lbl.setForeground(color);
lbl.setFont(textFont);
lbl.setOpaque(true);
lbl.setBackground(backg);
labels.add(lbl);
MyPanel.this.add(lbl);
}
这个只是配置标签并将其添加到面板和链接列表中
private void start() {
final Runnable running = new Runnable() {
@Override
public void run() {
MyPanel.this.repaint();
}
};
Thread t = new Thread() {
public void run() {
while (true) {
// for each label
for (JLabel lb : labels) {
if (lb.getLocation().x + lb.getWidth() < 0) {
if (msgsRemover.isEmpty() == true) {
//remove the label if she is out of the monitor
MyPanel.this.remove(lb);
// and add the label
MyPanel.this.add(lb);
MyPanel.this.repaint();
MyPanel.this.validate();
} else {
// if there is some message to remove
for (String s : msgsRemover) {
if (lb.getText().toString().equals(s)) {
// remove the visual label
MyPanel.this.remove(lb);
MyPanel.this.repaint();
// remove the message that need to be removed from the linked list
msgsRemover.remove(s);
// remove the label from the JLabel list
labels.remove(lb);
} else {
// if there is no message to be removed, they will just continue
// going to the end of the queue
MyPanel.this.remove(lb);
MyPanel.this.add(lb);
MyPanel.this.repaint();
MyPanel.this.validate();
}
}
}
}
lb.setLocation(lb.getLocation().x - 3, 0);
}
repaint();
try {
SwingUtilities.invokeAndWait(running);
sleep(30);
} catch (InterruptedException ex) {
Logger.getLogger(MyPanel.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(MyPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
};
t.start();
}
这是我收到错误的代码,有时程序崩溃以及它所说的问题所在:
for (JLabel lb : labels)
堆栈跟踪:
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:953)
at java.util.LinkedList$ListItr.next(LinkedList.java:886)
at smstest.MyPanel$3.run(MyPanel.java:110)
所以,我使用了一个迭代器并且它正在工作,但现在我面临另一个问题......有代码:
for(Iterator<String> it2 = msgsRemover.iterator(); it.hasNext();){
String s = it2.next();
if (lb.getText().toString().equals(s)) {
// remove the visual label
MyPanel.this.remove(lb);
MyPanel.this.repaint();
// remove the message that need to be removed from the linked list
it2.remove();
// remove the label from the JLabel list
it.remove();
所以,现在我的问题在于 String s = it2.next(); 堆栈跟踪是:
Exception in thread "Thread-2" java.util.NoSuchElementException
at java.util.LinkedList$ListItr.next(LinkedList.java:888)
at smstest.MyPanel$3.run(MyPanel.java:131)
任何线索我该如何解决?先感谢您