J'ai créé une calculatrice très simpel à des fins d'apprentissage où je veux qu'un "annonceur" annonce le résultat de l'opération dans un JTextArea. Le but de ce programme est d'utiliser les choses que nous avons apprises à l'université. J'ai une propre classe d'annonce qui implémente runnable et synchronise mon objet calc et c'est supposé ajouter le résultat mais rien ne se passe.La synchronisation ne fonctionne pas
Le programme fonctionne bien donc j'ai dépouillé le code pour les parties pertinentes:
La méthode d'exécution dans la classe annonceur:
public void run()
{
calc.getAnnouncementJTF().append("Announcer thread has been initialized...\n");
calc.getAnnouncementJTF().append("Hi. My name is " + this.getName() + " and my purpose is to " +
"announce the results of your operations as soon as they are ready. \r\n");
while(true){
synchronized(calc){
try
{
calc.wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
calc.getAnnouncementJTF().append(String.valueOf(calc.getResult() + "\n"));
}
}
Et est ici le conditionnel qui effectuera le calcul et informer tous les objets en attente:
else if(e.getSource() == sumButton && Numbers.size() != 0)
{
if(!actualNumber.getText().equals("")){
Numbers.add(new Double(actualNumber.getText()));
addToResults = previousNumbers.getText() + " " + actualNumber.getText();
} else {
addToResults = previousNumbers.getText().substring(0, previousNumbers.getText().length() - 2);
}
currentResult = performCalculation(Numbers, Operators);
previousCalcs.append(addToResults + " = " + String.valueOf(currentResult) + "\r\n");
// Clear both lists and add the result to a cleared
// list for further calculation on it.
Operators.clear();
Numbers.clear();
actualNumber.setText(String.valueOf(currentResult));
previousNumbers.setText("");
resultExist = true;
synchronized(this){
notifyAll();
}
}
méthode principale
public static void main(String[] args){
Announcer announcer = new Announcer();
Calculator calc = new Calculator(announcer);
calc.setTitle("Calculator");
calc.setSize(360, 900);
calc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
calc.setLocationRelativeTo(null);
calc.setVisible(true);
calc.setResizable(false);
announcer.setCalculator(calc); announcer.setName("Sam");
announcer.setAge(28); announcer.setLength(182.5);
Thread announcerThread = new Thread(announcer);
announcerThread.start();
}
Comme je l'ai mentionné avant le code fonctionne bien. Le seul problème que j'ai est que cette partie de la méthode d'exécution en classe annonceur est pas exécuté:
calc.getAnnouncementJTF().append(String.valueOf(calc.getResult() + "\n"));
Vous avez des problèmes de synchronisation dans votre classe, mais vous avez également un gros problème de Swing: les composants Swing ne sont pas accessibles à partir d'un thread autre que l'EDT. Lisez http://docs.oracle.com/javase/tutorial/uiswing/concurrency/ –
Déplacez 'calc.getAnnouncementJTF(). Append()' dans le bloc 'synchronized'. Et, comme @JBNizet l'a déclaré, nous 'SwingUtilities.invokeAndWait()' pour mettre à jour le texte en dehors de l'EDT. Où est appelée la "condition"? – Matthieu