/*
This file is part of the software framework JStatCom,
a library for building applications for data based analysis.
Copyright (C) 2000-2005 Markus Kraetzig
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
*/
package com.jstatcom.equation;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellRenderer;
import com.jstatcom.model.JSCTypeDef;
import com.jstatcom.model.JSCTypes;
import com.jstatcom.model.Scope;
import com.jstatcom.model.Symbol;
import com.jstatcom.model.SymbolEvent;
import com.jstatcom.model.SymbolListener;
import com.jstatcom.model.SymbolTable;
import com.jstatcom.table.JSCPopupTypes;
/**
* Implementation of EqTerm that represents one or more lags of a
* (Vector) AR model.
*
* Clients should make sure that the underlying data objects have the correct
* dimensions and ordering of variables for the display to be in sync with the
* data.
*
* @author Alexander Benkwitz, Markus Kraetzig
*
*/
public final class EqTermAR extends EqTerm implements PropertyChangeListener,
SymbolListener {
private EqTermDefault firstTerm = null;
private JSCTypeDef lagsDef = null;
private List allTerms;
private boolean addTermsToParent = true;
private EqPanel equationPanelParent = null;
private JPopupMenu tablePopup = JSCPopupTypes.PRECISION;
private Symbol lagsSymbol = null;
/**
* Constructor.
*/
public EqTermAR() {
super(new FlowLayout(FlowLayout.LEFT, 0, 0));
allTerms = new ArrayList();
firstTerm = new EqTermDefault();
allTerms.add(firstTerm);
firstTerm.addPropertyChangeListener(this);
firstTerm.setCoeffMatRequired(true);
firstTerm.setOpaque(false);
firstTerm.setVisible(false);
add(firstTerm);
}
/**
* Calls supermethod and updates layout in a new thread. It also set the
* symboltables for the childs.
*/
public void addNotify() {
super.addNotify();
Component parent = getParent();
if (parent != null && parent instanceof EqPanel)
equationPanelParent = (EqPanel) parent;
// this method must be called in a new thread, otherwise problems might
// result (the real dangerous thing is to run updateLayout() in the
// same command stack as addNotify()
Runnable thread = new Runnable() {
public void run() {
updateLagsSymbol();
}
};
SwingUtilities.invokeLater(thread);
}
/**
* Gets the column width of the alpha table.
*
* @return column width
*/
public int getColumnWidth() {
return ((EqTermDefault) allTerms.get(0)).getColumnWidth();
}
/**
* Gets the mouse listener of the underlying coefficients tables.
*
* @return java.awt.event.MouseListener
*/
public MouseListener getMouseListenerCoeff() {
return ((EqTermDefault) allTerms.get(0)).getMouseListenerCoeff();
}
/**
* Gets the precision of the underlying coefficients tables.
*
* @return precision
*/
public int getPrecision() {
return ((EqTermDefault) allTerms.get(0)).getPrecision();
}
/**
* Gets the cell renderer of the underlying coefficients tables.
*
* @return javax.swing.table.TableCellRenderer
*/
public TableCellRenderer getRendererCoeff() {
return ((EqTermDefault) allTerms.get(0)).getRendererCoeff();
}
/**
* Gets the lag that this equation term starts with. Usually this is -1.
*
* @return int start lag
*/
public int getStartLag() {
return -1 * ((EqTermDefault) allTerms.get(0)).getLagIndex();
}
/**
* Gets the symbolname for the coefficients.
*
* @return symbol name
*/
public String getSymbolNameCoeff() {
return ((EqTermDefault) allTerms.get(0)).getSymbolNameCoeff();
}
/**
* Gets the symbolname for the lags. Ther underlying data must be a
* JSCInt.
*
* @return symbol name
*/
public String getSymbolNameLags() {
if (lagsDef == null)
return null;
return lagsDef.name;
}
/**
* Gets the symbolname for the subset restrictions corresponding to the
* coefficients.
*
* @return symbol name
*/
public String getSymbolNameSubsetRes() {
return ((EqTermDefault) allTerms.get(0)).getSymbolNameSubsetRes();
}
/**
* Gets the symbolname for the names of the variables.
*
* @return symbol name
*/
public String getSymbolNameVariables() {
return ((EqTermDefault) allTerms.get(0)).getSymbolNameVariables();
}
/**
* Gets the popup menu for the underlying coefficients tables.
*
* @return popup menu
*/
public JPopupMenu getTablePopup() {
return tablePopup;
}
/**
* Gets whether the underlying coefficients tables are editable.
*
* @return true if editable
*/
public boolean isEditable() {
return ((EqTermDefault) allTerms.get(0)).isEditable();
}
/**
* Manages visibility of tis term.
*
* @param evt
* property change event
*/
public void propertyChange(java.beans.PropertyChangeEvent evt) {
if (evt.getSource().equals(allTerms.get(0))
&& evt.getPropertyName() == "visible") {
// also sets term visible/invisible
setDataAvailable(((Boolean) evt.getNewValue()).booleanValue());
}
}
/**
* Sets the column width of the underlying coefficients tables.
*
* @param colWidth
* column width
*/
public void setColumnWidth(int colWidth) {
for (int i = 0; i < allTerms.size(); i++)
((EqTermDefault) allTerms.get(i)).setColumnWidth(colWidth);
}
/**
* Sets whether the underlying coefficients tables are editable.
*
* @param isEditable
* true if editable
*/
public void setEditable(boolean isEditable) {
for (int i = 0; i < allTerms.size(); i++)
((EqTermDefault) allTerms.get(i)).setEditable(isEditable);
}
/**
* Manages visibility of the leading sign label.
*
* @param isVisible
* true if visible
*/
public void setLeadingSignVisible(boolean isVisible) {
((EqTermDefault) allTerms.get(0)).setLeadingSignVisible(isVisible);
}
/**
* Sets the symbol scope, which defines which symbol table to use (
* local,global or upper).
*
* @param scope
* the symbol scope
* @throws IllegalArgumentException
* if (scope == null)
*/
public void setSymbolScope(Scope scope) {
super.setSymbolScope(scope);
for (int i = 0; i < allTerms.size(); i++)
allTerms.get(i).setSymbolScope(scope);
updateLagsSymbol();
}
/**
* Sets the mouse listener for the underlying coefficients tables.
*
* @param listener
* java.awt.event.MouseListener
*/
public void setMouseListenerCoeff(MouseListener listener) {
for (int i = 0; i < allTerms.size(); i++)
((EqTermDefault) allTerms.get(i)).setMouseListenerCoeff(listener);
}
/**
* Sets the precision for the underlying coefficients tables.
*
* @param precision
*/
public void setPrecision(int precision) {
for (int i = 0; i < allTerms.size(); i++)
((EqTermDefault) allTerms.get(i)).setPrecision(precision);
}
/**
* Sets the cell renderer for the underlying coefficients tables.
*
* @param renderer
* javax.swing.table.TableCellRenderer
*/
public void setRendererCoeff(TableCellRenderer renderer) {
for (int i = 0; i < allTerms.size(); i++)
((EqTermDefault) allTerms.get(i)).setRendererCoeff(renderer);
}
/**
* Sets with which lag the equation term starts with. Only backward lags are
* supported, meaning that startLag must greater or equal to zero.
*
* @param startLag
* lag to start from
* @throws IllegalArgumentException
* if (startLag < 0)
*/
public void setStartLag(int startLag) {
if (startLag < 0)
throw new IllegalArgumentException("Start lag " + startLag
+ " < 0.");
((EqTermDefault) allTerms.get(0)).setLagIndex(-1 * startLag);
}
/**
* Sets the symbolname for the coefficients.
*
* @param symbolName
* for coefficients
*/
public void setSymbolNameCoeff(String symbolName) {
for (int i = 0; i < allTerms.size(); i++)
((EqTermDefault) allTerms.get(i)).setSymbolNameCoeff(symbolName);
}
/**
* Sets the symbolname for the lags. Ther underlying data must be a
* JSCInt.
*
* @param newSymbolNameLags
*/
public void setSymbolNameLags(String newSymbolNameLags) {
if (lagsSymbol != null)
lagsSymbol.removeSymbolListener(this);
if (newSymbolNameLags == null) {
lagsDef = null;
return;
}
lagsDef = new JSCTypeDef(newSymbolNameLags, JSCTypes.INT);
updateLagsSymbol();
}
/**
* Sets the symbolname for the subset restrictions corresponding to the
* coefficients.
*
* @param symbolName
* for subset restrictions
*/
public void setSymbolNameSubsetRes(String symbolName) {
for (int i = 0; i < allTerms.size(); i++)
((EqTermDefault) allTerms.get(i))
.setSymbolNameSubsetRes(symbolName);
}
/**
* Sets the symbolname for the names of the variables.
*
* @param symbolName
* for the variable names
*/
public void setSymbolNameVariables(String symbolName) {
for (int i = 0; i < allTerms.size(); i++)
((EqTermDefault) allTerms.get(i))
.setSymbolNameVariables(symbolName);
}
/**
* Sets the popup menu for the underlying coefficients tables.
*
* @param newTablePopup
* popup component
*/
public void setTablePopup(JPopupMenu newTablePopup) {
tablePopup = newTablePopup;
for (int i = 0; i < allTerms.size(); i++) {
((EqTermDefault) allTerms.get(i)).setTablePopup(tablePopup);
}
}
/**
* Manage layout of components.
*/
private void updateLayout() {
if (lagsSymbol == null)
return;
if (lagsSymbol.isEmpty()) {
updateVisibility(-1);
return;
}
int oldNumber = allTerms.size();
int newNumber = lagsSymbol.getJSCInt().intVal();
int startLag = getStartLag();
newNumber = newNumber - startLag + 1;
if (oldNumber < newNumber) {
String variableNames = getSymbolNameVariables();
String coefficientNames = getSymbolNameCoeff();
String subsetRestrictionsNames = getSymbolNameSubsetRes();
int columnWidth = getColumnWidth();
int precision = getPrecision();
boolean editable = isEditable();
MouseListener mouseListener = getMouseListenerCoeff();
for (int i = oldNumber; i < newNumber; i++) {
EqTermDefault newEquationTerm = new EqTermDefault(i, -1
* (i + startLag));
newEquationTerm.setSymbolNameCoeff(coefficientNames);
newEquationTerm.setSymbolNameSubsetRes(subsetRestrictionsNames);
newEquationTerm.setSymbolNameVariables(variableNames);
newEquationTerm.setCoeffMatRequired(true);
newEquationTerm.setOpaque(false);
newEquationTerm.setColumnWidth(columnWidth);
newEquationTerm.setPrecision(precision);
newEquationTerm.setEditable(editable);
newEquationTerm.setSymbolScope(getSymbolScope());
newEquationTerm.setTablePopup(tablePopup);
newEquationTerm.setMouseListenerCoeff(getMouseListenerCoeff());
newEquationTerm.setRendererCoeff(getRendererCoeff());
if (mouseListener != null)
newEquationTerm.setMouseListenerCoeff(mouseListener);
//
if (addTermsToParent && equationPanelParent != null) {
Component[] c = equationPanelParent.getComponents();
int offset = 0;
for (; offset < c.length; offset++) {
if (c[offset].equals(this))
break;
}
int j = offset;
if (allTerms.size() > 1) {
j = j + 1;
Object lastTerm = allTerms.get(allTerms.size() - 1);
for (; j < c.length; j++) {
if (c[j].equals(lastTerm))
break;
}
}
j = j + 1;
if (c.length <= j)
j = -1;
equationPanelParent.add(newEquationTerm, j);
} else {
add(newEquationTerm);
}
allTerms.add(newEquationTerm);
}
}
updateVisibility(newNumber);
}
/**
* Manages visibility of components.
*
* @param arg
* to updated only index from arg onwards
*/
private void updateVisibility(int arg) {
int n = allTerms.size();
boolean doNotRevalidate = true;
for (int i = 0; i < n; i++) {
EqTerm et = allTerms.get(i);
boolean wasVisible = et.isVisible();
et.setVisible(i < arg);
doNotRevalidate = doNotRevalidate && (et.isVisible() == wasVisible);
}
if (!doNotRevalidate) {
if (addTermsToParent) {
if (equationPanelParent != null)
equationPanelParent.revalidate();
} else {
revalidate();
}
}
}
/**
* Updates layout on symbol events of the underlying lag symbol.
*
* @param evt
* symbol event
*/
public void valueChanged(SymbolEvent evt) {
lagsSymbol = evt.getSource();
updateLayout();
}
private void updateLagsSymbol() {
SymbolTable sTable = getSymbolScope().getSymbolTable(EqTermAR.this);
if (sTable != null && lagsDef != null) {
if (lagsSymbol != null)
lagsSymbol.removeSymbolListener(EqTermAR.this);
lagsSymbol = sTable.get(lagsDef);
lagsSymbol.addSymbolListener(EqTermAR.this);
}
updateLayout();
}
}
Ads help maintain this website.