/* * JFLAP - Formal Languages and Automata Package * * * Susan H. Rodger * Computer Science Department * Duke University * August 27, 2009 * Copyright (c) 2002-2009 * All rights reserved. * JFLAP is open source software. Please see the LICENSE for terms. * */ package gui.grammar.parse; import java.awt.BorderLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import grammar.Grammar; import grammar.parse.BruteParser; import grammar.parse.BruteParserEvent; import grammar.parse.BruteParserListener; import grammar.parse.ParseNode; import grammar.parse.Unrestricted; import grammar.parse.UserParser; import gui.SplitPaneFactory; import gui.TableTextSizeSlider; import gui.environment.GrammarEnvironment; import gui.grammar.GrammarTable; import gui.grammar.GrammarTableModel; import gui.sim.multiple.InputTableModel; import javax.swing.*; import javax.swing.table.DefaultTableModel; import javax.swing.tree.TreeNode; /** * This class created GUI pane for UserControl Parsing. * This pane is similar to BruteParsePane, but it has more additional features * * @author Kyung Min (Jason) Lee */ public class UserControlParsePane extends BruteParsePane { /** The parser that is going to be used **/ private UserParser myParser; /** Index of the selected production rule **/ private int mySelectedProductionIndex=-1; /** The action for the stepping control. */ private Action myPreviousAction; /** Variable to store how many times Step button is clicked **/ private int myStepCount=0; /** Variable to store how many times Previous button is clicked **/ private int myPreviousCount=0; /** DefaultListModel to show current string at the bottom of the pane **/ private DefaultListModel myJListModel; /** JList to show the current string and allow user to click on the variables **/ private JList myStringJList; /** Target string that user is trying to derive **/ private String myTarget; /** * Constructor for User Control Parse Pane * calls the super class's constructor * @param environment * @param grammar */ public UserControlParsePane(GrammarEnvironment environment, Grammar grammar) { super(environment, grammar, null); intializeGrammarTableSetting(); } /** * Initialize the view */ protected void initView() { initTreePanel(); // Sets up the displays. JComponent pt = initParseTable(); JScrollPane parseTable = pt == null ? null : new JScrollPane(pt); GrammarTable g = initGrammarTable(grammar); JScrollPane grammarTable = new JScrollPane(g); myJListModel=new DefaultListModel(); myStringJList=new JList(myJListModel); myStringJList.setLayoutOrientation(JList.HORIZONTAL_WRAP); addMultipleSelectionToJList(); myStringJList.setVisibleRowCount(1); JScrollPane scroll=new JScrollPane(myStringJList); treeDerivationPane.add(initTreePanel(), "0"); derivationPane = new JScrollPane(initDerivationTable()); treeDerivationPane.add(derivationPane, "1"); bottomSplit = SplitPaneFactory.createSplit(environment, true, 0.3, grammarTable, treeDerivationPane); topSplit = SplitPaneFactory.createSplit(environment, true, 0.4, parseTable, initInputPanel()); bottomSplit=SplitPaneFactory.createSplit(environment, false, 0.52, bottomSplit, scroll); mainSplit = SplitPaneFactory.createSplit(environment, false, 0.3, topSplit, bottomSplit); add(mainSplit, BorderLayout.CENTER); add(statusDisplay, BorderLayout.SOUTH); add(new TableTextSizeSlider(g), BorderLayout.NORTH); } /** * Add multiple selection to be possible without clicking Ctrl or Shift button * */ private void addMultipleSelectionToJList() { myStringJList.setSelectionModel(new DefaultListSelectionModel() { public void setSelectionInterval(int index0, int index1) { if (isSelectedIndex(index0)) super.removeSelectionInterval(index0, index1); else super.addSelectionInterval(index0, index1); } } ); } /** * Initialize the grammar table setting, * and add Listeners so that we can track what user has clicked. * */ private void intializeGrammarTableSetting() { grammarTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); grammarTable.addKeyListener(new KeyListener(){ public void keyPressed(KeyEvent e) { } // when user realease a key that means user might or might not selected an item from the list public void keyReleased(KeyEvent e) { mySelectedProductionIndex=grammarTable.getSelectedRow(); if (mySelectedProductionIndex>-1 && mySelectedProductionIndex-1 && mySelectedProductionIndex0) statusDisplay.setText("Derived current Strings using "+previous.getProductions()[0]+" production"); else statusDisplay.setText(""); myPreviousCount++; if (myStepCount==myPreviousCount) { myPreviousAction.setEnabled(false); myStepCount=0; myPreviousCount=0; } stepAction.setEnabled(true); progress.setText(null); } /** * Returns the tool bar for the main user input panel. * * @return the tool bar for the main user input panel */ protected JToolBar initInputToolbar() { JToolBar toolbar = new JToolBar(); toolbar.add(startAction); myPreviousAction = new AbstractAction("Previous") { public void actionPerformed(ActionEvent e) { previous(); } }; myPreviousAction.setEnabled(false); toolbar.add(myPreviousAction); stepAction.setEnabled(false); toolbar.add(stepAction); // Set up the view customizer controls. toolbar.addSeparator(); final JComboBox box = new JComboBox(getViewChoices()); box.setSelectedIndex(0); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { changeView((String) box.getSelectedItem()); } }; box.addActionListener(listener); toolbar.add(box); return toolbar; } /** * This method is called when the step button is pressed. */ public boolean step() { // controller.step(); int count=myParser.checkValidAndParse(grammarTable.getSelectedRow()); String lhs=myParser.getLHSForProduction(grammarTable.getSelectedRow()); int length=lhs.length(); int index=-1; if (count>0) { if (count>1) { // Multiple variable but user did not specify one if (myStringJList.getSelectedIndex()<0) { JOptionPane.showMessageDialog(this,"Multiple Variable Detected, Please click the Variable you want to continue", "Select Variable", JOptionPane.ERROR_MESSAGE); return false; } else { String temp=""; int[] tempIndices=myStringJList.getSelectedIndices(); int tempCount=0; for (int i=0; i0) statusDisplay.setText("Derived current Strings using "+answer.getProductions()[0]+" production"); else statusDisplay.setText(""); if (myParser.isStringTerminal(answer.getDerivation())) { progress.setText("No Additional Production is Possible"); stepAction.setEnabled(false); } } /** * Add current string to the JList to show to the user * @param answer the current String that is going to be displayed at the bottom of the pane */ private void addAnswerToList(String answer) { myJListModel.removeAllElements(); for (int i=0; i