//--------------------------------------------------------------------------------// // 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 java.awt.*; import java.awt.event.*; /** * Ventana de creaci�n de tipos predefinidos * * @author Francisco Jos� Moreno Velo * */ public class XfeditTypeCreator extends JDialog implements ActionListener, ChangeListener, WindowListener { /** * C�digo asociado a la clase serializable */ private static final long serialVersionUID = 95505666603040L; //----------------------------------------------------------------------------// // MIEMBROS PRIVADOS // //----------------------------------------------------------------------------// /** * Referencia a la aplicaci�n Xfedit que abre la ventana de creaci�n de tipos */ private Xfedit xfeditor; /** * Sistema difuso a editar */ private Specification spec; /** * Lista de componentes de texto para introducir los datos */ private XTextForm dataform[]; /** * Men� desplegable para seleccionar el ancestro de un tipo heredado */ private XComboBox parentform; /** * Lista de bootones de selecci�n entre tipos predefinidos */ private JToggleButton button[]; //----------------------------------------------------------------------------// // CONSTRUCTOR // //----------------------------------------------------------------------------// /** * Constructor */ public XfeditTypeCreator(Xfedit xfeditor){ super(xfeditor,"Xfedit",false); this.xfeditor = xfeditor; this.spec = xfeditor.getSpecification(); build(); } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS EST�TICOS // //----------------------------------------------------------------------------// /** * Abre una ventana de creaci�n de un tipo de variable */ static void showTypeCreator(Xfedit xfeditor) { XfeditTypeCreator editor = new XfeditTypeCreator(xfeditor); editor.setVisible(true); editor.repaint(); } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Interfaz ActionListener */ public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); if(command.equals("Create")) { Type tp = create(); if(tp == null) return; setVisible(false); XfeditTypeEditor.showTypeEditor(xfeditor,tp); } else if(command.equals("Cancel")) setVisible(false); } /** * Interfaz ChangeListener */ public void stateChanged(ChangeEvent e) { AbstractButton button = (AbstractButton) e.getSource(); if(button.isSelected()) { button.setBorder(BorderFactory.createLoweredBevelBorder()); setDataEnabled(); } else button.setBorder(BorderFactory.createRaisedBevelBorder()); } /** * Interfaz WindowListener. Acci�n al abrir la ventana */ public void windowOpened(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al cerrar la ventana */ public void windowClosing(WindowEvent e) { setVisible(false); } /** * Interfaz WindowListener. Acci�n al terminar de cerrar la ventana */ public void windowClosed(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al minimizar la ventana */ public void windowIconified(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al maximizar la ventana */ public void windowDeiconified(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al activar la ventana */ public void windowActivated(WindowEvent e) { } /** * Interfaz WindowListener. Acci�n al desactivar la ventana */ public void windowDeactivated(WindowEvent e) { } //----------------------------------------------------------------------------// // M�TODOS PRIVADOS // //----------------------------------------------------------------------------// /** * Creaci�n de la ventana */ private void build() { String lb[] = {"Create","Cancel"}; XCommandForm form = new XCommandForm(lb,lb,this); form.setCommandWidth(120); form.block(); String datalabel[] = { "Name","Minimum","Maximum","Cardinality","No. MFs"}; dataform = new XTextForm[5]; for(int i=0; i<dataform.length; i++) { dataform[i] = new XTextForm(datalabel[i]); dataform[i].setLabelWidth(100); dataform[i].setFieldWidth(150); dataform[i].setAlignment(JLabel.CENTER); } parentform = new XComboBox("Parent"); parentform.setWidth(100,150); parentform.setList(spec.getTypes()); Box leftbox = new Box(BoxLayout.Y_AXIS); leftbox.add(dataform[0]); leftbox.add(parentform); leftbox.add(Box.createVerticalStrut(5)); leftbox.add(new XLabel("Universe of discourse")); leftbox.add(Box.createVerticalStrut(5)); leftbox.add(dataform[1]); leftbox.add(dataform[2]); leftbox.add(dataform[3]); leftbox.add(Box.createVerticalStrut(5)); leftbox.add(new XLabel("Membership functions")); leftbox.add(Box.createVerticalStrut(5)); leftbox.add(dataform[4]); button = new JToggleButton[12]; JPanel rightbox = new JPanel(); rightbox.setLayout(new GridLayout(4,3)); ButtonGroup rbg = new ButtonGroup(); ImageIcon icon[] = { XfeditIcons.typeF1, XfeditIcons.typeF2, XfeditIcons.type1, XfeditIcons.type2, XfeditIcons.type3, XfeditIcons.type4, XfeditIcons.type5, XfeditIcons.type6, XfeditIcons.type7, XfeditIcons.type8, XfeditIcons.type9}; for(int i=0; i<button.length; i++) { if(i<button.length-1) { button[i] = new JToggleButton(icon[i]); } else { button[i] = new JToggleButton("extends"); button[i].setFont(XConstants.textfont); button[i].setForeground(Color.black); } button[i].setBorder(BorderFactory.createRaisedBevelBorder()); button[i].setFocusPainted(false); button[i].setContentAreaFilled(false); button[i].addChangeListener(this); rbg.add(button[i]); rightbox.add(button[i]); } Box hbox = new Box(BoxLayout.X_AXIS); hbox.add(Box.createHorizontalStrut(5)); hbox.add(leftbox); hbox.add(Box.createHorizontalStrut(5)); hbox.add(rightbox); hbox.add(Box.createHorizontalStrut(5)); Container content = getContentPane(); content.setLayout(new BoxLayout(content,BoxLayout.Y_AXIS)); content.add(new XLabel("Type Creation")); content.add(Box.createVerticalStrut(5)); content.add(hbox); content.add(form); setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); addWindowListener(this); setLocationRelativeTo(xfeditor); pack(); } /** * Devuelve el indice del tipo predefinido seleccionado */ private int getSelection() { for(int i=0; i<button.length; i++) if(button[i].isSelected()) return i; return -1; } /** * Activa los campos de la ventana en funci�n de la selecci�n */ private void setDataEnabled() { int sel = getSelection(); if(sel == 10) /* BLANK */ { for(int i=1; i<4; i++) dataform[i].setFieldEnabled(true); for(int i=1; i<4; i++) dataform[i].setEditable(true); parentform.setEnabled(false); parentform.setSelectedItem(null); dataform[4].setFieldEnabled(false); dataform[4].setEditable(false); dataform[4].setText(""); } else if(sel == 11) /* EXTENDS */ { for(int i=1; i<5; i++) dataform[i].setFieldEnabled(false); for(int i=1; i<5; i++) dataform[i].setEditable(false); for(int i=1; i<5; i++) dataform[i].setText(""); parentform.setEnabled(true); } else /* ANY OTHER */ { for(int i=1; i<5; i++) dataform[i].setFieldEnabled(true); for(int i=1; i<5; i++) dataform[i].setEditable(true); parentform.setEnabled(false); parentform.setSelectedItem(null); } } /** * Lee el identificador del tipo y verifica que es correcto */ private String getTypeName() { String name = dataform[0].getText(); if(!XConstants.isIdentifier(name)) { dataform[0].setText(""); XDialog.showMessage(dataform[0],"Invalid Name"); return null; } if(spec.searchType(name) != null) { dataform[0].setText(""); XDialog.showMessage(dataform[0],"Invalid Name: Type already exists"); return null; } return name; } /** * Lee los campos del universo y verifica que son correctos */ private Universe getUniverse() { Universe u = null; boolean numeric = true; double min=0, max=0; int card=256; try { min = Double.parseDouble(dataform[1].getText()); } catch(NumberFormatException ex) { dataform[1].setText(""); numeric = false; } try { max = Double.parseDouble(dataform[2].getText()); } catch(NumberFormatException ex) { dataform[2].setText(""); numeric = false; } try { String cardinality = dataform[3].getText(); if(cardinality.length() >0 ) card = Integer.parseInt(cardinality); } catch(NumberFormatException ex) { dataform[3].setText(""); numeric = false; } if(!numeric) { XDialog.showMessage(dataform[3],"Not a numeric value"); return null; } try { u = new Universe(min,max,card); } catch(XflException ex) { XDialog.showMessage(dataform[3],"Invalid universe data"); return null; } return u; } /** * Lee el n�mero de etiquetas y verifica que es correcto */ private int getNumberOfMFs() { int sel = getSelection(); int limit = 0; if(sel == 0) limit = 2; else if(sel == 1) limit = 4; else if(sel <= 7) limit = 2; else limit = 1; int mfs = -1; try { mfs = Integer.parseInt(dataform[4].getText()); } catch(NumberFormatException ex) { dataform[4].setText(""); XDialog.showMessage(dataform[3],"Not a numeric value"); return -1; } if(mfs < limit) { dataform[4].setText(""); XDialog.showMessage(dataform[3],"Not a valid value"); return -1; } return mfs; } //----------------------------------------------------------------------------// // M�todos que generan el tipo // //----------------------------------------------------------------------------// /** * Crea un nuevo tipo de la familia seleccionada */ private Type create() { String name = getTypeName(); if(name == null) return null; Type parent = (Type) parentform.getSelectedItem(); Universe u = null; int mfs = 0; if(parent == null) { u = getUniverse(); if(u == null) return null; } int sel = getSelection(); if(sel == -1) { XDialog.showMessage(dataform[3],"A predefined selection is needed"); return null; } else if(dataform[4].isEditable()) { mfs = getNumberOfMFs(); if(mfs<0) return null; } Type tp; if(parent == null) tp = new Type(name,u); else tp = new Type(name,parent); createMemFuncs(tp, sel, mfs); spec.addType(tp); spec.setModified(true); return tp; } /** * Genera un conjunto de funciones de pertenencia predefinidas */ private void createMemFuncs(Type type, int sel, int mfs) { if(sel<0 || sel>9) return; String prefix = "mf"; boolean exists = true; while(exists) { exists = false; for(int i=0;i<mfs;i++) if(type.search(prefix+i) != null) exists = true; if(exists) prefix += "_"; } switch(sel) { case 0: createTypeF1(type,mfs,prefix); break; case 1: createTypeF2(type,mfs,prefix); break; case 2: createType0(type,mfs,prefix); break; case 3: createType1(type,mfs,prefix); break; case 4: createType2(type,mfs,prefix); break; case 5: createType3(type,mfs,prefix); break; case 6: createType4(type,mfs,prefix); break; case 7: createType5(type,mfs,prefix); break; case 8: createType6(type,mfs,prefix); break; case 9: createType7(type,mfs,prefix); break; } } /** * Crea una familia de triangulos equiespaciados */ private void createTypeF1(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double r = (max-min)/(mfs-1); double param[] = new double[mfs-2]; for(int i=0; i<mfs-2; i++) param[i] = min+(i+1)*r; String famname = "fam"; int index = 0; while(type.searchFamily(famname) != null) famname = "fam"+index; Family fam = new pkg.xfl.family.triangular(); fam.set(famname,type); try { fam.set(param); type.addFamily(fam); } catch(Exception ex) {} for(int i=0; i<mfs; i++) { FamiliarMemFunc fmf = new FamiliarMemFunc(prefix+i,fam,i); try { type.add(fmf); } catch(XflException e) {} } } /** * Crea una familia de splines equiespaciados */ private void createTypeF2(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double r = (max-min)/(mfs-2); double param[] = new double[mfs-3]; for(int i=0; i<mfs-3; i++) param[i] = min+(i+1)*r; String famname = "fam"; int index = 0; while(type.searchFamily(famname) != null) famname = "fam"+index; Family fam = new pkg.xfl.family.spline(); fam.set(famname,type); try { fam.set(param); type.addFamily(fam); } catch(Exception ex) {} for(int i=0; i<mfs; i++) { FamiliarMemFunc fmf = new FamiliarMemFunc(prefix+i,fam,i); try { type.add(fmf); } catch(XflException e) {} } } /** * Crea un conjunto de triangulos equiespaciados */ private void createType0(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double r = (max-min)/(mfs-1); double param[] = new double[3]; ParamMemFunc pmf[] = new ParamMemFunc[mfs]; param[0] = min - r; param[1] = min; param[2] = min + r; pmf[0] = new pkg.xfl.mfunc.triangle(); pmf[0].set(prefix+"0",u); try { pmf[0].set(param); } catch(XflException ex) { System.out.println(""+ex); } for(int i=1; i<mfs-1; i++) { param[0] = min + (i-1)*r; param[1] = min + i*r; param[2] = min + (i+1)*r; pmf[i] = new pkg.xfl.mfunc.triangle(); pmf[i].set(prefix+i,u); try { pmf[i].set(param); } catch(XflException ex) {} } param[0] = max - r; param[1] = max; param[2] = max + r; pmf[mfs-1] = new pkg.xfl.mfunc.triangle(); pmf[mfs-1].set(prefix+(mfs-1),u); try { pmf[mfs-1].set(param); } catch(XflException ex) {} try { for(int i=0; i<mfs; i++) type.add(pmf[i]); } catch(XflException e) {} } /** * Crea un conjunto de triangulos y trapecios */ private void createType1(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double r = (max-min)/(mfs+1); double param4[] = new double[4]; double param3[] = new double[3]; ParamMemFunc pmf[] = new ParamMemFunc[mfs]; param4[0] = min-r; param4[1] = min; param4[2] = min+r; param4[3] = min+2*r; pmf[0] = new pkg.xfl.mfunc.trapezoid(); pmf[0].set(prefix+"0",u); try { pmf[0].set(param4); } catch(XflException ex) {} for(int i=1; i<mfs-1; i++) { param3[0] = min + i*r; param3[1] = min + (i+1)*r; param3[2] = min + (i+2)*r; pmf[i] = new pkg.xfl.mfunc.triangle(); pmf[i].set(prefix+i,u); try { pmf[i].set(param3); } catch(XflException ex) {} } param4[0] = max-2*r; param4[1] = max-r; param4[2] = max; param4[3] = max+r; pmf[mfs-1] = new pkg.xfl.mfunc.trapezoid(); pmf[mfs-1].set(prefix+(mfs-1), u); try { pmf[mfs-1].set(param4); } catch(XflException ex) {} try { for(int i=0; i<mfs; i++) type.add(pmf[i]); } catch(XflException e) {} } /** * Crea un conjunto de campanas equiespaciadas */ private void createType2(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double r = (max-min)/(mfs-1); double param[] = new double[2]; ParamMemFunc pmf[] = new ParamMemFunc[mfs]; param[0] = min; param[1] = 0.6*r; pmf[0] = new pkg.xfl.mfunc.bell(); pmf[0].set(prefix+"0", u); try { pmf[0].set(param); } catch(XflException ex) {} for(int i=1; i<mfs-1; i++) { param[0] = min + i*r; pmf[i] = new pkg.xfl.mfunc.bell(); pmf[i].set(prefix+i, u); try { pmf[i].set(param); } catch(XflException ex) {} } param[0] = max; pmf[mfs-1] = new pkg.xfl.mfunc.bell(); pmf[mfs-1].set(prefix+(mfs-1), u); try { pmf[mfs-1].set(param); } catch(XflException ex) {} try { for(int i=0; i<mfs; i++) type.add(pmf[i]); } catch(XflException e) {} } /** * Crea un conjunto de campanas y sigmoides */ private void createType3(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double r = (max-min)/(mfs+1); double param[] = new double[2]; ParamMemFunc pmf[] = new ParamMemFunc[mfs]; param[0] = min + 1.5*r; param[1] = -0.17*r; pmf[0] = new pkg.xfl.mfunc.sigma(); pmf[0].set(prefix+"0", u); try { pmf[0].set(param); } catch(XflException ex) {} for(int i=1; i<mfs-1; i++) { param[0] = min + (i+1)*r; param[1] = 0.6*r; pmf[i] = new pkg.xfl.mfunc.bell(); pmf[i].set(prefix+i, u); try { pmf[i].set(param); } catch(XflException ex) {} } param[0] = max - 1.5*r; param[1] = 0.17*r; pmf[mfs-1] = new pkg.xfl.mfunc.sigma(); pmf[mfs-1].set(prefix+(mfs-1), u); try { pmf[mfs-1].set(param); } catch(XflException ex) {} try { for(int i=0; i<mfs; i++) type.add(pmf[i]); } catch(XflException e) {} } /** * Crea un conjunto de trapecios equiespaciados */ private void createType4(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double r = (max-min)/(3*mfs-1); double param[] = new double[4]; ParamMemFunc pmf[] = new ParamMemFunc[mfs]; param[0] = min - r; param[1] = min; param[2] = min + 2*r; param[3] = min + 3*r; pmf[0] = new pkg.xfl.mfunc.trapezoid(); pmf[0].set(prefix+"0", u); try { pmf[0].set(param); } catch(XflException ex) {} for(int i=1; i<mfs-1; i++) { param[0] = min + (3*i-1)*r; param[1] = min + 3*i*r; param[2] = min + (3*i+2)*r; param[3] = min + (3*i+3)*r; pmf[i] = new pkg.xfl.mfunc.trapezoid(); pmf[i].set(prefix+i, u); try { pmf[i].set(param); } catch(XflException ex) {} } param[0] = max - 3*r; param[1] = max - 2*r; param[2] = max; param[3] = max + r; pmf[mfs-1] = new pkg.xfl.mfunc.trapezoid(); pmf[mfs-1].set(prefix+(mfs-1), u); try { pmf[mfs-1].set(param); } catch(XflException ex) {} try { for(int i=0; i<mfs; i++) type.add(pmf[i]); } catch(XflException e) {} } /** * Crea un conjunto de singularidades equiespaciadas */ private void createType5(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double r = (max-min)/(mfs-1); double param; ParamMemFunc pmf[] = new ParamMemFunc[mfs]; param = min; pmf[0] = new pkg.xfl.mfunc.singleton(); pmf[0].set(prefix+"0", u); pmf[0].set(param); for(int i=1; i<mfs-1; i++) { param = min + i*r; pmf[i] = new pkg.xfl.mfunc.singleton(); pmf[i].set(prefix+i, u); pmf[i].set(param); } param = max; pmf[mfs-1] = new pkg.xfl.mfunc.singleton(); pmf[mfs-1].set(prefix+(mfs-1), u); pmf[mfs-1].set(param); try { for(int i=0; i<mfs; i++) type.add(pmf[i]); } catch(XflException e) {} } /** * Crea un conjunto de campanas centradas */ private void createType6(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double param[] = new double[2]; param[0] = (min + max)/2; param[1] = (max - min)/8; ParamMemFunc pmf[] = new ParamMemFunc[mfs]; for(int i=0; i<mfs; i++) { pmf[i] = new pkg.xfl.mfunc.bell(); pmf[i].set(prefix+i, u); try { pmf[i].set(param); } catch(XflException ex) {} } try { for(int i=0; i<mfs; i++) type.add(pmf[i]); } catch(XflException e) {} } /** * Crea un conjunto de singularidades centradas */ private void createType7(Type type, int mfs, String prefix) { Universe u = type.getUniverse(); double min = u.min(); double max = u.max(); double middle = (min + max)/2 ; ParamMemFunc pmf[] = new ParamMemFunc[mfs]; for(int i=0; i<mfs; i++) { pmf[i] = new pkg.xfl.mfunc.singleton(); pmf[i].set(prefix+i, u); pmf[i].set(middle); } try { for(int i=0; i<mfs; i++) type.add(pmf[i]); } catch(XflException e) {} } }