//--------------------------------------------------------------------------------//
// COPYRIGHT NOTICE //
//--------------------------------------------------------------------------------//
// Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) //
// //
// All rights reserved. //
// //
// Redistribution and use in source and binary forms, with or without //
// modification, are permitted provided that the following conditions are met: //
// //
// * Redistributions of source code must retain the above copyright notice, //
// this list of conditions and the following disclaimer. //
// //
// * Redistributions in binary form must reproduce the above copyright //
// notice, this list of conditions and the following disclaimer in the //
// documentation and/or other materials provided with the distribution. //
// //
// * Neither the name of the IMSE-CNM nor the names of its contributors may //
// be used to endorse or promote products derived from this software //
// without specific prior written permission. //
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" //
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE //
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE //
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL //
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR //
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER //
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
//--------------------------------------------------------------------------------//
package xfuzzy.xfedit;
import xfuzzy.lang.*;
import xfuzzy.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
/**
* Modelo de la tabla para la representaci�n de una base de reglas
* en formato libre
*
* @author Francisco Jos� Moreno Velo
*
*/
public class XfeditRulebaseFreeModel extends AbstractTableModel
implements TableCellRenderer {
/**
* C�digo asociado a la clase serializable
*/
private static final long serialVersionUID = 95505666603032L;
//----------------------------------------------------------------------------//
// MIEMBROS PRIVADOS //
//----------------------------------------------------------------------------//
/**
* Etiqueta para representar las celdas de las columnas 0, 2 y 5
*/
private XLabel label;
/**
* Etiqueta para representar las celdas de las columnas 1, 3, y 6
*/
private JLabel text;
/**
* Valor del grado de certeza de cada regla
*/
private double[] degree;
/**
* Editor del antecedente de cada regla
*/
private XfeditRulebaseFreeAntec[] premise;
/**
* Editor del consecuente de cada regla
*/
private XfeditRulebaseFreeConseq[] conclusion;
/**
* Panel de edici�n de la base de reglas en formato libre
*/
private XfeditRulebaseFreePanel panel;
//----------------------------------------------------------------------------//
// CONSTRUCTOR //
//----------------------------------------------------------------------------//
/**
* Constructor
*/
public XfeditRulebaseFreeModel(XfeditRulebaseFreePanel panel, Rulebase copy) {
super();
this.panel = panel;
initialize(copy);
}
//----------------------------------------------------------------------------//
// M�TODOS P�BLICOS //
//----------------------------------------------------------------------------//
/**
* Obtiene el n�mero de columnas de la tabla
*/
public int getColumnCount() {
return 6;
}
/**
* Obtiene el n�mero de filas (reglas) de la tabla
*/
public int getRowCount() {
return degree.length+1;
}
/**
* Obtiene un elemento de la tabla
*/
public Object getValueAt(int row, int column) {
if(column == 0 && row == degree.length) return "*";
if(row == degree.length) return "";
if(column == 0) return ""+row;
if(column == 1) return ""+degree[row];
if(column == 2) return "if";
if(column == 3) return premise[row].toString();
if(column == 4) return "->";
if(column == 5) return conclusion[row];
return "";
}
/**
* Asigna el valor a un elemento de la tabla
*/
public void setValueAt(Object value, int row, int column) {
if(row == degree.length) addRow();
if(column == 1) {
double deg;
try { deg = Double.parseDouble((String) value); }
catch(Exception ex) { deg = -1; }
if(deg <0.0 || deg > 1.0) Toolkit.getDefaultToolkit().beep();
else degree[row] = deg;
}
fireTableCellUpdated(row, column);
}
/**
* Obtiene las reglas representadas en la tabla
*/
public boolean getRules(Rulebase copy) {
copy.removeAllRules();
for(int i=0; i<degree.length; i++) {
if(premise[i].isIncomplete()) return false;
if(conclusion[i].isIncomplete()) return false;
}
for(int i=0; i<degree.length; i++) {
Rule newrule = new Rule(premise[i].getAntecedent(),degree[i]);
Conclusion conc[] = conclusion[i].getConsequents();
for(int j=0; j<conc.length; j++) newrule.add(conc[j]);
copy.addRule(newrule);
}
return true;
}
/**
* Obtiene los t�tulos de las columnas de la tabla
*/
public String getColumnName(int column) {
if(column == 0) return "Rule";
if(column == 1) return "";
if(column == 2) return "";
if(column == 3) return "Premise";
if(column == 4) return "";
if(column == 5) return "Conclusion";
return "";
}
/**
* Obtiene el editor de una celda de la tabla
*/
public TableCellEditor getEditor(int row, int column) {
if(column == 3 && row != degree.length) return premise[row];
if(column == 5 && row != degree.length) return conclusion[row];
return null;
}
/**
* Estudia si la celda es editable
*/
public boolean isCellEditable(int row, int column) {
return (column == 1 || column == 3 || column == 5);
}
/**
* Obtiene el componente que representa cada celda
*/
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if(column == 0 || column == 2 || column == 4)
{ label.setText(value.toString()); return label; }
if(isSelected) {
text.setForeground(table.getSelectionForeground());
text.setBackground(XConstants.textselectedbg);
} else {
text.setForeground(Color.black);
text.setBackground(XConstants.textbackground);
}
text.setText(value.toString());
return text;
}
/**
* Ejecuta una accion sobre el modelo
*/
public void modelAction(int row,int kind) {
if(kind == -2) conclusion[row].conclusionAdd();
else premise[row].action(kind);
}
/**
* Modifica la variable y MF del antecedente seleccionado
*/
public void changePremise(int row, Variable var, LinguisticLabel pmf) {
premise[row].setVariable(var);
premise[row].setMembershipFunction(pmf);
}
/**
* Modifica la variable y MF del consecuente seleccionado
*/
public void changeConclusion(int row, Variable var, LinguisticLabel pmf) {
conclusion[row].setVariable(var);
conclusion[row].setMembershipFunction(pmf);
}
/**
* Elimina una fila (regla) de la tabla
*/
public void removeRow(int row) {
XfeditRulebaseFreeAntec auxpm[];
auxpm = new XfeditRulebaseFreeAntec[degree.length-1];
System.arraycopy(premise,0,auxpm,0,row);
System.arraycopy(premise,row+1,auxpm,row,degree.length-row-1);
premise = auxpm;
XfeditRulebaseFreeConseq auxcn[];
auxcn = new XfeditRulebaseFreeConseq[degree.length-1];
System.arraycopy(conclusion,0,auxcn,0,row);
System.arraycopy(conclusion,row+1,auxcn,row,degree.length-row-1);
conclusion = auxcn;
double auxdeg[] = new double[degree.length - 1];
System.arraycopy(degree,0,auxdeg,0,row);
System.arraycopy(degree,row+1,auxdeg,row,degree.length-row-1);
degree = auxdeg;
fireTableChanged(new TableModelEvent(this, row, row,
TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE));
}
//----------------------------------------------------------------------------//
// M�TODOS PRIVADOS //
//----------------------------------------------------------------------------//
/**
* Inicializa el contenido de la tabla
*/
private void initialize(Rulebase copy) {
label = new XLabel("");
label.setLabelFont(XConstants.textfont);
text = new JLabel("");
text.setFont(XConstants.textfont);
text.setOpaque(true);
Rule[] rule = copy.getRules();
degree = new double[rule.length];
premise = new XfeditRulebaseFreeAntec[rule.length];
conclusion = new XfeditRulebaseFreeConseq[rule.length];
for(int i=0; i<rule.length; i++) {
Rule ruleclone = (Rule) rule[i].clone(copy);
Conclusion[] conclone = ruleclone.getConclusions();
degree[i] = ruleclone.getDegree();
premise[i] = new XfeditRulebaseFreeAntec(panel,ruleclone.getPremise());
conclusion[i] = new XfeditRulebaseFreeConseq(panel,conclone);
}
}
/**
* A�ade una fila (regla) a la tabla
*/
private void addRow() {
XfeditRulebaseFreeAntec auxpm[];
auxpm = new XfeditRulebaseFreeAntec[degree.length+1];
System.arraycopy(premise,0,auxpm,0,degree.length);
auxpm[degree.length] = new XfeditRulebaseFreeAntec(panel,null);
premise = auxpm;
XfeditRulebaseFreeConseq auxcn[];
auxcn = new XfeditRulebaseFreeConseq[degree.length+1];
System.arraycopy(conclusion,0,auxcn,0,degree.length);
auxcn[degree.length] = new XfeditRulebaseFreeConseq(panel,new Conclusion[0]);
conclusion = auxcn;
double auxdeg[] = new double[degree.length + 1];
System.arraycopy(degree,0,auxdeg,0,degree.length);
auxdeg[degree.length] = 1.0;
degree = auxdeg;
fireTableChanged(new TableModelEvent(this, degree.length, degree.length,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
}
}