1
votes

Assignation de variable While Loop à Runnable

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());
        }
    });

}

}


0 commentaires

3 Réponses :


0
votes

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);
        }
    });


3 commentaires

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.



0
votes

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());
        }
    });
}


0 commentaires

0
votes

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 ...).


0 commentaires