/*
* 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;
import grammar.Grammar;
import grammar.Production;
import gui.GrowableTableModel;
import java.util.ArrayList;
import javax.swing.Icon;
/**
* The GrammarTableModel
is used as a model for the input of a
* grammar. The first column is the left hand side of a production, the second
* middle column is reserved for a little icon that has a little arrow pointing
* to the right, and the third and last column is the right hand side of the
* production. Each row corresponds to a production, or to nothing if what is in
* the table is not properly a production.
*
* @see grammar.Production
*
* @author Thomas Finley
*/
public class GrammarTableModel extends GrowableTableModel {
/**
* Instantiates a GrammarTableModel
.
*/
public GrammarTableModel() {
super(3);
}
/**
* Instantiates a GrammarTableModel
.
*
* @param grammar
* the grammar to have for the grammar table model initialized to
*/
public GrammarTableModel(Grammar grammar) {
this();
Production[] ps = grammar.getProductions();
for (int i = 0; i < ps.length; i++)
addProduction(ps[i]);
}
/**
* This adds a production to the grammar table model.
*
* @param production
* the production to add to the data
* @return the row number where the production was added
*/
public int addProduction(Production production) {
int row = getRowCount() - 1;
setValueAt(production.getLHS(), row, 0);
setValueAt(production.getRHS(), row, 2);
return row;
}
/**
* This adds a production to the grammar table model at a specified index.
*
* @param production
* the production to add to the data
* @param row
* the row number to insert the production at
* @return the row where the data was added
*/
public int addProduction(Production production, int row) {
Object[] o = initializeRow(row);
o[0] = production.getLHS();
o[2] = production.getRHS();
insertRow(o, row);
return row;
}
/**
* Returns an empty string for each name.
*
* @param column
* the index of the column
* @return the empty string
*/
public String getColumnName(int column) {
return "";
}
/**
* Returns the production at a row.
*
* @param row
* the row to get the production for
* @return the production at this row, or null
if what is
* there is not properly a production
*/
public Production getProduction(int row) {
String lhs = (String) getValueAt(row, 0);
if (lhs.equals(""))
return null;
return new Production(lhs, (String) getValueAt(row, 2));
}
/**
* Returns an array containing all the productions. If a particular row does
* not have a valid production, it is skipped. In this way, index i
* of the array does not necessarily correspond to row i
of
* the model.
*
* @return an array of the productions
*/
public Production[] getProductions() {
ArrayList list = new ArrayList();
for (int i = 0; i < getRowCount() - 1; i++) {
Production production = getProduction(i);
if (production != null)
list.add(production);
}
return (Production[]) list.toArray(new Production[0]);
}
/**
* Everything in the table model is editable except for the middle arrow.
*
* @param row
* the index for the row
* @param column
* the index for the column
* @return true
if and only if this is a column other than
* the middle column, which is column index 1
*/
public boolean isCellEditable(int row, int column) {
return column != 1;
}
/**
* Initializes a row. For this particular object, a row is two strings
* surrounding an icon.
*
* @param row
* the row we're initializing, which is ignored
* @return an array containing the column entries for this new row
*/
protected Object[] initializeRow(int row) {
Object[] newRow = { "", ARROW, "" };
return newRow;
}
/**
* Returns the class of each column, which is a string for both the right
* and left hand sides, and an icon for the middle.
*
* @param column
* the column to get the class for
*/
public Class getColumnClass(int column) {
return column == 1 ? Icon.class : String.class;
}
/**
* Returns the object at a particular location in the model. This is
* overridden to see that the arrow does not display itself in the last
* column.
*
* @param row
* the row of the object to retrieve
* @param column
* the column of the object to retrieve
* @return the object at that location
*/
public Object getValueAt(int row, int column) {
if (column == 1 && row == getRowCount() - 1)
return null;
return super.getValueAt(row, column);
}
/**
* The arrow icon. This is simply the item returned for the second column.
*/
private static Icon ARROW = new ArrowIcon(20, 8);
}