私は を持っていて、LinkedList<JLabel>
それをスレッドで使用して に追加または削除しますJPanel
。問題は、例外が発生してアプリケーションがクラッシュすることがあるということです。リストの同期について話している投稿もあれば、イテレータが必要だと言う人もいるので、少し混乱しています。
理解しやすくするためにいくつかのコードを追加します。
public class MyPanel extends JPanel {
(...)
private LinkedList<JLabel> labels;
(...)
public MyPanel(Color corLabel, Color back, Font text) {
(...)
labels = new LinkedList<>();
(...)
}
これは、Linked List が初期化される場所です。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)
どうすれば解決できますか?前もって感謝します