package agg.gui.treeview.dialog; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; //import java.awt.Container; import java.awt.Dimension; //import java.awt.GridBagConstraints; //import java.awt.GridBagLayout; import java.awt.GridLayout; //import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.border.TitledBorder; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.DefaultTableCellRenderer; import agg.editor.impl.EdGraGra; import agg.gui.help.HtmlBrowser; import agg.xt_basis.Rule; import agg.xt_basis.RuleLayer; import agg.util.IntComparator; import agg.util.OrderedSet; import agg.util.Pair; //import com.objectspace.jgl.HashSet; //import com.objectspace.jgl.OrderedSet; //import com.objectspace.jgl.OrderedSetIterator; /** * This class provides a window for a user dialog. This dialog is necessary to * enter the grammar layers. * * @author $Author: olga $ * @version $Id: GraGraTriggerRuleOfLayerGUI.java,v 1.5 2006/12/14 18:21:44 olga * Exp $ */ @SuppressWarnings("serial") public class GraGraTriggerRuleOfLayerDialog extends JDialog implements ActionListener, MouseListener { JPanel contentPane; JPanel rulePanel; JPanel buttonPanel; JScrollPane ruleScrollPane; JTable ruleTable; JButton closeButton; JButton cancelButton; JButton helpButton; boolean isCancelled; RuleLayer layer; EdGraGra gragra; HtmlBrowser helpBrowser; /** This class models a hashtable for a table. */ public class HashTableModel extends DefaultTableModel { Hashtable<Rule, Pair<Integer, String>> table; RuleLayer ruleLayer; // Hashtable triggerTable; /** * Creates a new model with hashtable and the title for the column of * the table. * * @param layer * The rule layer with hashtable for the model. * @param columnNames * The array with the column names. */ @SuppressWarnings("rawtypes") public HashTableModel(RuleLayer layer, String[] columnNames) { super(); for (int i = 0; i < columnNames.length; i++) { addColumn(columnNames[i]); } Hashtable<Rule, Integer> layerTable = layer.getRuleLayer(); this.table = new Hashtable<Rule, Pair<Integer, String>>(layerTable .size()); // triggerTable = new Hashtable(layerTable.size()); for (Enumeration<Rule> e = layerTable.keys(); e.hasMoreElements();) { Rule key = e.nextElement(); String trigger = ""; if (key.isTriggerOfLayer()) trigger = "trigger"; Pair<Integer, String> value = new Pair<Integer, String>( layerTable.get(key), trigger); this.table.put(key, value); } this.ruleLayer = layer; Integer startLayer = layer.getStartLayer(); Hashtable<Integer, HashSet<Rule>> invertedRuleLayer = layer.invertLayer(); OrderedSet<Integer> ruleLayerSet = new OrderedSet<Integer>(new IntComparator<Integer>()); for (Enumeration<Integer> en = invertedRuleLayer.keys(); en .hasMoreElements();) { ruleLayerSet.add(en.nextElement()); } int i = 0; Integer currentLayer = startLayer; boolean nextLayerExists = true; while (nextLayerExists && (currentLayer != null)) { HashSet rulesForLayer = invertedRuleLayer.get(currentLayer); Iterator<?> en = rulesForLayer.iterator(); while (en.hasNext()) { Rule rule = (Rule) en.next(); Vector<Object> tmpVector = new Vector<Object>(); tmpVector.addElement(rule); tmpVector.addElement(Integer.valueOf(rule.getLayer())); String trigger = rule.isTriggerOfLayer() ? new String( "trigger") : new String(""); tmpVector.addElement(trigger); // System.out.println(tmpVector.lastElement()); addRow(tmpVector); } // set next Layer i++; if (i < ruleLayerSet.size()) { currentLayer = ruleLayerSet.get(i); } else { nextLayerExists = false; } } } /** * This method decides if a cell of a table is editable or not. * * @param rowIndex * The index of the row of the cell. * @param columnIndex * The index of the column of the cell. * @return The layer function can only entered in the second column. So * for any other column <CODE>false</CODE> is returned. */ public boolean isCellEditable(int rowIndex, int columnIndex) { return (columnIndex == 1); } /** * Returns the value of a cell. * * @param row * The index of the row of the cell. * @param column * The index of the column of the cell. * @return The object of the underlaying model of this table. */ public Object getValueAt(int row, int column) { // System.out.println("getValue: "+row+" "+column); Object result = super.getValueAt(row, column); if (result instanceof Rule) { result = ((Rule) result).getName(); } else { Object key = super.getValueAt(row, 0); if (key instanceof Rule) { Pair<Integer, String> p = this.table.get(key); if (column == 1) { result = p.first; } else if (column == 2) { result = p.second; } } } return result; } /** * Sets a new value to a cell. * * @param aValue * The new value of a cell. * @param row * The index of the row of the cell. * @param column * The index of the column of the cell. */ public void setValueAt(Object aValue, int row, int column) { Object key = super.getValueAt(row, 0); // System.out.println(((Rule)key).getName()+" setValueAt..."); try { if (column == 1) { Integer i = Integer.valueOf((String) aValue); Pair<Integer, String> pold = this.table.get(key); if (pold.first.intValue() != i.intValue()) { super.setValueAt(i, row, column); Pair<Integer, String> pnew = new Pair<Integer, String>( i, new String("")); this.table.put((Rule) key, pnew); this.ruleLayer.getRuleLayer().put((Rule) key, i); // System.out.println("WARNING! Layer has been changed! // Check trigger rule!"); } } else if (column == 2) { // System.out.println("set column 2...: value= "+aValue); String trigger = (String) aValue; if (key instanceof Rule) { Pair<Integer, String> pold = this.table.get(key); Pair<Integer, String> pnew = new Pair<Integer, String>( pold.first, trigger); this.table.put((Rule) key, pnew); } } } catch (NumberFormatException nfe) { } } public void refreshTriggerEntries(Object value, int row) { Rule rule = (Rule) super.getValueAt(row, 0); // System.out.println("refresh... after "+rule.getName()); for (Enumeration<Rule> e = this.table.keys(); e.hasMoreElements();) { Rule key = e.nextElement(); // System.out.println(key); if (!key.equals(rule)) { int rowOfKey = getRow(key); if (rowOfKey == -1) continue; int rlayer = ((Integer) getValueAt(row, 1)).intValue(); int layerOfKey = ((Integer) getValueAt(rowOfKey, 1)) .intValue(); if (rlayer == layerOfKey) { String triggerOfKey = (String) getValueAt(rowOfKey, 2); if (triggerOfKey.equals("trigger")) { Pair<Integer, String> pold = this.table.get(key); Pair<Integer, String> pnew = new Pair<Integer, String>( pold.first, ""); this.table.put(key, pnew); // System.out.println(key.getName()+" "+pnew); super.setValueAt("", rowOfKey, 2); break; } } } } } public Hashtable<Rule, Pair<Integer, String>> getTable() { return this.table; } public Rule getRule(String name) { for (Enumeration<Rule> e = this.table.keys(); e.hasMoreElements();) { Rule key = e.nextElement(); if (key.getName().equals(name)) return key; } return null; } public int getRow(Rule rule) { for (int i = 0; i < getRowCount(); i++) { String rname = (String) getValueAt(i, 0); Rule r = getRule(rname); if ((r != null) && r.equals(rule)) return i; } return -1; } } public class TriggerCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer, MouseListener // , ActionListener { Vector<JCheckBox> checks; public final JTable jtable; public TriggerCellRenderer(int size, JTable table) { super(); addMouseListener(this); this.jtable = table; this.jtable.addMouseListener(this); this.checks = new Vector<JCheckBox>(size); initTriggers(size); } private void initTriggers(int size) { for (int i = 0; i < size; i++) { JCheckBox cb = new JCheckBox("", false); cb.addMouseListener(this); // das wirkt noch nicht!!! // cb.addActionListener(this);// das wirkt noch nicht!!! cb.setBackground(Color.WHITE); this.checks.addElement(cb); Object value = ((DefaultTableModel) this.jtable.getModel()) .getValueAt(i, 2); if (((String) value).equals("trigger")) cb.setSelected(true); } } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // System.out.println("getTableCellRendererComponent...: "+row+" // "+column+" "+value); JCheckBox jcb = this.checks.get(row); if (!isSelected) { Object aValue = ((DefaultTableModel) this.jtable.getModel()) .getValueAt(row, 2); if (aValue.equals("") && jcb.isSelected()) jcb.setSelected(false); } return jcb; } /* * public void actionPerformed(ActionEvent e) { * System.out.println("TriggerCellRenderer.actionPerformed: * "+e.getSource()); Object source = e.getSource(); } */ public void mouseClicked(MouseEvent e) { // System.out.println("TriggerCellRenderer.mouseClicked: " // +e.getSource()); for (int i = 0; i < this.checks.size(); i++) { JCheckBox cb = this.checks.get(i); // System.out.println(this.jtable.isCellSelected(i, 2)); if (this.jtable.isCellSelected(i, 2)) { cb.setSelected(!cb.isSelected()); this.jtable.updateUI(); if (cb.isSelected()) { cb.setBackground(this.jtable.getSelectionBackground()); ((DefaultTableModel) this.jtable.getModel()).setValueAt( "trigger", i, 2); } else { ((DefaultTableModel) this.jtable.getModel()).setValueAt("", i, 2); } Object newValue = ((DefaultTableModel) this.jtable.getModel()) .getValueAt(i, 2); // System.out.println(" newValue: "+newValue); if (cb.isSelected()) ((HashTableModel) this.jtable.getModel()) .refreshTriggerEntries(newValue, i); } } } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public Vector<JCheckBox> getChecks() { return this.checks; } } /** * Creates new form GraGraLayerGUI * * @param parent * The parent frame of this gui. * @param layer * The layer function must be changed. */ public GraGraTriggerRuleOfLayerDialog(JFrame parent, RuleLayer layer) { super(parent, true); // System.out.println("GraGraLayerRuleTriggerGUI parent: "+parent); setTitle("Set Trigger Rule"); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { exitForm(evt); } }); this.layer = layer; if (parent != null) setLocationRelativeTo(parent); else setLocation(300, 100); initComponents(); } /** * This method is called from within the constructor to initialize the * dialog. */ private void initComponents() { this.contentPane = new JPanel(new BorderLayout()); this.contentPane.setBackground(Color.lightGray); this.rulePanel = new JPanel(new BorderLayout()); this.rulePanel.setBackground(Color.orange); this.rulePanel.setBorder(new TitledBorder("Set Trigger Rule for Layer")); this.ruleTable = new JTable(new HashTableModel(this.layer, new String[] { "Rule", "Layer", "Trigger" })); this.ruleTable.getColumn("Layer").setMaxWidth(50); this.ruleTable.setRowSelectionAllowed(true); this.ruleTable.setColumnSelectionAllowed(false); this.ruleTable.setSelectionBackground(Color.WHITE); TableColumn triggerColumn = this.ruleTable.getColumn("Trigger"); triggerColumn.setMaxWidth(50); TriggerCellRenderer tcr = new TriggerCellRenderer(this.ruleTable .getRowCount(), this.ruleTable); triggerColumn.setCellRenderer(tcr); this.ruleTable.getSelectionModel().setSelectionMode(2); // System.out.println(this.ruleTable.getSelectionModel().getSelectionMode()); int hght = getHeight(this.ruleTable.getRowCount(), this.ruleTable.getRowHeight()) + 10; // System.out.println("this.ruleTable Height: "+hght); this.ruleTable.doLayout(); this.ruleScrollPane = new JScrollPane(this.ruleTable); this.ruleScrollPane.setPreferredSize(new Dimension(300, hght)); this.rulePanel.add(this.ruleScrollPane); this.buttonPanel = new JPanel(new GridLayout(0, 3, 5, 5)); this.closeButton = new JButton(); this.closeButton.setActionCommand("close"); this.closeButton.setText("Close"); this.closeButton.setToolTipText("Accept entries and close dialog."); this.closeButton.addActionListener(this); this.cancelButton = new JButton(); this.isCancelled = false; this.cancelButton.setActionCommand("cancel"); this.cancelButton.setText("Cancel"); this.closeButton.setToolTipText("Reject entries and close dialog."); this.cancelButton.addActionListener(this); this.helpButton = new JButton(); this.helpButton.setActionCommand("help"); this.helpButton.setText("Help"); this.helpButton.addActionListener(this); this.buttonPanel.add(this.closeButton); this.buttonPanel.add(this.cancelButton); this.buttonPanel.add(this.helpButton); this.contentPane.add(this.rulePanel, BorderLayout.CENTER); this.contentPane.add(this.buttonPanel, BorderLayout.SOUTH); this.contentPane.revalidate(); setContentPane(this.contentPane); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); validate(); pack(); } /** Exit the Application */ void exitForm(WindowEvent evt) { setVisible(false); dispose(); } public void showGUI() { setVisible(true); } @SuppressWarnings("rawtypes") private void acceptValues() { Hashtable<Rule, Pair<Integer, String>> table = ((HashTableModel) this.ruleTable.getModel()).getTable(); for (Enumeration<Rule> e = table.keys(); e.hasMoreElements();) { Rule key = e.nextElement(); Integer l = (Integer) ((Pair) table.get(key)).first; key.setLayer(l.intValue()); String trigger = (String) ((Pair) table.get(key)).second; if (trigger.equals("")) key.setTriggerForLayer(false); else key.setTriggerForLayer(true); } } /** * This handels the clicks on the different buttons. * * @param e * The event from the buttons. */ public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (source == this.closeButton) { acceptValues(); setVisible(false); if (this.helpBrowser != null) { this.helpBrowser.setVisible(false); this.helpBrowser.dispose(); } dispose(); } else if (source == this.cancelButton) { this.isCancelled = true; setVisible(false); if (this.helpBrowser != null) { this.helpBrowser.setVisible(false); this.helpBrowser.dispose(); } dispose(); } else if (source == this.helpButton) { if (this.isModal()) this.setModal(false); if (this.helpBrowser == null) { if (this.isModal()) { this.setModal(false); this.setAlwaysOnTop(true); } this.helpBrowser = new HtmlBrowser("TriggerRuleHelp.html"); this.helpBrowser.setSize(500, 300); this.helpBrowser.setLocation(50, 50); this.helpBrowser.setVisible(true); } else { this.helpBrowser.setVisible(true); } } } public void setGraGra(EdGraGra gra) { this.gragra = gra; } public boolean isCancelled() { return this.isCancelled; } private int getHeight(int rowCount, int rowHeight) { int h = (rowCount + 1) * rowHeight; if (rowCount > 10) h = (10 + 2) * rowHeight; return h; } @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } /* 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); } */ }