package agg.gui.termination;
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.ScrollPaneConstants;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JDialog;
import javax.swing.border.TitledBorder;
import agg.xt_basis.Arc;
import agg.xt_basis.GraphObject;
import agg.xt_basis.Node;
import agg.xt_basis.Rule;
import agg.termination.TerminationLGTS;
import agg.termination.TerminationLGTSInterface;
import agg.termination.TerminationLGTSTypedByTypeGraph;
import agg.util.Pair;
/**
* Shows a table with a row for a layer and a column for a termination
* condition, so that each element stands for rules on certain layer. The color
* of the pairs shows the state of them (green - condition is satisfied, rot -
* not satisfied).
*
* @version $Id: LayerTerminationCondTable.java,v 1.3 2006/12/13 13:33:05 enrico
* Exp $
* @author $Author: olga $
*/
@SuppressWarnings("serial")
public class LayerTerminationCondTable extends JDialog implements
ActionListener {
static final Color NOT_VALID = Color.red;
static final Color VALID = Color.green;
/** the Buttons for the entries. Hashtable[Integer, Vector[Rule]] */
private Hashtable<Integer, Hashtable<String, JButton>>
buttons = new Hashtable<Integer, Hashtable<String, JButton>>();
private TerminationLGTSInterface termination;
/** the layer for a Button. */
private Hashtable<JButton, Integer> firstLayers = new Hashtable<JButton, Integer>();
/** the condition for a Button. */
private Hashtable<JButton, String> secondConds = new Hashtable<JButton, String>();
private JPanel panel;
private JPanel tablePanel;
private JScrollPane scrLayer;
// private JScrollPane scrInfo;
private RuleTable tableRule;
private TypeTable tableTypeDeletion;
private TypeTable tableTypeCreation;
private JButton lastButton;
private Vector<Pair<String, String>> conds;
private int w, h;
/**
* It is used in a constructor.
*/
static private Vector<Pair<String, String>> getConditionName() {
Vector<Pair<String, String>> names = new Vector<Pair<String, String>>(3);
names.add(new Pair<String, String>("Deletion_1",
"Type Deletion Layer Condition"));
names.add(new Pair<String, String>("Deletion_2",
"Deletion Layer Condition"));
names.add(new Pair<String, String>("Nondeletion",
"Nondeletion Layer Condition"));
return names;
}
/**
* constructs a new dialog panel for the given layers and termination
* conditions
*/
public LayerTerminationCondTable(TerminationLGTSInterface termination) {
super(new JFrame(), false);
setTitle("Termination of LGTS");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
setVisible(false);
dispose();
}
});
this.termination = termination;
GridBagLayout gridbag = new GridBagLayout();
JPanel main = new JPanel(new BorderLayout());
main.setBackground(Color.lightGray);
this.panel = new JPanel(gridbag);
// create the ScrollPane
this.scrLayer = new JScrollPane();
this.scrLayer.setBackground(Color.orange);
this.scrLayer.setBorder(new TitledBorder(" Termination Conditions of LGTS "));
// the head of the rows
JPanel rowHead = new JPanel();
rowHead.setLayout(new GridLayout(termination.getOrderedRuleLayer()
.size(), 1));
Enumeration<Integer> en = termination.getOrderedRuleLayer().elements();
while (en.hasMoreElements()) {
String text = en.nextElement().toString();
JLabel act = new JLabel(" Layer " + text + " ");
act.setToolTipText("");
rowHead.add(act);
}
// the head of the columns
JPanel colHead = new JPanel();
colHead.setLayout(new GridLayout(1, 3));
this.conds = getConditionName();
for (int i = 0; i < this.conds.size(); i++) {
Pair<String, String> cond = this.conds.get(i);
String text = cond.first;
JLabel act = new JLabel(" " + text);
act.setToolTipText("");
colHead.add(act);
}
// create the center panel with a button for each rule
this.tablePanel = new JPanel();
this.tablePanel.setLayout(new GridLayout(termination.getOrderedRuleLayer()
.size(), 3));
int i = 0;
while (i < termination.getOrderedRuleLayer().size()) {
int ii = 0;
while (ii < 3) {
JButton act = new JButton(" ");
act.setToolTipText(this.conds.elementAt(ii).first);
act.setMinimumSize(new Dimension(act.getHeight(), act
.getHeight()));
act.addActionListener(this);
// System.out.println(termination.getOrderedRuleLayer().elementAt(i));
// System.out.println(this.conds.elementAt(ii));
this.addButton(termination.getOrderedRuleLayer().elementAt(i),
this.conds.elementAt(ii).first, act);
this.tablePanel.add(act);
refreshView(termination.getOrderedRuleLayer().elementAt(i),
this.conds.elementAt(ii).first, act);
ii++;
}
i++;
}
// get the preferred size for the center panel
Dimension dim = this.tablePanel.getPreferredSize();
// System.out.println("tablePanel "+dim);
Dimension dim1 = new Dimension();
dim1.setSize(dim.getWidth() + 50, dim.getHeight() + 20);
// calculate minimum/prefered size for column header
Dimension dim2 = new Dimension();
dim2.setSize(dim1.getWidth(), colHead.getPreferredSize().getHeight());
colHead.setMinimumSize(dim2);
colHead.setPreferredSize(dim2);
// calculate minimum/preferred size for row header
dim2 = new Dimension();
dim2.setSize(rowHead.getPreferredSize().getWidth(), dim1.getHeight());
rowHead.setPreferredSize(dim2);
rowHead.setMinimumSize(dim2);
// set the table panel to its actual size
this.tablePanel.setPreferredSize(dim1);
this.tablePanel.setMinimumSize(dim1);
// construct JScrollPane
this.scrLayer.setRowHeaderView(rowHead);
this.scrLayer.setColumnHeaderView(colHead);
this.scrLayer.setViewportView(this.tablePanel);
this.scrLayer.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER,
new JLabel(""));
constrainBuild(this.panel, this.scrLayer, 0, 0, 1, 1, GridBagConstraints.BOTH,
GridBagConstraints.CENTER, 1.0, 0.0, 5, 5, 5, 5);
JButton closeButton = new JButton("Close");
closeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
}
});
JPanel closeP = new JPanel(new GridLayout(1, 3));
closeP.add(new JLabel(" "));
closeP.add(closeButton);
closeP.add(new JLabel(" "));
main.add(this.panel, BorderLayout.CENTER);
main.add(closeP, BorderLayout.SOUTH);
main.revalidate();
JScrollPane scroll = new JScrollPane(main);
scroll.setPreferredSize(new Dimension(300, 250));
getContentPane().setLayout(new BorderLayout());
getContentPane().add(scroll);
validate();
setLocation(200, 100);
pack();
}
public void showGUI() {
setVisible(true);
this.w = getWidth();
}
/**
* Gets called, if a button is pressed
*/
synchronized public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
Integer layer = this.firstLayers.get(source);
String second = this.secondConds.get(source);
if (this.lastButton != null)
this.lastButton.setText("");
if ((layer != null) && (second != null)) {
if (this.scrLayer != null)
this.panel.remove(this.scrLayer);
if (this.tableRule != null)
this.panel.remove(this.tableRule);
if (this.tableTypeDeletion != null)
this.panel.remove(this.tableTypeDeletion);
if (this.tableTypeCreation != null)
this.panel.remove(this.tableTypeCreation);
((JButton) source).setText("X");
this.h = (int) (this.scrLayer.getPreferredSize().getHeight());
constrainBuild(this.panel, this.scrLayer, 0, 0, 1, 1,
GridBagConstraints.BOTH, GridBagConstraints.CENTER, 1.0,
0.0, 5, 5, 5, 5);
Vector<String> rules = getRules(layer, second);
if (rules.size() != 0) {
this.tableRule = new RuleTable(rules, " Rules of the Layer "
+ layer);
this.tableRule.setPreferredSize(new Dimension(this.w, this.tableRule
.getTableHeight()));
this.h = this.h + (int) (this.tableRule.getPreferredSize().getHeight());
constrainBuild(this.panel, this.tableRule, 0, 1, 1, 1,
GridBagConstraints.BOTH, GridBagConstraints.CENTER,
1.0, 0.0, 5, 5, 10, 5);
if (second.equals("Deletion_1")) {
Vector<String> deletionTypeTypes = getTypes(layer, "Deletion_1");
this.tableTypeDeletion = new TypeTable(deletionTypeTypes,
" Type - Deletion ");
this.tableTypeDeletion.setPreferredSize(new Dimension(this.w,
this.tableTypeDeletion.getTableHeight()));
this.h = this.h + (int) (this.tableTypeDeletion.getPreferredSize()
.getHeight());
constrainBuild(this.panel, this.tableTypeDeletion, 0, 2, 1, 1,
GridBagConstraints.BOTH, GridBagConstraints.CENTER,
1.0, 0.0, 5, 5, 10, 5);
} else if (second.equals("Deletion_2")) {
Vector<String> deletionTypes = getTypes(layer, "Deletion_2");
this.tableTypeDeletion = new TypeTable(deletionTypes,
" Type Deletion of the Layer " + layer);
this.tableTypeDeletion.setPreferredSize(new Dimension(this.w,
this.tableTypeDeletion.getTableHeight()));
this.h = this.h + (int) (this.tableTypeDeletion.getPreferredSize()
.getHeight());
constrainBuild(this.panel, this.tableTypeDeletion, 0, 2, 1, 1,
GridBagConstraints.BOTH, GridBagConstraints.CENTER,
1.0, 0.0, 5, 5, 10, 5);
Vector<String> creationTypes = getCreatedTypesOnDeletionLayer(layer);
if (creationTypes.size() != 0) {
this.tableTypeCreation = new TypeTable(creationTypes,
" Type Creation of the Layer " + layer);
this.tableTypeCreation.setPreferredSize(new Dimension(this.w,
this.tableTypeCreation.getTableHeight()));
this.h = this.h + (int) (this.tableTypeCreation.getPreferredSize()
.getHeight());
constrainBuild(this.panel, this.tableTypeCreation, 0, 3, 1, 1,
GridBagConstraints.BOTH,
GridBagConstraints.CENTER, 1.0, 0.0, 5, 5, 10,
5);
}
} else if (second.equals("Nondeletion")) {
Vector<String> creationTypes = getTypes(layer, "Nondeletion");
this.tableTypeCreation = new TypeTable(creationTypes,
" Type Creation of the Layer " + layer);
this.tableTypeCreation.setPreferredSize(new Dimension(this.w,
this.tableTypeCreation.getTableHeight()));
constrainBuild(this.panel, this.tableTypeCreation, 0, 2, 1, 1,
GridBagConstraints.BOTH, GridBagConstraints.CENTER,
1.0, 0.0, 5, 5, 10, 5);
this.h = this.h + (int) (this.tableTypeCreation.getPreferredSize()
.getHeight());
}
}
this.h = this.h + 50;
this.panel.setPreferredSize(new Dimension(this.w, this.h));
this.panel.revalidate();
setSize(this.w + 50, this.h + 80);
validate();
this.lastButton = (JButton) source;
}
}
/**
* adds the button to the internal structur, so it can be adressed for
* relabeling.
*/
void addButton(Integer layer, String condName, JButton button) {
// create buttons-Hashtable
Hashtable<String, JButton> hash1 = this.buttons.get(layer);
if (hash1 == null) {
hash1 = new Hashtable<String, JButton>();
this.buttons.put(layer, hash1);
}
hash1.put(condName, button);
// save for reverse search
this.firstLayers.put(button, layer);
this.secondConds.put(button, condName);
}
/** returns the button for the given rule pair (r1,r2) */
JButton getButton(Integer layer, String condName) {
Hashtable<String, JButton> hash1 = this.buttons.get(layer);
if (hash1 == null) {
return null;
}
return hash1.get(condName);
} // getButton
/** force the panel to update all buttons */
public void refreshView() {
Enumeration<Integer> en1 = this.buttons.keys();
while (en1.hasMoreElements()) {
Integer first = en1.nextElement();
Enumeration<String> en2 = this.buttons.get(first).keys();
while (en2.hasMoreElements()) {
String second = en2.nextElement();
refreshView(first, second);
} // while en2.hasMoreElements
} // while en1.hasMoreElements
} // reload
/** renews the button for the given pair (first, second). */
void refreshView(Integer first, String second) {
// the button for the pair
refreshView(first, second, getButton(first, second));
} // refreshView
/** renews the button for the given pair (layer, cond). */
void refreshView(Integer layer, String cond, JButton button) {
boolean value = getValue(layer, cond);
if (value) {
button.setBackground(VALID);
button.setText(" ");
} else {
button.setBackground(NOT_VALID);
button.setText(" ");
}
}
private boolean getValue(Integer layer, String condName) {
if (condName.equals("Deletion_1")) {
Pair<Boolean, Vector<Rule>> value = this.termination
.getResultTypeDeletion().get(layer);
return value.first.booleanValue();
} else if (condName.equals("Deletion_2")) {
Pair<Boolean, Vector<Rule>> value = this.termination.getResultDeletion()
.get(layer);
return value.first.booleanValue();
} else if (condName.equals("Nondeletion")) {
Pair<Boolean, Vector<Rule>> value = this.termination
.getResultNondeletion().get(layer);
return value.first.booleanValue();
} else
return false;
}
@SuppressWarnings("unused")
private Vector<String> getRules(Integer layer, String condName) {
Vector<String> names = new Vector<String>();
boolean result = false;
if (condName.equals("Deletion_1")) {
Pair<Boolean, Vector<Rule>> p = this.termination.getResultTypeDeletion()
.get(layer);
result = p.first.booleanValue();
} else if (condName.equals("Deletion_2")) {
Pair<Boolean, Vector<Rule>> p = this.termination.getResultDeletion()
.get(layer);
result = p.first.booleanValue();
} else if (condName.equals("Nondeletion")) {
Pair<Boolean, Vector<Rule>> p = this.termination.getResultNondeletion()
.get(layer);
result = p.first.booleanValue();
}
HashSet<?> rulesForLayer = this.termination
.getInvertedRuleLayer().get(layer);
Iterator<?> en = rulesForLayer.iterator();
while (en.hasNext()) {
Rule rule = (Rule) en.next();
names.addElement(rule.getName());
}
return names;
}
private Vector<String> getTypes(Integer layer, String condName) {
Vector<String> names = new Vector<String>();
HashSet<?> typesForLayer = null;
if (condName.equals("Deletion_1")) {
if (this.termination instanceof TerminationLGTS) {
if ((this.termination.getDeletionType() != null)
&& this.termination.getDeletionType().containsKey(layer)) {
Vector<agg.xt_basis.Type> types = this.termination.getDeletionType().get(layer);
if (types != null) {
Enumeration<agg.xt_basis.Type> en = types.elements();
while (en.hasMoreElements()) {
agg.xt_basis.Type t = en.nextElement();
if (t.getStringRepr().equals(""))
names.addElement("(unnamed)");
else
names.addElement(t.getStringRepr());
}
}
}
}
else if (this.termination instanceof TerminationLGTSTypedByTypeGraph) {
if ((this.termination.getDeletionTypeObject() != null)
&& this.termination.getDeletionTypeObject().containsKey(layer)) {
Vector<GraphObject> typeObjs = this.termination.getDeletionTypeObject().get(layer);
if (typeObjs != null) {
Enumeration<GraphObject> en = typeObjs.elements();
while (en.hasMoreElements()) {
GraphObject tobj = en.nextElement();
if (tobj.isNode()) {
if (tobj.getType().getStringRepr().equals(""))
names.add("(unnamed)");
else
names.add(tobj.getType().getStringRepr());
}
else {
names.add(getTypeStringOfEdge((Arc) tobj));
}
}
}
}
}
return names;
} else if (condName.equals("Deletion_2")) {
if ((this.termination.getInvertedTypeDeletionLayer() != null)
&& this.termination.getInvertedTypeDeletionLayer().containsKey(layer))
typesForLayer = this.termination.getInvertedTypeDeletionLayer().get(layer);
} else if (condName.equals("Nondeletion")) {
if ((this.termination.getInvertedTypeCreationLayer() != null)
&& this.termination.getInvertedTypeCreationLayer().containsKey(layer))
typesForLayer = this.termination.getInvertedTypeCreationLayer().get(layer);
}
if (typesForLayer != null) {
Iterator<?> en = typesForLayer.iterator();
while (en.hasNext()) {
final Object tobj = en.next();
if (tobj instanceof agg.xt_basis.Type) {
final agg.xt_basis.Type t = (agg.xt_basis.Type) tobj;
if (t.getStringRepr().equals(""))
names.addElement("(unnamed)");
else
names.addElement(t.getStringRepr());
}
else if (tobj instanceof Node) {
names.add(this.getTypeStringOfNode((Node) tobj));
}
else if (tobj instanceof Arc) {
names.add(getTypeStringOfEdge((Arc) tobj));
}
}
}
return names;
}
private Vector<String> getCreatedTypesOnDeletionLayer(Integer layer) {
final Vector<String> names = new Vector<String>();
final Vector<Object> types = this.termination.getCreatedTypesOnDeletionLayer(layer);
final Enumeration<Object> en = types.elements();
while (en.hasMoreElements()) {
final Object tobj = en.nextElement();
if (tobj instanceof agg.xt_basis.Type) {
final agg.xt_basis.Type t = (agg.xt_basis.Type) tobj;
if (t.getStringRepr().equals(""))
names.addElement("(unnamed)");
else
names.addElement(t.getStringRepr());
}
else if (tobj instanceof Node) {
names.add(this.getTypeStringOfNode((Node) tobj));
}
else if (tobj instanceof Arc) {
names.add(getTypeStringOfEdge((Arc) tobj));
}
}
return names;
}
// constrainBuild() method
private void constrainBuild(Container container, Component component,
int grid_x, int grid_y, int grid_width, int grid_height, int fill,
int anchor, double weight_x, double weight_y, int top, int left,
int bottom, int right) {
GridBagConstraints c = new GridBagConstraints();
c.gridx = grid_x;
c.gridy = grid_y;
c.gridwidth = grid_width;
c.gridheight = grid_height;
c.fill = fill;
c.anchor = anchor;
c.weightx = weight_x;
c.weighty = weight_y;
c.insets = new Insets(top, left, bottom, right);
((GridBagLayout) container.getLayout()).setConstraints(component, c);
container.add(component);
}
private String getTypeStringOfNode(final Node go) {
String s = go.getType().getStringRepr();
if (s.equals(""))
s = "(unnamed)";
return s;
}
private String getTypeStringOfEdge(final Arc go) {
String s = getTypeStringOfNode((Node) go.getSource());
s = s.concat("--");
String s1 = go.getType().getStringRepr();
if (s1.equals(""))
s1 = "(unnamed)";
s = s.concat(s1);
s = s.concat("->");
s = s.concat(getTypeStringOfNode((Node) go.getTarget()));
return s;
}
}