/*
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.table;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
import com.jstatcom.equation.CoeffTable;
import com.jstatcom.model.JSCNArray;
import com.jstatcom.util.UMatrix;
/**
* The DataTablePopupTypes class defines different popups that
* can be used by data tables. This class can be extended to provide special
* popup menus in a certain context on a JSCDataTable.
*
* It implements the typesave enum pattern (Joshua Bloch, "Effective
* Java", Item 21) . If you compare DataTablePopupTypes,
* always use the == operator. This is save, because they are
* Singletons (Gamma et al., 1995) .
*
* @author Markus Kraetzig
*/
public abstract class JSCPopupTypes extends JPopupMenu implements
ActionListener {
/**
* The name of the popupType.
*/
private final String name;
private Component dataTable = null;
/**
* PopupMenu for click change between * and 0. If a subset
* restriction is set, the corresponding element is not changed.
*/
public static final JSCPopupTypes CLICK_01 = new JSCPopupTypes("CLICK_01") {
{
JMenuItem menuItem = add("Set to '0'");
menuItem.addActionListener(this);
menuItem.setActionCommand("0");
//
menuItem = add("Set to '*'");
menuItem.addActionListener(this);
menuItem.setActionCommand("*");
//
pack();
}
public void actionPerformed(ActionEvent e) {
if (!(getDataTable() instanceof JSCNArrayTable))
return;
JSCNArrayTable table = (JSCNArrayTable) getDataTable();
JSCNArray dataObject = table.getJSCNArray();
int r = dataObject.rows();
int c = dataObject.cols();
if (r > 0 && c > 0) {
String actionCommand = e.getActionCommand();
if (actionCommand == null)
return;
int v;
if (actionCommand.equals("0"))
v = 0;
else if (actionCommand.equals("*"))
v = 1;
else
return; // unknown action command
if (table instanceof CoeffTable) {
CoeffTable coeffTable = (CoeffTable) table;
int start = coeffTable.getSubMatModel().getIndex()
* coeffTable.getSubMatModel().getNumberOfColumns();
for (int i = start; i < start
+ coeffTable.getSubMatModel().getNumberOfColumns(); i++)
for (int j = 0; j < dataObject.rows(); j++)
// Check if subset restriction is set
if (!isSubsetRes(coeffTable, j, i))
dataObject.setValAt(v, j, i);
return;
}
/**
* Here no CoefficientsTable is set.
*/
double[][] newValues = UMatrix.ones(r, c);
newValues = UMatrix.multiply(newValues, v);
dataObject.setVal(newValues);
}
}
};
/**
* PopupMenu for click change between * , 0 and !. If a
* subset restriction is set, the corresponding element is not changed.
*/
public static final JSCPopupTypes CLICK_012 = new JSCPopupTypes("CLICK_012") {
{
JMenuItem menuItem = add("Set to '0'");
menuItem.addActionListener(this);
menuItem.setActionCommand("0");
//
menuItem = add("Set to '*'");
menuItem.addActionListener(this);
menuItem.setActionCommand("*");
//
menuItem = add("Set to '!'");
menuItem.addActionListener(this);
menuItem.setActionCommand("!");
pack();
}
public void actionPerformed(ActionEvent e) {
if (!(getDataTable() instanceof JSCNArrayTable))
return;
JSCNArrayTable table = (JSCNArrayTable) getDataTable();
JSCNArray dataObject = table.getJSCNArray();
int r = dataObject.rows();
int c = dataObject.cols();
if (r > 0 && c > 0) {
String actionCommand = e.getActionCommand();
if (actionCommand == null)
return;
int v;
if (actionCommand.equals("0"))
v = 0;
else if (actionCommand.equals("*"))
v = 1;
else if (actionCommand.equals("!"))
v = 2;
else
return; // unknown action command
if (table instanceof CoeffTable) {
CoeffTable coeffTable = (CoeffTable) getDataTable();
int start = coeffTable.getSubMatModel().getIndex()
* coeffTable.getSubMatModel().getNumberOfColumns();
for (int i = start; i < start
+ coeffTable.getSubMatModel().getNumberOfColumns(); i++)
for (int j = 0; j < dataObject.rows(); j++)
// Check if subset restriction is set
if (!isSubsetRes(coeffTable, j, i))
dataObject.setValAt(v, j, i);
return;
}
/**
* Here no CoefficientsTable is set.
*/
double[][] newValues = UMatrix.ones(r, c);
newValues = UMatrix.multiply(newValues, v);
dataObject.setVal(newValues);
}
}
};
/**
* PopupMenu for precision change, as well as to toggle the
* use of scientific representation of numbers.
*/
public static final JSCPopupTypes PRECISION = new JSCPopupTypes("PRECISION") {
private String increase = "Increase Precision";
private String decrease = "Decrease Precision";
private String scientific = "Scientific On/Off";
{
JMenuItem menuItem = add(increase);
menuItem.addActionListener(this);
menuItem.setActionCommand(increase);
menuItem = add(decrease);
menuItem.addActionListener(this);
menuItem.setActionCommand(decrease);
menuItem = add(scientific);
menuItem.addActionListener(this);
menuItem.setActionCommand(scientific);
pack();
}
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
Component table = getDataTable();
if (table instanceof NumberDisplayTable) {
NumberDisplayTable nTable = (NumberDisplayTable) table;
if (actionCommand.equals(increase)) {
int oldPrecision = nTable.getPrecision();
nTable.setPrecision(oldPrecision + 1);
return;
}
if (actionCommand.equals(decrease)) {
int oldPrecision = nTable.getPrecision();
nTable.setPrecision(Math.max(oldPrecision - 1, 0));
return;
}
if (actionCommand.equals(scientific)) {
if (nTable instanceof CoeffTable) {
// here the COEFF_DEFAULT renderers are used which
// take subset res into account
if (nTable.getCellRenderer() == JSCCellRendererTypes.COEFF_DEFAULT)
nTable
.setCellRenderer(JSCCellRendererTypes.COEFF_SCIENTIFIC);
else
nTable
.setCellRenderer(JSCCellRendererTypes.COEFF_DEFAULT);
} else {
if (nTable.getCellRenderer() == JSCCellRendererTypes.DEFAULT)
nTable
.setCellRenderer(JSCCellRendererTypes.SCIENTIFIC);
else
nTable
.setCellRenderer(JSCCellRendererTypes.DEFAULT);
}
}
}
}
};
/**
* PopupMenu for precision change.
*/
public static final JSCPopupTypes PRECISION_NOSCIENTIFIC = new JSCPopupTypes(
"PRECISION_NOSCIENTIFIC") {
private String increase = "Increase Precision";
private String decrease = "Decrease Precision";
{
JMenuItem menuItem = add(increase);
menuItem.addActionListener(this);
menuItem.setActionCommand(increase);
menuItem = add(decrease);
menuItem.addActionListener(this);
menuItem.setActionCommand(decrease);
pack();
}
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
Component table = getDataTable();
if (table instanceof NumberDisplayTable) {
NumberDisplayTable nTable = (NumberDisplayTable) table;
if (actionCommand.equals(increase)) {
int oldPrecision = nTable.getPrecision();
nTable.setPrecision(oldPrecision + 1);
return;
}
if (actionCommand.equals(decrease)) {
int oldPrecision = nTable.getPrecision();
nTable.setPrecision(Math.max(oldPrecision - 1, 0));
return;
}
}
}
};
/**
* Creates a DataTablePopupTypes with a descriptive name.
*/
protected JSCPopupTypes(String name) {
super();
this.name = name;
}
/**
* DataTablePopupTypes implement ActionListener
* and can therefore register themselves as listeners, for example with the
* menu items that are added to them. Subclasses can overwrite the empty
* default implementation of this method.
*
* @param evt
* the action event
*/
public void actionPerformed(ActionEvent evt) {
}
/**
* Override prevention method to enforce a.equals(b) if and
* only if a==b.
*
* @param o
* object to compare with
* @return true if equal, false otherwise
*/
public final boolean equals(Object o) {
return super.equals(o);
}
/**
* Gets a reference to the unterlying data table.
*
* @return the data table
*/
public final Component getDataTable() {
return dataTable;
}
/**
* Gets the name of this type.
*
* @return a descriptive name
*/
public final String getName() {
return name;
}
/**
* Override prevention method invokes super method.
*
* @return hash code
*/
public final int hashCode() {
return super.hashCode();
}
/**
* Checks, whether there is a subset restriction at the given position
* (row, col) in the subset restriction matrix. The subset
* matrix must be referenced from the data table implementation, for example
* com.jstatcom.equation.CoefficientsTable.
*
* @param table
* the data table with a possible reference to a subset matrix
* @param row
* index for row
* @param col
* index for column
* @return true if the corresponding subset matrix exists and
* the element at (row, col) is set to restricted
* @see com.jstatcom.equation.CoeffTable
*/
protected final boolean isSubsetRes(CoeffTable table, int row, int col) {
JSCNArray subsetRes = table.getJSCNArraySubsetRes();
if (subsetRes != null) {
// Check for restriction. If 0 then element is restricted.
if (row < subsetRes.rows() && col < subsetRes.cols())
return subsetRes.intAt(row, col) == 0;
}
return false;
}
/**
* Triggers the popup menu if the invoker was a JSCDataTable
* with a number type.
*
* @param e
* the mouse event
* @param path
* can be null in this context
* @param manager
* can be null in this context
*/
public void processMouseEvent(MouseEvent e, MenuElement[] path,
MenuSelectionManager manager) {
if (!SwingUtilities.isRightMouseButton(e))
return;
Component c = e.getComponent();
// Show only for NumberDisplayTable.
if (c instanceof NumberDisplayTable) {
setDataTable(c);
pack();
show(c, e.getX(), e.getY());
}
}
/**
* Sets a reference to the unterlying data table.
*
* @param newDataTable
* the data table
*/
public final void setDataTable(Component newDataTable) {
dataTable = newDataTable;
}
/**
* Gets a string representing this type, do not use for comparisons.
*
* @return string representation
*/
public final String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getClass().getName() + "[name=" + name);
for (int i = 0; i < getComponentCount(); i++)
buffer.append("," + getComponent(i).getName());
buffer.append("]");
return buffer.toString();
}
}
Ads help maintain this website.