Java JADE-ContractNet与GUI问题
我在使用ContractNet(交互协议)和GUI(使用JADE Multi-Agent framework)时遇到一些问题 特别是,在重写handlePropose方法时。 我知道我的问题来自GUI的使用。让我解释一下: 我的代理(启动器)使用第一个GUI,单击后 对话从第二个代理(响应者)开始。根据 协议,发起方因此向响应方发送了CFP。代理人 响应者使用包含不同数据的建议进行响应 从这里开始,一切都很好。现在 我希望代理发起人在返回答复之前可以检查 数据。。。ie发布在JTable上,供用户使用!用户将 通过GUI检查提案,并通过 点击一个按钮Java JADE-ContractNet与GUI问题,java,user-interface,actionlistener,agents-jade,multi-agent,Java,User Interface,Actionlistener,Agents Jade,Multi Agent,我在使用ContractNet(交互协议)和GUI(使用JADE Multi-Agent framework)时遇到一些问题 特别是,在重写handlePropose方法时。 我知道我的问题来自GUI的使用。让我解释一下: 我的代理(启动器)使用第一个GUI,单击后 对话从第二个代理(响应者)开始。根据 协议,发起方因此向响应方发送了CFP。代理人 响应者使用包含不同数据的建议进行响应 从这里开始,一切都很好。现在 我希望代理发起人在返回答复之前可以检查 数据。。。ie发布在JTable上,供用
- 如果接受,发起人将发送接受建议
- 如果不接受,发起人将发送拒绝建议
@Override
protected void handlePropose(final ACLMessage propose, final Vector acceptances) {
try {
System.out.println("Agent "+getLocalName()
+": receive PROPOSE from "+propose.getSender().getLocalName());
final ACLMessage reply = propose.createReply();
Vector<Goods> goods = (Vector<Goods>) propose.getContentObject();
// the JTable's GUI for visualize the list of data:
final GoodsChoiceBox gcb = new GoodsChoiceBox(propose.getSender().getName(), goods);
// the problem:
gcb.getExecuteJButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
reply.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
System.out.println("Agent "+getLocalName()+": send ACCEPT PROPOSAL ");
acceptances.addElement(reply);
}
});
// similar case, but for REJECT:
// gcb.getAbortJButton().addActionListener(... bla bla
gcb.setVisible(true);
} catch (UnreadableException e){
e.printStackTrace();
}
}
@覆盖
受保护的无效处理建议(最终消息建议、最终向量接受){
试一试{
System.out.println(“代理”+getLocalName()
+“:从“+PROPOSE.getSender().getLocalName())接收提议;
final ACLMessage reply=propose.createReply();
Vector商品=(Vector)propose.getContentObject();
//用于可视化数据列表的JTable GUI:
最终GoodsChoiceBox gcb=新的GoodsChoiceBox(propose.getSender().getName(),货物);
//问题是:
gcb.getExecuteJButton().addActionListener(新ActionListener()){
@凌驾
已执行的公共无效操作(操作事件e){
回复.setPerformative(ACLMessage.ACCEPT_提案);
System.out.println(“代理”+getLocalName()+“:发送接受建议”);
接受.补充(答复);
}
});
//类似情况,但对于拒收:
//gcb.getAbortJButton().addActionListener(…bla bla)
gcb.setVisible(真);
}捕获(不可访问的例外e){
e、 printStackTrace();
}
}
……但显然,这不起作用
在启动器代理中,ContractNet行为被中止……因此HandleInfo、handleRefuse和handleFailure(用于处理答案)也不起作用。
启动器的主要GUI被阻止。以及其他问题
相反,如果我这样做(没有JButton,另一个GUI和ActionListener):
@覆盖
受保护的无效处理建议(最终消息建议、最终向量接受){
试一试{
System.out.println(“代理”+getLocalName()
+“:从“+PROPOSE.getSender().getLocalName())”收到提议;
final ACLMessage reply=propose.createReply();
Vector商品=(Vector)propose.getContentObject();
//用于可视化数据列表的JTable GUI:
最终GoodsChoiceBox gcb=新的GoodsChoiceBox(propose.getSender().getName(),货物);
回复.setPerformative(ACLMessage.ACCEPT_提案);
System.out.println(“代理”+getLocalName()+”:接受建议di“+propose.getSender().getLocalName());
接受.补充(答复);
}捕获(不可访问的例外e){
e、 printStackTrace();
}
}
..有效
我知道问题在于ActionListener及其多线程特性。
但是我需要图形用户界面
如何修复?我经常遇到此类问题。这些是有限状态机行为,因此您应该能够暂停并恢复某个行为,但我不确定如何修复。我所做的是在发起方和响应方分别创建两个单独的交互行为
Initiator Responder
| |
| |
| First behaviour |The responder only has 1 behaviour
|| CFP-> ||
|| <-Proposal ||
| ||
| Second behaviour ||
|| Accept prop-> ||
|| <-Response ||
| |
从第一个行为开始,并在第二个行为中使用它
msg.setConversationID().
(二)
第二种行为是另一个合同网发起人,但在prepareCFPs方法中,将MESSAGE performative设置为接受建议
类ContractServiceList扩展ContractNetInitiator
{
这些事情很难解释,所以我试着附上一张照片,但有两个小的代表点
我现在有足够的代表点来附上我正在做的图片
我刚刚意识到这个问题还有另一个解决方案。第二个解决方案涉及使用ChildBehavior和数据存储。可以在暂停父行为时启动子行为。在子行为完成后,必须恢复父行为 我附上一张照片,以更好地解释这种互动 因此,在您的CNI(ContractNetInitiator)家长行为中的A点,您希望启动孩子行为。您可以使用CNI.registerHandlePropose(new ChildBehavior)来实现这一点 setup()方法应该是这样的:
protected void setup()
{
ContractNetInitiator parentBehave= new ContractNetInitiator (null, null, GlobDataStore);
ContractNetInitiator.registerHandlePropose(new ChildBehavoiur (GlobDataStore));
addBehaviour(CNI);
}
在您的子行为中,您必须检查来自父级(GlobDataStore)的数据,并返回要传回的消息。要遵循的代码:
class ChildBehaviour extends OneShotBehaviour{
@Override
public void action() {
//evaluate globalestore here;
ACLMessage CNIresponse=new ACLMessage();
if(true)
{
storeNotification(ACLMessage.ACCEPT_PROPOSAL, CNIresponse);
}
else
{
storeNotification(ACLMessage.REJECT_PROPOSAL, CNIresponse);
}
}
public void storeNotification(int performative, ACLMessage original)
{
// Retrieve the incoming request from the DataStore
String incomingCFPkey = (String) ((ContractNetResponder) parent).CFP_KEY;
incomingCFPkey = (String) ((ContractNetResponder) parent).CFP_KEY;
ACLMessage incomingCFP = (ACLMessage) getDataStore().get(incomingCFPkey);
// Prepare the notification to the request originator and store it in the DataStore
ACLMessage notification = incomingCFP.createReply();
notification.setPerformative(performative);
notification.setContent(original.getContent());
String notificationkey = (String) ((ContractNetResponder) parent).PROPOSE_KEY;
getDataStore().put(notificationkey, notification);
}
}
我试着回答自己。我不确定这是最好的解决方案,但肯定有效 请注意,在使用此解决方案之前,我已详细记录了(上)提供的指南和教程,并与其他人进行了交流 JADE开发者(邮件列表中) 答案很复杂,所以我会尽量详尽 在我的项目中,我必须处理两种不同类型的代理
- ShipperAgent,代表一个托运人:它跟踪托运人拥有的车辆、可用的车辆以及“保留”的货物
- BuyerAgent,代表客户(或买家):每个客户都有一个要从a点移动到B点的商品列表
protected Vector prepareCfps(ACLMessage cfp) {
ACLmessage AP= new ACLmessage(ACLmessage.ACCEPT_PROPOSAL)
.....
protected void setup()
{
ContractNetInitiator parentBehave= new ContractNetInitiator (null, null, GlobDataStore);
ContractNetInitiator.registerHandlePropose(new ChildBehavoiur (GlobDataStore));
addBehaviour(CNI);
}
class ChildBehaviour extends OneShotBehaviour{
@Override
public void action() {
//evaluate globalestore here;
ACLMessage CNIresponse=new ACLMessage();
if(true)
{
storeNotification(ACLMessage.ACCEPT_PROPOSAL, CNIresponse);
}
else
{
storeNotification(ACLMessage.REJECT_PROPOSAL, CNIresponse);
}
}
public void storeNotification(int performative, ACLMessage original)
{
// Retrieve the incoming request from the DataStore
String incomingCFPkey = (String) ((ContractNetResponder) parent).CFP_KEY;
incomingCFPkey = (String) ((ContractNetResponder) parent).CFP_KEY;
ACLMessage incomingCFP = (ACLMessage) getDataStore().get(incomingCFPkey);
// Prepare the notification to the request originator and store it in the DataStore
ACLMessage notification = incomingCFP.createReply();
notification.setPerformative(performative);
notification.setContent(original.getContent());
String notificationkey = (String) ((ContractNetResponder) parent).PROPOSE_KEY;
getDataStore().put(notificationkey, notification);
}
}
/*
* ...
*/
final MessageTemplate template = MessageTemplate.and(
MessageTemplate.MatchProtocol(FIPANames.InteractionProtocol.FIPA_CONTRACT_NET),
MessageTemplate.MatchPerformative(ACLMessage.CFP) );
// SSResponderDispatcher:
SSResponderDispatcher dispatcher = new SSResponderDispatcher(this, template) {
BuyerAgent b = (BuyerAgent) this.myAgent;
protected Behaviour createResponder(ACLMessage initiationMsg) {
// SearchJobResponder for single cfp:
return new SearchJobResponder(b, initiationMsg);
}
};
addBehaviour(dispatcher);
/*
* ...
*/
/*
* ...
*/
ACLMessage cfp = new ACLMessage(ACLMessage.CFP);
AID[] buyerAgents = searchBuyers(); // search all buyerAgents
for (AID buyer : buyerAgents)
cfp.addReceiver(buyer);
addBehaviour(new SearchJobInitiator(this, cfp));
/*
* ...
*/
/*
* ...
*/
public class SearchJobInitiator extends ContractNetInitiator {
ShipperAgent shipperAgent;
public SearchJobInitiator(ShipperAgent a, ACLMessage cfp) {
super(a, cfp);
shipperAgent=a;
// Very important:
registerHandleAllResponses(new HandleProposes());
}
@Override
protected Vector<?> prepareCfps(ACLMessage cfp) {
long now = System.currentTimeMillis();
cfp.setConversationId("contractNet-by-"
+shipperAgent.getAID().getLocalName()+now);
cfp.setContent("Fammi delle proposte di lavoro");
/*
* filtering...
*/
cfp.setProtocol(FIPANames.InteractionProtocol.FIPA_CONTRACT_NET);
cfp.setReplyByDate(new Date(now+10000));
//cfp.setReplyWith("cfp"+System.currentTimeMillis()) //useless, is overwrited at the end
return super.prepareCfps(cfp);
}
//inner class for handling a single proposal
public class HandleProposes extends Behaviour {
private static final long serialVersionUID = 1L;
private Vector<ACLMessage> proposes;
private Vector<ACLMessage> acceptances;
private int numberOfProposes;
public void onStart() {
proposes = (Vector<ACLMessage>) getDataStore().get(ALL_RESPONSES_KEY);
acceptances = (Vector<ACLMessage>) getDataStore().get(ALL_ACCEPTANCES_KEY);
numberOfProposes=proposes.size();
for (Iterator I=proposes.iterator(); I.hasNext();) {
ACLMessage propose = (ACLMessage) I.next();
// Very important:
if (propose.getPerformative()==ACLMessage.PROPOSE)
myAgent.addBehaviour(new HandleSinglePropose(propose, acceptances));
else
numberOfProposes--;
}
}
public void action() {
if (!done())
block();
}
public boolean done() {
return (acceptances.size()==numberOfProposes);
}
/*
* Inner class for handle a single proposal and display it:
*/
public class HandleSinglePropose extends Behaviour {
private ACLMessage propose;
private Vector<ACLMessage> acceptances;
private boolean finish=false;
public HandleSinglePropose (ACLMessage propose, Vector<ACLMessage> acceptances) {
this.propose=propose;
this.acceptances=acceptances;
// This is GUI in 3.1 point
GoodsChoiceBox gcb = new GoodsChoiceBox(shipperAgent, this, propose); // fill the JTable
gcb.setVisible(true);
}
@Override
public void action() {
MessageTemplate mt = MessageTemplate.and(
MessageTemplate.MatchSender(shipperAgent.getAID()),
MessageTemplate.and(
MessageTemplate.MatchReplyWith("response"+propose.getReplyWith()),
MessageTemplate.or(
MessageTemplate.MatchPerformative(ACLMessage.ACCEPT_PROPOSAL),
MessageTemplate.MatchPerformative(ACLMessage.REJECT_PROPOSAL)
) ) ) ;
// Read data from GUI. The user accept or reject:
ACLMessage decisionFromGUI = shipperAgent.receive(mt);
if (decisionFromGUI != null) {
ACLMessage reply = propose.createReply();
// bla bla...
finish=true;
HandleProposes.this.restart();
} else {
block();
}
}
public boolean done() {
return finish;
}
public void handleChoice(ACLMessage propose, boolean bool, Vector<Goods> selectedGoods) {
ACLMessage reply;
if (bool){
reply = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL);
//...
} else {
reply = new ACLMessage(ACLMessage.REJECT_PROPOSAL);
//...
}
reply.addReceiver(shipperAgent.getAID());
reply.setReplyWith("response"+propose.getReplyWith());
shipperAgent.send(reply);
}
} // closes HandleSinglePropose
} // closes HandleProposes
}
public class SearchJobResponder extends SSContractNetResponder {
BuyerAgent buyerAgent;
public SearchJobResponder(BuyerAgent a, ACLMessage cfp) {
super(a, cfp);
buyerAgent = a;
}
/*
* override methods...
*/
}
public GoodsChoiceBox(final Agent agent, final HandleSinglePropose behaviour, final ACLMessage propose){
/*
* graphics stuff
*/
// if goods selected and press Execute
behaviour.handleChoice(propose,true,selectedGoods);
//else
behaviour.handleChoice(propose,false,null);
/*
* bla bla
*/
}