//--------------------------------------------------------------------------------// // 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 java.awt.*; import java.awt.event.*; import java.util.Vector; /** * Ventana de edici�n de una funci�n de pertenencia * * @author Francisco Jos� Moreno Velo */ public class XfeditMFEditor extends JDialog implements ActionListener, ListCellRenderer, ItemListener { /** * C�digo asociado a la clase serializable */ private static final long serialVersionUID = 95505666603025L; //----------------------------------------------------------------------------// // MIEMBROS PRIVADOS // //----------------------------------------------------------------------------// /** * Lista de campos para introducir los valores de los par�metros */ private XTextForm[] paramform; /** * Campo para introducir el nombre de la funci�n */ private XTextForm labelform; /** * Panel que contiene los campos de los par�metros */ private Box parambox; /** * Men� desplegable para seleccionar la funci�n */ private XComboBox functionform; /** * Panel para representar gr�ficamente la funci�n */ private XfeditTypeGraphPanel mfgraph; /** * Editor de tipos que realiza la llamada a XfeditMFEditor */ private XfeditTypeEditor editor; /** * Objeto original que describe la funci�n de pertenencia a editar */ private LinguisticLabel mforig; /** * Copia de trabajo sobre la que se realizan los cambios * de edici�n de la funci�n de pertenencia */ private LinguisticLabel mfcopy; /** * Objeto Type al que pertenece la funci�n */ private Type type; /** * Indice del campo que permite crear un nuevo par�metro */ private int index; /** * M�nimo n�mero de campos de par�metros */ private int MINSIZE = 5; //----------------------------------------------------------------------------// // CONSTRUCTOR // //----------------------------------------------------------------------------// /** * Constructor */ public XfeditMFEditor(XfeditTypeEditor editor,LinguisticLabel function) { super(editor.getXfedit(),"Xfedit",true); this.editor = editor; this.type = editor.getWorkingCopy(); this.mforig = function; if(function == null) { this.mfcopy = null; } else if(function instanceof ParamMemFunc) { ParamMemFunc pff = (ParamMemFunc) function; ParamMemFunc pmf = (ParamMemFunc) pff.clone(type.getUniverse()); pmf.setLabel(pff.getLabel()); pmf.u = pff.u; this.mfcopy = pmf; } else if(function instanceof FamiliarMemFunc) { FamiliarMemFunc fmf = (FamiliarMemFunc) function; String label = fmf.getLabel(); Family fam = fmf.getFamily(); int index = fmf.getIndex(); this.mfcopy = new FamiliarMemFunc(label,fam,index); } build(); setList(); setData(); } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Interfaz ActionListener */ public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if(command.equals("MFSet")) { setMF(); return; } else if(command.equals("MFRefresh")) { if(getData()) setData(); return; } else if(command.equals("MFCancel")) { setVisible(false); return; } int i = Integer.parseInt(command); if(i > index ) return; if(i == index ) addParameter(); else removeParameter(i); } /** * Interfaz ListCellRenderer */ public Component getListCellRendererComponent( JList list, Object value, int listindex, boolean isSelected, boolean cellHasFocus) { String label; if(listindex == -1 && mfcopy!=null) { if(mfcopy instanceof ParamMemFunc) { ParamMemFunc pmf = (ParamMemFunc) mfcopy; label = pmf.getPackageName()+"."+pmf.getFunctionName(); } else { FamiliarMemFunc fmf = (FamiliarMemFunc) mfcopy; label = ""+fmf.getFamily(); } } else if(listindex == -1) label = " "; else label = value.toString(); JLabel renderer = new JLabel(label); renderer.setForeground(Color.black); renderer.setBackground(XConstants.textbackground); renderer.setOpaque(true); renderer.setFont(XConstants.textfont); return renderer; } /** * Interfaz ItemListener */ public void itemStateChanged(ItemEvent e) { if(functionform.getSelectedItem() == null) return; if(e.getStateChange() != ItemEvent.SELECTED) return; Object item = functionform.getSelectedItem(); if(item instanceof Family) { Family fam = (Family) item; if(mfcopy == null || mfcopy instanceof ParamMemFunc) { mfcopy = new FamiliarMemFunc(labelform.getText(), fam, 0); setData(); } else { FamiliarMemFunc fmfc = (FamiliarMemFunc) mfcopy; if(fmfc.getFamily() != fam) { mfcopy = new FamiliarMemFunc(labelform.getText(), fam, 0); setData(); } } } else { String def = (String) item; int dot = def.indexOf('.'); String pkgname = def.substring(0, dot); String funcname = def.substring(dot+1); if(mfcopy == null || mfcopy instanceof FamiliarMemFunc) { XflPackageBank bank = editor.getXfedit().getXflPackageBank(); ParamMemFunc pmf = (ParamMemFunc) bank.instantiate(pkgname, funcname, XflPackage.MFUNC); pmf.setLabel(labelform.getText()); pmf.u = type.getUniverse(); mfcopy = pmf; setData(); } else { ParamMemFunc pmfc = (ParamMemFunc) mfcopy; if(!pkgname.equals(pmfc.getPackageName()) || !funcname.equals(pmfc.getFunctionName()) ) { XflPackageBank bank = editor.getXfedit().getXflPackageBank(); ParamMemFunc pmf = (ParamMemFunc) bank.instantiate(pkgname, funcname, XflPackage.MFUNC); pmf.setLabel(labelform.getText()); pmf.u = type.getUniverse(); mfcopy = pmf; setData(); } } } functionform.setSelectedItem(null); } //----------------------------------------------------------------------------// // M�TODOS PRIVADOS // //----------------------------------------------------------------------------// /** * Construye la ventana */ private void build() { String label[] = { "Set", "Refresh", "Cancel" }; String command[] = { "MFSet", "MFRefresh", "MFCancel" }; XCommandForm form = new XCommandForm(label, command, this); form.setCommandWidth(130); labelform = new XTextForm("Label"); labelform.setLabelWidth(100); labelform.setFieldWidth(200); labelform.setAlignment(JLabel.CENTER); functionform = new XComboBox("Function"); functionform.setWidth(100,200); functionform.setRenderer(this); functionform.addItemListener(this); Box box1 = new Box(BoxLayout.Y_AXIS); box1.add(labelform); box1.add(functionform); Box labelbox = new Box(BoxLayout.X_AXIS); labelbox.add(Box.createHorizontalStrut(5)); labelbox.add(box1); labelbox.add(Box.createHorizontalStrut(5)); paramform = new XTextForm[MINSIZE]; for(int i=0; i<paramform.length; i++) { paramform[i] = new XTextForm("",this); paramform[i].setEditable(false); paramform[i].setLabelWidth(100); paramform[i].setFieldWidth(200); paramform[i].setFieldEnabled(false); paramform[i].setAlignment(JLabel.CENTER); paramform[i].setActionCommand(""+i); } parambox = new Box(BoxLayout.Y_AXIS); for(int i=0; i<paramform.length; i++) parambox.add(paramform[i]); Box pbox = new Box(BoxLayout.X_AXIS); pbox.add(Box.createHorizontalStrut(5)); pbox.add(parambox); pbox.add(Box.createHorizontalStrut(5)); Box leftbox = new Box(BoxLayout.Y_AXIS); leftbox.add(Box.createVerticalStrut(5)); leftbox.add(labelbox); leftbox.add(Box.createVerticalStrut(5)); leftbox.add(new XLabel("Parameters")); leftbox.add(Box.createVerticalStrut(5)); leftbox.add(new JScrollPane(pbox)); leftbox.add(Box.createVerticalStrut(5)); leftbox.add(Box.createGlue()); this.mfgraph = new XfeditTypeGraphPanel(type,300); Box hbox = new Box(BoxLayout.X_AXIS); hbox.add(Box.createHorizontalStrut(5)); hbox.add(leftbox); hbox.add(Box.createHorizontalStrut(5)); hbox.add(this.mfgraph); hbox.add(Box.createHorizontalStrut(5)); Container content = getContentPane(); content.setLayout(new BoxLayout(content,BoxLayout.Y_AXIS)); content.add(new XLabel("Parameter Selection")); content.add(Box.createVerticalStrut(5)); content.add(hbox); content.add(Box.createVerticalStrut(5)); content.add(Box.createGlue()); content.add(form); content.add(Box.createGlue()); setFont(XConstants.font); pack(); setLocationRelativeTo(editor.getXfedit()); } /** * Actualiza la lista de funciones disponibles */ private void setList() { Vector available = new Vector(); Family fam[] = type.getFamilies(); for(int i=0; i<fam.length; i++) available.addElement(fam[i]); XflPackageBank bank = this.editor.getXfedit().getXflPackageBank(); Vector mfavailable = bank.getFunctionNames(XflPackage.MFUNC); available.addAll(mfavailable); functionform.setList(available); } /** * Actualiza los datos de la funci�n de pertenencia */ private void setData() { if(mfcopy == null) return; labelform.setText(mfcopy.getLabel()); if(mfcopy instanceof ParamMemFunc) { ParamMemFunc pmfc = (ParamMemFunc) mfcopy; Parameter[] single = pmfc.getSingleParameters(); Parameter[] list = pmfc.getParamList(); String listname = pmfc.getParamListName(); if(pmfc.hasParamList()) index = single.length + list.length; else index = single.length; ensureSize(); for(int i=0; i<single.length; i++) { paramform[i].setText(""+single[i].value); paramform[i].setLabel(single[i].getName()); paramform[i].setEditable(true); paramform[i].setFieldEnabled(true); } for(int i=single.length; i<index; i++) { String paramname = listname+"["+(i-single.length)+"]"; paramform[i].setText(""+list[i-single.length].value); paramform[i].setLabel(paramname); paramform[i].setEditable(true); paramform[i].setFieldEnabled(true); } for(int i=index; i<paramform.length; i++) { paramform[i].setText(""); paramform[i].setLabel(""); paramform[i].setEditable(false); paramform[i].setFieldEnabled(false); } if(pmfc.hasParamList()) paramform[index].setLabel("New"); } else { index = 1; ensureSize(); paramform[0].setText(""+((FamiliarMemFunc) mfcopy).getIndex()); paramform[0].setLabel("Index"); paramform[0].setEditable(true); paramform[0].setFieldEnabled(true); for(int i=index; i<paramform.length; i++) { paramform[i].setText(""); paramform[i].setLabel(""); paramform[i].setEditable(false); paramform[i].setFieldEnabled(false); } } mfgraph.setExcluded(mforig); mfgraph.setSelection(mfcopy); mfgraph.repaint(); } /** * Obtiene los datos de la ventana */ private boolean getData() { if(mfcopy == null) return false; boolean numeric = true; mfcopy.setLabel(labelform.getText()); if(mfcopy instanceof ParamMemFunc) { ParamMemFunc pmfc = (ParamMemFunc) mfcopy; Parameter[] single = pmfc.getSingleParameters(); Parameter[] list = pmfc.getParamList(); for(int i=0; i<single.length; i++) { try { single[i].value = Double.parseDouble(paramform[i].getText());} catch (NumberFormatException ex) { paramform[i].setText(""+single[i].value); numeric = false; } } if(pmfc.hasParamList()) for(int i=0; i<list.length; i++) { String text = paramform[i+single.length].getText(); try { list[i].value = Double.parseDouble(text);} catch (NumberFormatException ex) { paramform[i+single.length].setText(""+list[i].value); numeric = false; } } } else { FamiliarMemFunc fmfc = (FamiliarMemFunc) mfcopy; try { fmfc.setIndex( Integer.parseInt(paramform[0].getText()) ); } catch (NumberFormatException ex) { paramform[0].setText(""+fmfc.getIndex()); numeric = false; } } if(!numeric) { XDialog.showMessage(editor,"Not a numeric value"); return false; } if(!mfcopy.test()) { XDialog.showMessage(editor,"Invalid parameters"); return false; } return true; } /** * Redimensiona el panel de par�metros para asegurar que se * puedan editar todos los par�metros de la funci�n de pertenencia */ private void ensureSize() { while(index < paramform.length-1 && paramform.length > MINSIZE) { parambox.remove(paramform[paramform.length-1]); XTextForm at[] = new XTextForm[paramform.length-1]; System.arraycopy(paramform,0,at,0,paramform.length-1); paramform = at; } for(int i=index-paramform.length; i>=0; i--) { XTextForm nt = new XTextForm(" ",this); nt.setLabelWidth(100); nt.setFieldWidth(200); nt.setAlignment(JButton.CENTER); nt.setActionCommand(""+paramform.length); parambox.add(nt); XTextForm at[] = new XTextForm[paramform.length+1]; System.arraycopy(paramform,0,at,0,paramform.length); at[paramform.length] = nt; paramform = at; } } /** * A�ade un campo para un nuevo par�metro */ private void addParameter() { if(mfcopy instanceof FamiliarMemFunc) return; ParamMemFunc pmfc = (ParamMemFunc) mfcopy; if(!pmfc.hasParamList()) return; String listname = pmfc.getParamListName(); Parameter[] list = pmfc.getParamList(); Parameter np = new Parameter(listname); Parameter p[] = new Parameter[list.length+1]; System.arraycopy(list,0,p,0,list.length); p[list.length] = np; pmfc.setParamList(p); index++; ensureSize(); String paramname = listname+"["+(index-1)+"]"; paramform[index-1].setLabel(paramname); paramform[index-1].setEditable(true); paramform[index-1].setFieldEnabled(true); paramform[index].setLabel("New"); paramform[index].setEditable(false); paramform[index].setFieldEnabled(false); } /** * Elimina un campo para introducir un par�metro */ private void removeParameter(int i) { if(mfcopy instanceof FamiliarMemFunc) return; ParamMemFunc pmfc = (ParamMemFunc) mfcopy; if(!pmfc.hasParamList()) return; Parameter[] single = pmfc.getSingleParameters(); Parameter[] list = pmfc.getParamList(); if(i<single.length) return; for(int j=i+1; j<index; j++) { paramform[j-1].setText(paramform[j].getText()); list[j-single.length-1].value = list[j-single.length].value; } Parameter ap[] = new Parameter[list.length-1]; System.arraycopy(list,0,ap,0,list.length-1); pmfc.setParamList(ap); index--; paramform[index].setLabel("New"); paramform[index].setText(""); paramform[index].setEditable(false); paramform[index].setFieldEnabled(false); paramform[index+1].setLabel(""); paramform[index+1].setText(""); ensureSize(); } /** * Actualiza la funci�n de pertenencia y cierra la ventana */ private void setMF() { if(!getData()) return; if(!XConstants.isIdentifier( mfcopy.getLabel() )) { labelform.setText(""); mfcopy.setLabel(""); XDialog.showMessage(editor,"Invalid linguistic label"); return; } LinguisticLabel[] pmf = type.getMembershipFunctions(); for(int i=0; i<pmf.length; i++) if(pmf[i] != mforig && pmf[i].equals(mfcopy.getLabel())) { String msg = "Label "+mfcopy.getLabel()+" already exists"; labelform.setText(""); mfcopy.setLabel(""); XDialog.showMessage(editor,msg); return; } if(mforig == null) editor.addMF(mfcopy); else editor.exchangeMF(mforig,mfcopy); setVisible(false); } }