jadex.rules.tools.reteviewer.RetePanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-rules-tools Show documentation
Show all versions of jadex-rules-tools Show documentation
The Jadex rules tools package contains tools for the Jadex rule engine.
package jadex.rules.tools.reteviewer;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.functors.ConstantTransformer;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.GraphMouseListener;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.EdgeShape;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import jadex.commons.ChangeEvent;
import jadex.commons.IBreakpointPanel;
import jadex.commons.IChangeListener;
import jadex.commons.ICommand;
import jadex.commons.ISteppable;
import jadex.rules.rulesystem.Activation;
import jadex.rules.rulesystem.IAgendaListener;
import jadex.rules.rulesystem.IRule;
import jadex.rules.rulesystem.RuleSystem;
import jadex.rules.rulesystem.rete.RetePatternMatcherFunctionality;
import jadex.rules.rulesystem.rete.RetePatternMatcherState;
import jadex.rules.rulesystem.rete.nodes.AlphaNode;
import jadex.rules.rulesystem.rete.nodes.BetaNode;
import jadex.rules.rulesystem.rete.nodes.INode;
import jadex.rules.rulesystem.rete.nodes.IObjectConsumerNode;
import jadex.rules.rulesystem.rete.nodes.IObjectSourceNode;
import jadex.rules.rulesystem.rete.nodes.ITupleConsumerNode;
import jadex.rules.rulesystem.rete.nodes.ITupleSourceNode;
import jadex.rules.rulesystem.rete.nodes.InitialFactNode;
import jadex.rules.rulesystem.rete.nodes.LeftInputAdapterNode;
import jadex.rules.rulesystem.rete.nodes.NotNode;
import jadex.rules.rulesystem.rete.nodes.ReteMemory;
import jadex.rules.rulesystem.rete.nodes.ReteNode;
import jadex.rules.rulesystem.rete.nodes.RightInputAdapterNode;
import jadex.rules.rulesystem.rete.nodes.SplitNode;
import jadex.rules.rulesystem.rete.nodes.TerminalNode;
import jadex.rules.rulesystem.rete.nodes.TestNode;
import jadex.rules.rulesystem.rete.nodes.TypeNode;
/**
* Can be used to visualize a rete network.
*/
public class RetePanel extends JPanel
{
//-------- constants --------
/** The name of the node details panel. */
public static final String NODE_DETAILS_NAME = "Node Details";
/** The name of the agenda panel. */
public static final String AGENDA_NAME = "Agenda";
//-------- attributes --------
/** Flag if node text should be shown. */
protected boolean showtxt;
/** The rulebase panel. */
protected IBreakpointPanel rulebasepanel;
/** The agenda panel. */
protected AgendaPanel ap;
/** The info panels on the right hand side. */
protected JTabbedPane infopanels;
/** The currently removed nodes and edges. */
protected List remnodes;
protected List remedges;
/** The graph. */
protected DirectedSparseGraph g;
/** The viewer. */
protected VisualizationViewer vv;
/** The layout. */
protected ReteLayout layout;
/** The agenda listener. */
protected IAgendaListener agendalistener;
/** The rule system. */
protected RuleSystem system;
//-------- constructors --------
/**
* Create a new rete panel.
* Set steppable to null for panel without breakpoints and step mode.
*/
public RetePanel(final RuleSystem system, final ISteppable steppable, final IBreakpointPanel rulebasepanel)
{
this.rulebasepanel = rulebasepanel;
this.infopanels = new JTabbedPane();
this.system = system;
final ReteNode root = ((RetePatternMatcherFunctionality)system.getMatcherFunctionality()).getReteNode();
final ReteMemory mem = ((RetePatternMatcherState)system.getMatcherState()).getReteMemory();
this.g = new DirectedSparseGraph();
buildGraph(g, root);
hideMarkedNodes(Collections.EMPTY_SET);
final NodePanel np = new NodePanel(null, mem, system.getState());
this.layout = new ReteLayout(g);
this.vv = new VisualizationViewer(layout, new Dimension(600,600));
vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line());
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
vv.getRenderContext().setVertexLabelTransformer(new Transformer()
{
public Object transform(Object arg0)
{
return showtxt? arg0.toString(): null;
}
});
vv.getRenderContext().setVertexStrokeTransformer(new Transformer()
{
public Object transform(Object node)
{
Collection coll = ((INode)node).getNodeMemory(mem);
return (coll==null || coll.isEmpty())
? new BasicStroke(1) : new BasicStroke(2);
}
});
vv.getRenderContext().setVertexFillPaintTransformer(new Transformer()
{
public Object transform(Object node)
{
Color fg;
if(node instanceof ReteNode)
fg = Color.WHITE;
else if(node instanceof TypeNode)
fg = Color.PINK;
else if(node instanceof AlphaNode)
fg = Color.RED;
else if(node instanceof LeftInputAdapterNode)
fg = Color.ORANGE;
else if(node instanceof RightInputAdapterNode)
fg = Color.ORANGE;
else if(node instanceof NotNode)
fg = Color.YELLOW;
else if(node instanceof BetaNode)
fg = Color.GREEN;
else if(node instanceof SplitNode)
fg = Color.MAGENTA;
else if(node instanceof TerminalNode)
fg = Color.CYAN;
else if(node instanceof TestNode)
fg = new Color(0, 255, 100);
else if(node instanceof InitialFactNode)
fg = new Color(255, 100, 0);
else
fg = Color.GRAY;
return fg;
// Collection coll = ((INode)node).getNodeMemory(mem);
// return (coll==null || coll.isEmpty())
// ? fg : new LinearGradientPaint(0,0, 5,5, new float[]{0.8f, 1f}, new Color[]{fg,Color.BLACK});
}
});
vv.getRenderContext().setEdgeDrawPaintTransformer(new Transformer()
{
public Object transform(Object edge)
{
if(edge instanceof ReteEdge)
{
if(((ReteEdge)edge).isTuple())
{
return Color.GREEN;
}
else
{
return Color.RED;
}
}
else
{
return Color.GRAY;
}
}
});
vv.setVertexToolTipTransformer(new ToStringLabeller());
vv.getRenderContext().setArrowFillPaintTransformer(new ConstantTransformer(Color.lightGray));
DefaultModalGraphMouse gm = new DefaultModalGraphMouse();
gm.setMode(ModalGraphMouse.Mode.PICKING);
vv.setGraphMouse(gm);
vv.addGraphMouseListener(new GraphMouseListener()
{
public void graphClicked(Object arg0, MouseEvent arg1)
{
//System.out.println("clicked: "+arg0+" "+arg1);
if(arg0 instanceof INode)
{
np.setNode((INode)arg0);
infopanels.setSelectedComponent(getInfoPanel(NODE_DETAILS_NAME));
}
}
public void graphPressed(Object arg0, MouseEvent arg1)
{
// System.out.println("pressed: "+arg0+" "+arg1);
}
public void graphReleased(Object arg0, MouseEvent arg1)
{
// System.out.println("released: "+arg0+" "+arg1);
}
});
final JButton hidenodes = new JButton("Show Subgraph");
hidenodes.setMargin(new Insets(2,4,2,4));
hidenodes.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
Set subgraph = new HashSet(vv.getPickedVertexState().getPicked());
hideMarkedNodes(subgraph);
layout.graphChanged();
vv.repaint();
}
});
/*final JButton showdesc = new JButton("Show text");
showdesc.setMargin(new Insets(0,0,0,0));
showdesc.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
showtxt = !showtxt;
vv.repaint();
showdesc.setText(showtxt? "Hide text": "Show text");
}
});*/
JButton refresh = new JButton("Refresh");
// refresh.setMargin(new Insets(0,0,0,0));
refresh.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
np.refresh();
vv.repaint();
}
});
// JButton remrule = new JButton("Remove rule");
// remrule.setMargin(new Insets(0,0,0,0));
/*remrule.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
Set subgraph = new HashSet(vv.getPickedVertexState().getPicked());
if(subgraph.isEmpty())
{
System.out.println("Please select a terminal node(s) first.");
}
else
{
for(Iterator it=subgraph.iterator(); it.hasNext(); )
{
INode node = (INode)it.next();
if(node instanceof TerminalNode)
{
TerminalNode tn = (TerminalNode)node;
root.removeRule(tn.getRule());
buildGraph(g, root);
}
}
vv.repaint();
}
}
});*/
int mw = (int)hidenodes.getMinimumSize().getWidth();
int pw = (int)hidenodes.getPreferredSize().getWidth();
int mh = (int)hidenodes.getMinimumSize().getHeight();
int ph = (int)hidenodes.getPreferredSize().getHeight();
hidenodes.setMinimumSize(new Dimension(mw, mh));
hidenodes.setPreferredSize(new Dimension(pw, ph));
// showdesc.setMinimumSize(new Dimension(mw, mh));
// showdesc.setPreferredSize(new Dimension(pw, ph));
refresh.setMinimumSize(new Dimension(mw, mh));
refresh.setPreferredSize(new Dimension(pw, ph));
// remrule.setMinimumSize(new Dimension(mw, mh));
// remrule.setPreferredSize(new Dimension(pw, ph));
JPanel buts = new JPanel(new GridBagLayout());
// buts.setBorder(BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(
// BevelBorder.LOWERED), "Node Settings"));
buts.add(hidenodes, new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.EAST,
GridBagConstraints.NONE,new Insets(2,4,4,2),0,0));
// buts.add(showdesc, new GridBagConstraints(1,0,1,1,0,0,GridBagConstraints.EAST,
// GridBagConstraints.NONE,new Insets(2,4,4,2),0,0));
buts.add(refresh, new GridBagConstraints(0,1,1,1,1,0,GridBagConstraints.EAST,
GridBagConstraints.NONE,new Insets(2,4,4,2),0,0));
// buts.add(remrule, new GridBagConstraints(0,3,1,1,0,0,GridBagConstraints.EAST,
// GridBagConstraints.NONE,new Insets(2,4,4,2),0,0));
JPanel tmp = new JPanel(new BorderLayout());
tmp.add(np, BorderLayout.CENTER);
tmp.add(buts, BorderLayout.SOUTH);
this.ap = new AgendaPanel(system.getAgenda());
JPanel tmp3 = new JPanel(new BorderLayout());
final JCheckBox followact = new JCheckBox("Follow activation", true);
followact.setToolTipText("Follow the selected activation by displaying the rule.");
tmp3.add(ap, BorderLayout.CENTER);
// tmp3.add(followact, BorderLayout.SOUTH);
// The step action
final JButton step = new JButton("Step");
if(steppable!=null)
{
JPanel tmp4 = new JPanel(new GridBagLayout());
step.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
steppable.doStep();
}
});
step.setEnabled(steppable.isStepmode() && !system.getAgenda().isEmpty());
final JCheckBox stepmode = new JCheckBox("Step Mode", steppable.isStepmode());
stepmode.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
steppable.setStepmode(stepmode.isSelected());
step.setEnabled(steppable.isStepmode() && !system.getAgenda().isEmpty());
}
});
steppable.addBreakpointCommand(new ICommand()
{
public void execute(Object args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
stepmode.setSelected(steppable.isStepmode());
step.setEnabled(steppable.isStepmode() && !system.getAgenda().isEmpty());
}
});
}
});
int row = 0;
int col = 0;
tmp4.add(followact, new GridBagConstraints(col, row++, 2, 1,
1,0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(1,1,1,1), 0,0));
tmp4.add(stepmode, new GridBagConstraints(col++, row, 1, 1,
1,0, GridBagConstraints.LINE_END, GridBagConstraints.NONE, new Insets(1,1,1,1), 0,0));
tmp4.add(step, new GridBagConstraints(col, row++, GridBagConstraints.REMAINDER, 1,
0,0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(1,1,1,1), 0,0));
tmp3.add(tmp4, BorderLayout.SOUTH);
}
addInfoPanel(NODE_DETAILS_NAME, tmp);
addInfoPanel(AGENDA_NAME, tmp3);
JSplitPane sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
sp2.setOneTouchExpandable(true);
sp2.setResizeWeight(1);
sp2.setDividerLocation(500);
sp2.add(vv);
sp2.add(infopanels);
this.setLayout(new BorderLayout());
this.add(sp2, BorderLayout.CENTER);
vv.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent e)
{
layout.setSize(vv.getSize());
}
});
rulebasepanel.addBreakpointListener(new IChangeListener()
{
public void changeOccurred(ChangeEvent e)
{
String[] rules = (String[])rulebasepanel.getSelectedBreakpoints();
// System.out.println("Selected: "+SUtil.arrayToString(rules)+" "+e);
if(rules!=null && rules.length>0)
{
// Show all nodes
if(remnodes!=null)
showHiddenNodes();
// Build subgraph of selected rules (terminal nodes).
Set subgraph = new HashSet();
for(int i=0; i
© 2015 - 2024 Weber Informatics LLC | Privacy Policy