package agg.gui.cpa;
import java.awt.Container;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.event.MouseEvent;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.ScrollPaneConstants;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;
import javax.swing.border.MatteBorder;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.PopupMenuListener;
import javax.swing.event.PopupMenuEvent;
import agg.gui.parser.event.ParserGUIEvent;
import agg.gui.parser.event.ParserGUIListener;
import agg.gui.parser.event.CPAEventData;
import agg.parser.CriticalPairData;
import agg.parser.CriticalPairEvent;
import agg.parser.CriticalPair;
import agg.parser.DependencyPairContainer;
import agg.parser.ExcludePairContainer;
import agg.parser.ParserEvent;
import agg.parser.ParserEventListener;
import agg.xt_basis.OrdinaryMorphism;
import agg.xt_basis.Rule;
import agg.util.Pair;
/**
* Shows a table with a row and a column for each rule, so that each element
* stands for a pair of rules. The color of the pairs shows the state of them
* (critic, non-critic, unchecked).
*
* @version $Id: CriticalPairPanel.java,v 1.17 2010/12/21 16:34:01 olga Exp $
* @author $Author: olga $
*/
@SuppressWarnings("serial")
public class CriticalPairPanel extends JPanel implements ActionListener,
ParserEventListener, ItemListener, PopupMenuListener {
static final Font bfont = new Font("Helvetica-Bold", Font.BOLD, 14);
/** the color for untested pairs */
static final Color NOT_SET = Color.white;
/** the color for pairs which will be checked soon */
static final Color SCHEDULED = Color.gray;
/** the color for pairs which are checked at the moment */
// static final Color COMPUTING = Color.yellow;
static final Color COMPUTING = new Color(255, 255, 160);
/** the color for critic pairs */
// static final Color CRITIC = Color.red;
// static final Color CRITIC = new Color(255, 210, 160);
static final Color CRITIC = new Color(255, 204, 204);
/** the color for critic pairs */
// static final Color DEPEND = Color.blue;
// static final Color DEPEND = new Color(155, 205, 255);
static final Color DEPEND = new Color(204, 204, 255);
static final Color DEPEND2 = Color.cyan;
/** the color for non-critic pairs */
// static final Color NOT_CRITIC = Color.green;
// static final Color NOT_CRITIC = new Color(155, 255, 105);
static final Color NOT_CRITIC = new Color(201, 255, 204);
/** the color for disabled rules */
static final Color DISABLED = Color.lightGray;
/** the color for not related rules */
static final Color NOT_RELATED = Color.lightGray;
/** the PairContainer, which is displayed here */
private ExcludePairContainer container;
private Hashtable<JButton,CriticalPairData> b2cpData = new Hashtable<JButton,CriticalPairData>();
// private Hashtable<Graph, Vector<Hashtable<GraphObject, GraphObject>>> computeAndCheckGraph;
private Hashtable<Rule, Hashtable<Rule, JButton>>
buttons = new Hashtable<Rule, Hashtable<Rule, JButton>>();
private Hashtable<JButton, Rule> firstRules = new Hashtable<JButton, Rule>();
private Hashtable<JButton, Rule> secondRules = new Hashtable<JButton, Rule>();
/** the listener for selections in the array */
private Vector<ParserGUIListener> listeners = new Vector<ParserGUIListener>();
private Rule first, second;
private int tableW, tableH;
final private JPopupMenu menu = new JPopupMenu();
private JMenuItem miClear, miContinue, miComputeAndCheck, miVisibleRel, miVisibleRule;
final static private String clearRelation = "Clear";
final static private String continueCompute = "Continue Compute";
final static private String computeAndCheck = "Compute & Check Host Graph";
final static private String hideRelation = "Hide Relation ( in CPA Graph )";
final static private String showRelation = "Show Relation ( in CPA Graph )";
final static private String hideRule = "Hide Rule ( in CPA Graph )";
final static private String showRule = "Show Rule ( in CPA Graph )";
final static private javax.swing.border.Border
border = (new JButton()).getBorder();
int borderWidth = 7;
final private JScrollPane main = new JScrollPane();
MouseInputAdapter ml;
boolean active;
/** constructs a new panel for the given rules */
public CriticalPairPanel(final List<Rule> rules, final ExcludePairContainer container) {
super(new BorderLayout(), true);
makePanel(rules, rules, container);
}
/** constructs a new panel for the given rules1 on horizontal
* and rules2 on vertical of the rule pairs table
*/
public CriticalPairPanel(final List<Rule> rules1, final List<Rule> rules2, final ExcludePairContainer container) {
super(new BorderLayout(), true);
makePanel(rules1, rules2, container);
}
private void makePanel(
final List<Rule> somerules1,
final List<Rule> somerules2,
final ExcludePairContainer cpContainer) {
if (somerules1 == null || somerules1.size() == 0
|| somerules2 == null || somerules2.size() == 0)
return;
// store the container
this.container = cpContainer;
this.container.addPairEventListener(this);
List<Rule> rules = getEnabledRules(somerules1);
List<Rule> rules2 = (somerules1 == somerules2)? rules: getEnabledRules(somerules2);
// the head of the rows
// add all rule names and numbers to the head
int tablesize2 = rules2.size();
final JPanel rowHead = new JPanel();
rowHead.setLayout(new GridLayout(tablesize2, 1));
int nn = 0;
for (int i=0; i<rules2.size(); i++) {
Rule r = rules2.get(i);
if (r.isEnabled()) {
nn++;
String rName = r.getQualifiedName();
String text = String.valueOf(nn) + " " + rName;
JLabel act = new JLabel(text);
act.setToolTipText("first rule " + text);
rowHead.add(act);
}
}
// the head of the columns
// add all rule numbers to the head
int tablesize = rules.size();
final JPanel colHead = new JPanel();
colHead.setLayout(new GridLayout(1, tablesize));
nn = 0;
boolean sameRules = rules.equals(rules2);
for (int i=0; i<rules.size(); i++) {
Rule r = rules.get(i);
if (r.isEnabled()) {
nn++;
String text = " " +String.valueOf(nn);
if (!sameRules) {
String rName = r.getQualifiedName();
text = String.valueOf(nn) + " " + rName;
}
JLabel act = new JLabel(text);
act.setToolTipText("second rule " + text);
colHead.add(act);
}
} // while col
// create the center panel with a button for each rule
final JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(tablesize2, tablesize));
int i = 0;
int ii;
// create button pop-up menu
this.menu.addPopupMenuListener(this);
this.miClear = new JMenuItem(clearRelation);
this.menu.add(this.miClear);
this.miClear.addActionListener(this);
this.miContinue = new JMenuItem(continueCompute);
this.menu.add(this.miContinue);
this.miContinue.addActionListener(this);
this.miComputeAndCheck = this.menu.add(new JMenuItem(computeAndCheck));
this.miComputeAndCheck.addActionListener(this);
if (this.container instanceof DependencyPairContainer)
this.miComputeAndCheck.setEnabled(false);
else
this.miComputeAndCheck.setEnabled(true);
this.menu.addSeparator();
this.miVisibleRel = this.menu.add(new JMenuItem(hideRelation));
this.miVisibleRel.addActionListener(this);
this.miVisibleRule = new JMenuItem(hideRule);
this.miVisibleRule.addActionListener(this);
this.menu.add(this.miVisibleRule);
this.ml = new MouseInputAdapter() {
// public void mousePressed(MouseEvent e) {}
// public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
if (e.getSource() instanceof JButton) {
JButton b = (JButton)e.getSource();
if (b.getBorder() instanceof MatteBorder) {
if (((MatteBorder)b.getBorder()).getMatteColor() == DEPEND2) {
b.setBackground(DEPEND2);
b.setBorder(BorderFactory.createMatteBorder(
CriticalPairPanel.this.borderWidth,
CriticalPairPanel.this.borderWidth,
CriticalPairPanel.this.borderWidth,
CriticalPairPanel.this.borderWidth, DEPEND));
}
}
}
}
public void mouseExited(MouseEvent e) {
if (e.getSource() instanceof JButton) {
JButton b = (JButton)e.getSource();
if (b.getBorder() instanceof MatteBorder) {
if (((MatteBorder)b.getBorder()).getMatteColor() == DEPEND
|| ((MatteBorder)b.getBorder()).getMatteColor() == DEPEND2) {
b.setBackground(DEPEND);
b.setBorder(BorderFactory.createMatteBorder(
CriticalPairPanel.this.borderWidth,
CriticalPairPanel.this.borderWidth,
CriticalPairPanel.this.borderWidth,
CriticalPairPanel.this.borderWidth, DEPEND2));
}
}
}
}
};
addMouseListener(this.ml);
while (i < tablesize2) {
Rule r1 = rules2.get(i);
ii = 0;
while (ii < tablesize) {
Rule r2 = rules.get(ii);
JButton act = new JButton("?");
act.setFont(CriticalPairPanel.bfont);
act.setForeground(Color.black);
act.addMouseListener(this.ml);
act.addActionListener(this);
// set tool tip text
String r1Name = r1.getQualifiedName();
String r2Name = r2.getQualifiedName();
act.setToolTipText(
"[" + r1Name + ", " + r2Name + "]");
act.setMinimumSize(
new Dimension(act.getHeight(), act.getHeight()));
// add popup menu
act.setComponentPopupMenu(this.menu);
addButton(r1, r2, act);
mainPanel.add(act);
refreshView(r1, r2, act, -1);
ii++;
}
i++;
} // while i
// get the preferred size for the center panel
Dimension dim = mainPanel.getPreferredSize();
// calculate minimum/preferred size for column header
Dimension dim2 = new Dimension();
dim2.setSize(dim.getWidth(), colHead.getPreferredSize().getHeight());
// System.out.println("col: "+dim2.getWidth()+" "+dim2.getHeight());
colHead.setMinimumSize(dim2);
colHead.setPreferredSize(dim2);
this.tableW = (int) dim2.getWidth();
// calculate minimum/preferred size for row header
dim2 = new Dimension();
dim2.setSize(rowHead.getPreferredSize().getWidth(), dim.getHeight());
// System.out.println("row: "+dim2.getWidth()+" "+dim2.getHeight());
rowHead.setPreferredSize(dim2);
rowHead.setMinimumSize(dim2);
this.tableH = (int) dim2.getHeight();
// set the main panel to its actual size
mainPanel.setPreferredSize(dim);
mainPanel.setMinimumSize(dim);
// construct JScrollPane
this.main.setRowHeaderView(rowHead);
this.main.setColumnHeaderView(colHead);
this.main.setViewportView(mainPanel);
this.main.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, new JLabel(
" first \\ second"));
// add JScrollPane to this
this.add(this.main, BorderLayout.CENTER);
} // paneTest
private List<Rule> getEnabledRules(List<Rule> rules) {
List<Rule> result = new Vector<Rule>();
for (int i=0; i<rules.size(); i++) {
if (rules.get(i).isEnabled()) {
result.add(rules.get(i));
}
}
return result;
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
JButton b = (JButton) ((JPopupMenu) e.getSource()).getInvoker();
if (!b.isEnabled() || b.getActionCommand().equals("VIEW")) {
this.menu.removeAll();
return;
}
this.first = this.firstRules.get(b);
this.second = this.secondRules.get(b);
ExcludePairContainer.Entry entry = this.container.getEntry(this.first, this.second);
if (entry.getStatus() == ExcludePairContainer.Entry.NOT_COMPUTABLE) {
this.menu.removeAll();
return;
}
ExcludePairContainer.Entry entry1 = this.container.getEntry(this.first, this.first);
ExcludePairContainer.Entry entry2 = this.container.getEntry(this.second, this.second);
if (entry.getState() == ExcludePairContainer.Entry.DISABLED) {
this.menu.removeAll();
this.menu.add(new JMenuItem(this.first.getName() + " - disabled"));
this.menu.getComponent(0).setEnabled(false);
return;
} else if (entry.getState() == ExcludePairContainer.Entry.NOT_RELATED) {
this.menu.removeAll();
this.menu.add(new JMenuItem(this.first.getName() + " - not related"));
this.menu.getComponent(0).setEnabled(false);
return;
} else {
if (this.menu.getComponents().length <= 1) {
this.menu.removeAll();
this.menu.add(this.miClear);
this.menu.add(this.miContinue);
this.menu.add(this.miVisibleRel);
this.menu.add(this.miVisibleRule);
}
}
if (entry.getState() != ExcludePairContainer.Entry.COMPUTED
&& entry.getState() != ExcludePairContainer.Entry.COMPUTED2
&& entry.getState() != ExcludePairContainer.Entry.COMPUTED12) {
this.miClear.setEnabled(false);
this.miContinue.setEnabled(false);
this.miVisibleRel.setEnabled(false);
this.miVisibleRule.setEnabled(false);
} else {
this.miClear.setEnabled(true);
this.miContinue.setEnabled(entry.isProgressIndexSet());
this.miVisibleRel.setEnabled(true);
this.miVisibleRule.setEnabled(true);
}
if (entry.isRelationVisible())
this.miVisibleRel.setText(hideRelation);
else
this.miVisibleRel.setText(showRelation);
if (entry.isRuleVisible())
this.miVisibleRule.setText(hideRule);
else
this.miVisibleRule.setText(showRule);
if (this.first != this.second) {
this.miVisibleRule.setEnabled(false);
if (!entry.isCritical())
this.miVisibleRel.setEnabled(false);
else if (!entry1.isRuleVisible() || !entry2.isRuleVisible())
this.miVisibleRel.setEnabled(false);
else
this.miVisibleRel.setEnabled(true);
} else {
this.miVisibleRule.setEnabled(true);
if (!entry.isCritical())
this.miVisibleRel.setEnabled(false);
else
this.miVisibleRel.setEnabled(true);
}
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
public void popupMenuCanceled(PopupMenuEvent e) {
}
public Container getMainContainer() {
return this.main;
}
public ExcludePairContainer getPairContainer() {
return this.container;
}
/** changes the PairContainer displayed */
public void setPairContainer(ExcludePairContainer container) {
this.container = container;
refreshView();
}// setPairContainer
public boolean isActive() {
return this.active;
}
public boolean isEmpty() {
return this.container.isEmpty();
}
/** Returns CriticalPair.CONFLICT or CriticalPair.DEPENDENCY */
public int getKindOfPairContainer() {
return this.container.getKindOfConflict();
}
public void itemStateChanged(ItemEvent e) {
// System.out.println("itemStateChanged... "+e.getSource());
// if(e.getSource() instanceof JMenuItem){}
}
public int getTableWidth() {
return this.tableW;
}
public int getTableHeight() {
return this.tableH;
}
/**
* Gets called, if a button is pressed
*/
synchronized public void actionPerformed(ActionEvent e) {
// System.out.println("CriticalPairPanel.actionPerformed:: "+e.getSource());
Object source = e.getSource();
if (e.getSource() instanceof JMenuItem) {
if ((this.first != null) && (this.second != null)) {
ExcludePairContainer.Entry entry = this.container.getEntry(this.first,
this.second);
// System.out.println(">>> CriticalPairPanel.actionPerformed:: entry.state: "+entry.getState());
if (entry.getState() == ExcludePairContainer.Entry.COMPUTED
|| entry.getState() == ExcludePairContainer.Entry.COMPUTED2
|| entry.getState() == ExcludePairContainer.Entry.COMPUTED12) {
if (((JMenuItem) e.getSource()).getText().equals(
clearRelation)) {
this.container.clearEntry(this.first, this.second);
this.container.enableUseHostGraph(false, null);
JButton b = (JButton) ((Hashtable<Rule, JButton>) this.buttons.get(this.first))
.get(this.second);
b.setBackground(NOT_SET);
if (b.getBorder() instanceof MatteBorder) {
b.setBorder(BorderFactory.createMatteBorder(
this.borderWidth, this.borderWidth,
this.borderWidth, this.borderWidth, NOT_SET));
}
b.setText("?");
clearRulePair(this.first, this.second);
// setRuleContextVisible(first, second, false);
// setRuleVisible(first, second, false);
fireParserGUIEvent(null);
} else if (((JMenuItem) e.getSource()).getText().equals(
continueCompute)) {
if (entry.isProgressIndexSet()) {
if (this.b2cpData.get(e.getSource()) == null) {
Pair<Rule, Rule> pair = new Pair<Rule, Rule>(this.first, this.second);
fireParserGUIEvent(pair, CriticalPairEvent.CONTINUE_COMPUTE);
} else {
CriticalPairData data = this.b2cpData.get(e.getSource());
fireParserGUIEvent(data, CriticalPairEvent.CONTINUE_COMPUTE);
}
}
} else if (((JMenuItem) e.getSource()).getText().equals(
computeAndCheck)) {
this.container.enableUseHostGraph(true, this.container.getGrammar()
.getGraph());
Pair<Rule, Rule> pair = new Pair<Rule, Rule>(this.first, this.second);
fireParserGUIEvent(pair);
} else if (((JMenuItem) e.getSource()).getText().equals(
hideRelation)) {
if (entry.isCritical()) {
setRelationVisible(this.first, this.second, false);
refreshView();
}
} else if (((JMenuItem) e.getSource()).getText().equals(
showRelation)) {
if (entry.isCritical()) {
if (this.container.getEntry(this.first, this.first)
.isRuleVisible()
&& this.container.getEntry(this.second, this.second)
.isRuleVisible()) {
setRelationVisible(this.first, this.second, true);
refreshView();
}
}
} else if (((JMenuItem) e.getSource()).getText().equals(
hideRule)) {
setRuleContextVisible(this.first, this.second, false);
setRuleVisible(this.first, this.second, false);
refreshView();
} else if (((JMenuItem) e.getSource()).getText().equals(
showRule)) {
setRuleContextVisible(this.first, this.second, true);
setRuleVisible(this.first, this.second, true);
refreshView();
}
} else if (((JMenuItem) e.getSource()).getText().equals(
computeAndCheck)) {
this.container.enableUseHostGraph(true, this.container.getGrammar()
.getGraph());
Pair<Rule, Rule> pair = new Pair<Rule, Rule>(this.first, this.second);
fireParserGUIEvent(pair);
} else if (((JMenuItem) e.getSource()).getText().equals(
hideRule)) {
setRuleContextVisible(this.first, this.second, false);
setRuleVisible(this.first, this.second, false);
refreshView();
} else if (((JMenuItem) e.getSource()).getText().equals(
showRule)) {
setRuleContextVisible(this.first, this.second, true);
setRuleVisible(this.first, this.second, true);
refreshView();
}
}
}
else if (e.getSource() instanceof JButton) {
this.first = this.firstRules.get(source);
this.second = this.secondRules.get(source);
if ((this.first != null) && (this.second != null)) {
if (this.b2cpData.get(e.getSource()) == null) {
ExcludePairContainer.Entry entry = this.container.getEntry(this.first,
this.second);
if (entry.getState() != ExcludePairContainer.Entry.DISABLED
&& entry.getState() != ExcludePairContainer.Entry.NOT_RELATED
&& entry.getState() != ExcludePairContainer.Entry.COMPUTING_IS_RUNNING) {
Pair<Rule, Rule> pair = new Pair<Rule, Rule>(this.first, this.second);
/*
if (entry.getState() == ExcludePairContainer.Entry.NOT_SET) {
String what = "";
if (this.first.hasEnabledACs(false))
what = "The first rule: < ".concat(this.first.getName()).concat(" > ");
else if (this.second.hasEnabledACs(false))
what = "The second rule: < ".concat(this.second.getName()).concat(" > ");
if (!what.isEmpty()) {
JOptionPane.showMessageDialog(null,
"Computation result of this critical pair may be incomplete! \n"
+what+"\nmakes use of General Application Conditions.\n"
+"Unfortunately, critical pair analysis does not take GACs in account"
+"\n(not jet implemented).\n",
"CPA",
JOptionPane.WARNING_MESSAGE);
}
}*/
fireParserGUIEvent(pair);
}
} else {
CriticalPairData data = this.b2cpData.get(e.getSource());
fireParserGUIEvent(data);
}
}
}
} // actionPerformed
private void clearRulePair(Rule rule1, Rule rule2) {
if (this.container.getKindOfConflict() == CriticalPair.CONFLICT) {
fireParserGUIEvent(new CriticalPairEvent(this.container, rule1, rule2,
CriticalPairEvent.REMOVE_RELATION_ENTRY));
// fireParserGUIEvent(new CPAEventData(rule1, rule2,
// CPAEventData.HIDE_RELATION, "C", false));
}
else {
fireParserGUIEvent(new CriticalPairEvent(this.container, rule1, rule2,
CriticalPairEvent.REMOVE_RELATION_ENTRY));
// fireParserGUIEvent(new CPAEventData(rule1, rule2,
// CPAEventData.HIDE_RELATION, "D", false));
}
}
private void setRuleVisible(Rule rule1, Rule rule2, boolean vis) {
JButton b = (JButton) ((Hashtable<Rule, JButton>) this.buttons.get(rule1)).get(rule2);
if (!vis) {
b.setForeground(Color.darkGray);
b.setToolTipText(b.getToolTipText() + ":HIDDEN");
} else {
b.setForeground(Color.white);
b.setToolTipText("[" + rule1.getQualifiedName() + ", " + rule2.getQualifiedName()
+ "]");
}
if (this.container.getKindOfConflict() == CriticalPair.CONFLICT)
fireParserGUIEvent(new CPAEventData(rule1, rule2,
CPAEventData.SHOW_RULE, "C", vis));
else
fireParserGUIEvent(new CPAEventData(rule1, rule2,
CPAEventData.SHOW_RULE, "D", vis));
this.container.setEntryRuleVisible(rule1, rule2, vis, true, false);
}
private void setRuleContextVisible(Rule rule1, Rule rule2, boolean vis) {
for (Enumeration<Rule> keys = this.container.getExcludeContainer().keys(); keys
.hasMoreElements();) {
Rule r1 = keys.nextElement();
if (r1 == rule1) {
// System.out.println("ExcludePC:: reduce: "+r1.getName());
Hashtable<Rule, Pair<Boolean, Vector<Pair<Pair<OrdinaryMorphism, OrdinaryMorphism>, Pair<OrdinaryMorphism, OrdinaryMorphism>>>>>
secondPart = this.container
.getExcludeContainer().get(r1);
for (Enumeration<Rule> k2 = secondPart.keys(); k2.hasMoreElements();) {
Rule r2 = k2.nextElement();
// ExcludePairContainer.Entry entry = container.getEntry(r1,r2);
// if(entry.isCritical())
setRelationVisible(r1, r2, vis);
}
for (Enumeration<Rule> k2 = secondPart.keys(); k2.hasMoreElements();) {
Rule r2 = k2.nextElement();
// if(r2 != rule1)
{
// ExcludePairContainer.Entry entry = container.getEntry(r2, r1);
// if(entry.isCritical())
setRelationVisible(r2, r1, vis);
}
}
break;
}
}
}
private void setRelationVisible(Rule rule1, Rule rule2, boolean vis) {
JButton b = (JButton) ((Hashtable<Rule, JButton>) this.buttons.get(rule1)).get(rule2);
if (b != null) {
if (!vis) {
b.setForeground(Color.darkGray);
b.setToolTipText(b.getToolTipText() + ":HIDDEN");
} else {
b.setForeground(Color.white);
b.setToolTipText("[" + rule1.getQualifiedName() + ", " + rule2.getQualifiedName()
+ "]");
}
if (this.container.getKindOfConflict() == CriticalPair.CONFLICT)
fireParserGUIEvent(new CPAEventData(rule1, rule2,
CPAEventData.SHOW_RELATION, "C", vis));
else
fireParserGUIEvent(new CPAEventData(rule1, rule2,
CPAEventData.SHOW_RELATION, "D", vis));
this.container.setEntryRelationVisible(rule1, rule2, vis, true);
}
}
/**
* Register here a new listener to receive events.
*
* @param listener
* The listener.
*/
public void addParserGUIListener(ParserGUIListener listener) {
this.listeners.addElement(listener);
}
/**
* Remove a listener here and stop getting messages.
*
* @param listener
* The listener.
*/
public void removeParserGUIListener(ParserGUIListener listener) {
this.listeners.removeElement(listener);
}// removeParserGUIListener
/** fire a parser gui event */
private void fireParserGUIEvent(Object data) {
ParserGUIEvent event = new ParserGUIEvent(this, data);
for (int i = 0; i < this.listeners.size(); i++) {
ParserGUIListener l = this.listeners.elementAt(i);
l.occured(event);
}
}
private void fireParserGUIEvent(Object data, int msg) {
ParserGUIEvent event = new ParserGUIEvent(this, data, msg);
for (int i = 0; i < this.listeners.size(); i++) {
ParserGUIListener l = this.listeners.elementAt(i);
l.occured(event);
}
}
/**
* adds the button to the internal structure, so it can be addressed for
* relabeling.
*/
void addButton(Rule r1, Rule r2, JButton button) {
// create buttons-Hashtable
Hashtable<Rule, JButton> hash1 = this.buttons.get(r1);
if (hash1 == null) {
hash1 = new Hashtable<Rule, JButton>();
this.buttons.put(r1, hash1);
}
hash1.put(r2, button);
// save for reverse search
this.firstRules.put(button, r1);
this.secondRules.put(button, r2);
} // addButton
/** returns the button for the given rule pair (r1,r2) */
JButton getButton(Rule r1, Rule r2) {
Hashtable<Rule, JButton> hash1 = this.buttons.get(r1);
if (hash1 == null) {
return null;
}
return hash1.get(r2);
} // getButton
public void showCriticalPairsOfKind(String kind) {
this.b2cpData.clear();
clearView();
List<CriticalPairData> list = this.container.getCriticalPairDataOfKind(kind);
for (int i=0; i<list.size(); i++) {
CriticalPairData data = list.get(i);
JButton b = getButton(data.getRule1(), data.getRule2());
b.setActionCommand("VIEW");
this.b2cpData.put(b, data);
this.refreshView(data, b);
}
}
/** renews the button for the given rule pair (r1, r2). */
void refreshView(CriticalPairData pairData, JButton button) {
if (button == null)
return;
Rule r1 = pairData.getRule1();
Rule r2 = pairData.getRule2();
// gets the entry holding the informations of this pair
ExcludePairContainer.Entry entry = this.container.getEntry(r1, r2);
if (entry != null) {
if (entry.getState() == ExcludePairContainer.Entry.COMPUTED
|| entry.getState() == ExcludePairContainer.Entry.COMPUTED2
|| entry.getState() == ExcludePairContainer.Entry.COMPUTED12) {
if (entry.isCritical()) {
if (entry.getOverlapping() != null) {
button.setText("" + pairData.getCriticalsOfKind(-1).size());
// and is critic, so show number of overlappings
if (this.container.getKindOfConflict() == CriticalPair.TRIGGER_DEPENDENCY
|| this.container.getKindOfConflict() == CriticalPair.TRIGGER_SWITCH_DEPENDENCY) {
if (entry.getState() == ExcludePairContainer.Entry.COMPUTED) {
button.setBackground(DEPEND);
} else if (entry.getState() == ExcludePairContainer.Entry.COMPUTED2) {
button.setBackground(DEPEND2);
} else if (entry.getState() == ExcludePairContainer.Entry.COMPUTED12) {
button.setBackground(DEPEND);
button.setBorder(BorderFactory.createMatteBorder(
this.borderWidth, this.borderWidth,
this.borderWidth, this.borderWidth, DEPEND2));
}
}
else if (this.container.getKindOfConflict() == CriticalPair.CONFLICT) {
button.setBackground(CRITIC);
}
button.setEnabled(true);
}
}
}
}
}
private void clearView() {
Enumeration<Rule> en1 = this.buttons.keys();
while (en1.hasMoreElements()) {
Rule r1 = en1.nextElement();
Enumeration<Rule> en2 = this.buttons.get(r1).keys();
while (en2.hasMoreElements()) {
Rule r2 = en2.nextElement();
JButton btn = this.getButton(r1, r2);
clearButtonView(r1, r2, btn);
}
}
}
private void clearButtonView(Rule r1, Rule r2, JButton button) {
if (button == null)
return;
if (!button.getText().equals("?")) {
button.setBackground(NOT_CRITIC);
button.setText("0");
button.setToolTipText("");
button.setEnabled(false);
}
}
/** force the panel to update all buttons */
public void refreshView() {
this.b2cpData.clear();
Enumeration<Rule> en1 = this.buttons.keys();
while (en1.hasMoreElements()) {
Rule r1 = en1.nextElement();
Enumeration<Rule> en2 = this.buttons.get(r1).keys();
while (en2.hasMoreElements()) {
Rule r2 = en2.nextElement();
refreshView(r1, r2, getButton(r1, r2), -1);
}
}
}
/** renews the button for the given rule pair (r1, r2). */
void refreshView(Rule r1, Rule r2, int key) {
// the button for the pair
refreshView(r1, r2, getButton(r1, r2), key);
} // refreshView
/** renews the button for the given rule pair (r1, r2). */
void refreshView(Rule r1, Rule r2, JButton button, int key) {
if (button == null)
return;
button.setEnabled(true);
button.setActionCommand("");
// gets the entry holding the informations of this pair
ExcludePairContainer.Entry entry = this.container.getEntry(r1, r2);
ExcludePairContainer.Entry entry1 = this.container.getEntry(r1, r1);
ExcludePairContainer.Entry entry2 = this.container.getEntry(r2, r2);
// System.out.println("key: "+key+" entry.getState(): "+entry.getState());
// the given pair was not tested yet
if (entry.getState() == ExcludePairContainer.Entry.NOT_SET) {
button.setBackground(NOT_SET);
button.setText("?");
button.setForeground(Color.black);
if (button.getBorder() instanceof MatteBorder) {
button.setBorder(border);
}
}
// the pair will be checked soon
else if (entry.getState() == ExcludePairContainer.Entry.SCHEDULED_FOR_COMPUTING) {
button.setBackground(NOT_SET);
button.setText("?");
if (button.getBorder() instanceof MatteBorder) {
button.setBorder(border);
}
}
// the calculation is running
else if (entry.getState() == ExcludePairContainer.Entry.COMPUTING_IS_RUNNING) {
button.setBackground(COMPUTING);
button.setText("C");
if (button.getBorder() instanceof MatteBorder) {
button.setBorder(border);
}
}
// the pair was checked
else if (entry.getState() == ExcludePairContainer.Entry.COMPUTED
|| entry.getState() == ExcludePairContainer.Entry.COMPUTED2
|| entry.getState() == ExcludePairContainer.Entry.COMPUTED12) {
if (entry.isCritical()) {
// and is critic, so show number of overlappings
if (this.container.getKindOfConflict() == CriticalPair.TRIGGER_DEPENDENCY
|| this.container.getKindOfConflict() == CriticalPair.TRIGGER_SWITCH_DEPENDENCY) {
if (entry.getState() == ExcludePairContainer.Entry.COMPUTED) {
button.setBackground(DEPEND);
} else if (entry.getState() == ExcludePairContainer.Entry.COMPUTED2) {
button.setBackground(DEPEND2);
} else if (entry.getState() == ExcludePairContainer.Entry.COMPUTED12) {
button.setBackground(DEPEND);
button.setBorder(BorderFactory.createMatteBorder(
this.borderWidth, this.borderWidth,
this.borderWidth, this.borderWidth, DEPEND2));
}
}
else if (this.container.getKindOfConflict() == CriticalPair.CONFLICT) {
button.setBackground(CRITIC);
}
if (entry.getStatus() == ExcludePairContainer.Entry.NOT_COMPLETE_COMPUTABLE) {
button.setBorder(BorderFactory.createMatteBorder(
3, 3, 3, 3, Color.BLACK));
}
if (entry.getOverlapping() != null)
button.setText("" + entry.getOverlapping().size());
else
button.setText("!");
if (!entry.isRuleVisible() || !entry.isRelationVisible()) {
button.setForeground(Color.white);
if (button.getToolTipText().indexOf("HIDDEN") == -1)
button.setToolTipText(button.getToolTipText()
+ ":HIDDEN");
} else if ((entry1 != null && !entry1.isRuleVisible())
|| (entry2 != null && !entry2.isRuleVisible())) {
button.setForeground(Color.white);
if (button.getToolTipText().indexOf("HIDDEN") == -1)
button.setToolTipText(button.getToolTipText()
+ ":HIDDEN");
} else {
button.setForeground(Color.black);
button.setToolTipText("[" + r1.getQualifiedName() + ", "
+ r2.getQualifiedName() + "]");
}
if (key == CriticalPairEvent.UNCRITICAL
|| entry.getStatus() == ExcludePairContainer.Entry.NON_RELEVANT)
button.setEnabled(false);
else if (entry.getState() != ExcludePairContainer.Entry.DISABLED)
button.setEnabled(true);
} else {
// or it is non-critic, so show 0
button.setBackground(NOT_CRITIC);
if (entry.getStatus() == ExcludePairContainer.Entry.NOT_COMPLETE_COMPUTABLE) {
button.setBorder(BorderFactory.createMatteBorder(
3, 3, 3, 3, Color.BLACK));
}
button.setText("0");
if (!entry.isRuleVisible() || !entry.isRelationVisible()) {
button.setForeground(Color.white);
if (button.getToolTipText().indexOf("HIDDEN") == -1)
button.setToolTipText(button.getToolTipText()
+ ":HIDDEN");
} else if ((entry1 != null && !entry1.isRuleVisible())
|| (entry2 != null && !entry2.isRuleVisible())) {
button.setForeground(Color.white);
if (button.getToolTipText().indexOf("HIDDEN") == -1)
button.setToolTipText(button.getToolTipText()
+ ":HIDDEN");
} else {
button.setForeground(Color.black);
button.setToolTipText("[" + r1.getQualifiedName() + ", "
+ r2.getQualifiedName() + "]");
}
}
if (key == CriticalPairEvent.NON_RELEVANT
|| entry.getStatus() == ExcludePairContainer.Entry.NON_RELEVANT)
button.setEnabled(false);
else if (entry.getStatus() == ExcludePairContainer.Entry.NOT_COMPUTABLE) {
button.setToolTipText("[" + r1.getQualifiedName() + ", "
+ r2.getQualifiedName() + "]"+" - not computed");
button.setBackground(Color.LIGHT_GRAY);
button.setText("");
}
else if (entry.getState() != ExcludePairContainer.Entry.DISABLED)
button.setEnabled(true);
} else if (entry.getState() == ExcludePairContainer.Entry.DISABLED) {
if (!r1.isEnabled() || !r2.isEnabled()) {
String s = r1.getName() + ": DISABLED";
if (!r1.isEnabled() && !r2.isEnabled())
s = "DISABLED";
else if (!r2.isEnabled())
s = r2.getName() + ": DISABLED";
button.setBackground(DISABLED);
button.setText("");
button.setToolTipText(s);
} else {
entry.setState(ExcludePairContainer.Entry.NOT_SET);
this.container.clearEntry(r1, r2);
button.setBackground(NOT_SET);
button.setText("?");
button.setForeground(Color.black);
}
} else if (entry.getState() == ExcludePairContainer.Entry.NOT_RELATED) {
button.setBackground(NOT_RELATED);
button.setText("");
} else if (entry.getState() == ExcludePairContainer.Entry.NON_RELEVANT) {
button.setEnabled(false);
}
} // refreshView
/**
* gets called if something changed in the critical pair container so the
* display must be updated.
*/
public void parserEventOccured(ParserEvent p) {
if (p instanceof CriticalPairEvent) {
// System.out.println("CriticalPairPanel.parserEventOccured ->
// CriticalPairEvent: "+p.getSource());
if (((CriticalPairEvent) p).getFirstRule() == null
|| ((CriticalPairEvent) p).getSecondRule() == null)
return;
Rule r1 = ((CriticalPairEvent) p).getFirstRule();
Rule r2 = ((CriticalPairEvent) p).getSecondRule();
refreshView(r1, r2, ((CriticalPairEvent) p).getKey());
}
} // parserEventOccured
} // class CriticalPairPanel