Pourquoi chaque exécutable imprime-t-il le même périphérique alors que chacun est censé se voir attribuer un périphérique différent?
Il semble que chaque Runnable utilise le dernier périphérique attribué à partir de la boucle while. Comment puis-je m'assurer que chaque Runnable se voit attribuer un périphérique de la boucle?
public abstract class ProtocolInterface<N> implements Callable<ReturnInterface<N>>, Serializable{ protected DefaultDevice device; protected String name = ""; protected Task task; protected Date scheduledDate; protected ReturnInterface<N> returnInterface; final private CredentialInterface credential = new CredentialInterface() { private String user = ""; private String password = ""; private int port = 22; @Override public String getUser() { return user; } @Override public String getPassword() { return password; } @Override public int getPort() { return port; } @Override public void setUser(String s) { user = s; } @Override public void setPassword(String s) { password = s; } @Override public void setPort(int p) { port = p; } @Override public DefaultDevice getHost() { return device; } @Override public void setHost(DefaultDevice host) { System.out.println("[ProtocolInterface].CredentialInterface.setHost() host= "+host); device = host; } }; boolean useIP = true; public ProtocolInterface() { } public CredentialInterface getCredential() { return credential; } public ProtocolInterface(String name, DefaultDevice device) { this.name = name; this.device = device; } public DefaultDevice getDevice() { return device; } public ReturnInterface<N> getReturnInterface() { return returnInterface; } public void setReturnInterface(ReturnInterface<N> returnInterface) { this.returnInterface = returnInterface; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Task getTask() { return task; } public void setTask(Task task) { this.task = task; } public Date getScheduledDate() { return scheduledDate; } public void setScheduledDate(Date scheduledDate) { this.scheduledDate = scheduledDate; } public abstract Icon getIcon(); public abstract CredentialForm_Interface getCredentialForm(); @Override public int hashCode() { int hash = 7; hash = 47 * hash + Objects.hashCode(this.device); hash = 47 * hash + Objects.hashCode(this.name); return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ProtocolInterface<?> other = (ProtocolInterface<?>) obj; if (this.useIP != other.useIP) { return false; } if (!Objects.equals(this.name, other.name)) { return false; } if (!Objects.equals(this.device, other.device)) { return false; } if (!Objects.equals(this.credential, other.credential)) { return false; } return true; } @Override public String toString() { return name; }
Voici le code d'interface de protocole demandé par wsa.
Iterator<TaskCard> i = taskManager.getTaskCards().iterator(); while (i.hasNext()) { TaskCard taskCard = i.next(); taskCard.updateTask(); ReturnInterface<String> returnInterface = new TaskReturnIterface(taskManager, taskCard); Task task = taskCard.getTask(); ProtocolInterface selectedProtocol = task.getDevice().getSelectedProtocol(); selectedProtocol.setTask(task); selectedProtocol.setReturnInterface(returnInterface); SwingUtilities.invokeLater(new Runnable() { final ProtocolInterface mySelectedProtocol=selectedProtocol; @Override public void run() { System.out.println("[Taskmanager.TaskReturnInterface.actionPerformed.RUN()]selectedProtocol device= " + mySelectedProtocol.getDevice()); } }); }
}
3 Réponses :
Oui, vous avez raison! Vous créez une instance Runnable
en référence à l'objet protocole. Cette référence peut être modifiée jusqu'à ce que invokeLater
exécute cette tâche. Vous devez donc copier les données requises au lieu de sauvegarder la référence.
SwingUtilities.invokeLater(new Runnable() { final Device device = selectedProtocol.getDevice(); @Override public void run() { System.out.println("[Taskmanager.TaskReturnInterface.actionPerformed.RUN()]selectedProtocol device= " + device); } });
la sortie est toujours la même.
@JamieSnipes pouvez-vous fournir des sources de classe Device
et SelectedProtocol
?
Je suppose que puisque selectedProtocol change également, cela pourrait expliquer pourquoi il imprime toujours le même périphérique.
Essayez ceci:
Iterator<TaskCard> i = taskManager.getTaskCards().iterator(); while (i.hasNext()) { TaskCard taskCard = i.next(); taskCard.updateTask(); ReturnInterface<String> returnInterface = new TaskReturnIterface(taskManager, taskCard); Task task = taskCard.getTask(); final ProtocolInterface selectedProtocol = task.getDevice().getSelectedProtocol(); selectedProtocol.setTask(task); selectedProtocol.setReturnInterface(returnInterface); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { System.out.println("[Taskmanager.TaskReturnInterface.actionPerformed.RUN()]selectedProtocol device= " + selectedProtocol.getDevice()); } }); }
C'est difficile à dire sans plus d'informations sur la TaskCard
et d'autres objets mais vous devriez essayer de déclarer une variable final
et essayer d'imprimer le code de hachage de l'objet, pour vérifier s'il s'agit vraiment de la même instance ou de différentes instances sémantiquement égales:
ProtocolInterface selectedProtocol = task.getDevice().getSelectedProtocol(); selectedProtocol.setTask(task); selectedProtocol.setReturnInterface(returnInterface);
Il semblerait qu'il y ait des liens entre les objets qui pourraient soit imprimer la même sortie, soit utilisez le même objet dans le backend. Surtout cette partie:
for (Iterator<TaskCard> i = taskManager.getTaskCards().iterator(); i.hasNext();) { TaskCard taskCard = i.next(); taskCard.updateTask(); ReturnInterface<String> returnInterface = new TaskReturnIterface(taskManager, taskCard); Task task = taskCard.getTask(); // Mark this as "final" so you can use it as is in any internal anonymous class: final ProtocolInterface selectedProtocol = task.getDevice().getSelectedProtocol(); selectedProtocol.setTask(task); selectedProtocol.setReturnInterface(returnInterface); System.out.println("[1] selectedProtocol device=" + selectedProtocol.getDevice().hashCode()); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { System.out.println("[2] selectedProtocol device=" + selectedProtocol.getDevice().hashCode()); } }); }
semble étrange car le selectedProtocol
semble en quelque sorte lié à un appareil lui-même lié à une tâche, alors vous devez définir sa tâche encore une fois?
Il s'agit essentiellement de faire task.getDevice (). getSelectedProtocol (). setTask (tâche)
qui ressemble à une sorte d'échappatoire que vous devriez vérifier ...
De plus, SwingUtilities.invokeLater ()
est en quelque sorte réservé au traitement de l'interface graphique, vous voudrez peut-être le supprimer (à moins qu'il ne fasse de l'interface graphique ...).