HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Components, and Creating a Custom Property Editor"
Volume: 4 Issue: 11, p. 32

	

Listing 1: 

package CodeEditor; 

import com.sun.java.swing.*; 
import com.sun.java.swing.text.*; 
import java.util.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.io.*; 

public class CodeTextPane extends JTextPane implements Serializable{ 
  public CodeTextPane() { 

  } 

  void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { 
    ois.defaultReadObject(); 
  } 

  void writeObject(ObjectOutputStream oos) throws IOException { 
    oos.defaultWriteObject(); 
  } 

  public void setKeywords(Vector aNewSetOfKeywords) { 
    Document doc = getDocument(); 
    if (doc instanceof CodeDocument) { 
      CodeDocument codeDoc = (CodeDocument) doc; 
      codeDoc.setKeywords(aNewSetOfKeywords); 
    } 
  } 

  public void setKeywords(String aNewSetOfKeywords[]){ 
    Vector v = new Vector(); 
    for (int i=0;i< aNewSetOfKeywords.length;i++){ 
      v.addElement(aNewSetOfKeywords[i]); 
    } 
    setKeywords(v); 
  } 
  

  public Vector getKeywords() { 
    Vector keywords = null; 

    Document doc = getDocument(); 
    if (doc instanceof CodeDocument) { 
      CodeDocument codeDoc = (CodeDocument) doc; 
      keywords = codeDoc.getKeywords(); 
    } 

    return keywords; 
  } 

} 
  

Listing 2: 

//Title:        Your Product Name 
//Version: 
//Copyright:    Copyright (c) 1998 
//Author:       Your Name 
//Company:      Your Company 
//Description:  Your description 

package CodeEditor; 

import java.beans.*; 

public class CodeTextPaneBeanInfo extends SimpleBeanInfo { 
  Class beanClass = CodeTextPane.class; 
  String iconColor16x16Filename; 
  String iconColor32x32Filename; 
  String iconMono16x16Filename; 
  String iconMono32x32Filename; 
  

  public CodeTextPaneBeanInfo() { 
  } 

  public PropertyDescriptor[] getPropertyDescriptors() { 
    try  { 
      PropertyDescriptor _keywords = new PropertyDescriptor("keywords", beanClass,
	   "getKeywords", "setKeywords"); 
      _keywords.setDisplayName("keywords"); 
      _keywords.setShortDescription("keywords"); 
      _keywords.setPropertyEditorClass(CodeEditor.KeywordsEditor.class); 

      PropertyDescriptor[] pds = new PropertyDescriptor[] { 
        _keywords, 
      }; 
      return pds; 
    } 
    catch (IntrospectionException ex) { 
      ex.printStackTrace(); 
      return null; 
    } 
  } 

  public java.awt.Image getIcon(int iconKind) { 
    switch (iconKind) { 
    case BeanInfo.ICON_COLOR_16x16: 
      return iconColor16x16Filename != null ? loadImage(iconColor16x16Filename) : null; 
    case BeanInfo.ICON_COLOR_32x32: 
      return iconColor32x32Filename != null ? loadImage(iconColor32x32Filename) : null; 
    case BeanInfo.ICON_MONO_16x16: 
      return iconMono16x16Filename != null ? loadImage(iconMono16x16Filename) : null; 
    case BeanInfo.ICON_MONO_32x32: 
      return iconMono32x32Filename != null ? loadImage(iconMono32x32Filename) : null; 
    } 
    return null; 
  } 

  public BeanInfo[] getAdditionalBeanInfo() { 
    Class superclass = beanClass.getSuperclass(); 
    try  { 
      BeanInfo superBeanInfo = Introspector.getBeanInfo(superclass); 
      return new BeanInfo[] { superBeanInfo }; 
    } 
    catch (IntrospectionException ex) { 
      ex.printStackTrace(); 
      return null; 
    } 
  } 
} 

Listing 3: 

//Title:        Your Product Name 
//Version: 
//Copyright:    Copyright (c) 1998 
//Author:       Your Name 
//Company:      Your Company 
//Description:  Your description 

package CodeEditor; 

import java.awt.*; 
import java.beans.*; 
import java.util.*; 

public class KeywordsEditor extends PropertyEditorSupport { 
  private KeywordsEditorComponent editor; 
  

  public KeywordsEditor() { 
  } 

  public boolean supportsCustomEditor() { 
    return true; 
  } 

  public Component getCustomEditor() { 
    if (editor == null) { 
      editor = new KeywordsEditorComponent(this); 
    } 
    return editor; 
  } 

  public String getJavaInitializationString() { 
    //TODO: Implement this for your property type 
    Vector v = (Vector)getValue(); 
    String s = "new String[] {"; 
    Enumeration enum = v.elements(); 
    while (enum.hasMoreElements()){ 
      String keyword = (String)enum.nextElement(); 
      if ( enum.hasMoreElements() ){ 
        s += "\"" + keyword + "\","; 
      } 
      else{ 
        s += "\"" + keyword + "\"}"; 
      } 
    } 
    return s; 
  } 
} 

Listing 4:
 
//Title:        Your Product Name 
//Version: 
//Copyright:    Copyright (c) 1998 
//Author:       Your Name 
//Company:      Your Company 
//Description:  Your description 

package CodeEditor; 

import java.awt.*; 
import java.awt.event.*; 
import java.beans.*; 
import com.sun.java.swing.*; 
import com.sun.java.swing.event.*; 
import java.util.*; 

public class KeywordsEditorComponent extends Panel{ 
  private PropertyEditor editor; 
  JLabel label1 = new JLabel(); 
  JLabel label2 = new JLabel(); 
  DefaultListModel keywords = new DefaultListModel(); 
  JList keywordList = new JList(keywords); 
  JTextField keywordEdit = new JTextField(); 
  JButton addBtn = new JButton(); 
  JButton deleteBtn = new JButton(); 
  JScrollPane listScroller = new JScrollPane(keywordList); 

  private void initEditor(){ 
    addBtn.setText("Add to keywords list"); 
    addBtn.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        addBtn_actionPerformed(e); 
      } 
    }); 

    deleteBtn.setText("Delete item from list"); 
    deleteBtn.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        deleteBtn_actionPerformed(e); 
      } 
    }); 

    label1.setText("Keywords List"); 
    label2.setText("Keyword: "); 

    keywordEdit.setText(""); 
    keywordEdit.setPreferredSize(new Dimension(80, 25)); 

    listScroller.setPreferredSize(new Dimension(150, 200)); 

    if (editor != null){ 
      keywords.removeAllElements(); 
      Vector v = (Vector)editor.getValue(); 
      Enumeration enum = v.elements(); 
      while (enum.hasMoreElements()){ 
        keywords.addElement(enum.nextElement()); 
      } 
    } 
    keywords.addListDataListener(new ListDataListener(){ 
      public void contentsChanged(ListDataEvent e){ 
        keywords_changed(e); 
      } 
      public void intervalAdded(ListDataEvent e){ 
        keywords_changed(e); 
      } 

      public void intervalRemoved(ListDataEvent e){ 
        keywords_changed(e); 
      } 
    }); 

    //set the layout manager 
    GridBagLayout gb = new GridBagLayout(); 
    this.setLayout(gb); 
    GridBagConstraints gridConst = new GridBagConstraints(); 
    gridConst.gridx = 0; 
    gridConst.gridy = 0; 
    gridConst.gridheight = 1; 
    gridConst.gridwidth = 1; 
    gridConst.anchor = GridBagConstraints.NORTHWEST; 
    gb.setConstraints(label1,gridConst); 
    this.add(label1); 

    gridConst = new GridBagConstraints(); 
    gridConst.gridx = 0; 
    gridConst.gridy = 1; 
    gridConst.gridheight = 3; 
    gridConst.gridwidth = 2; 
    gridConst.anchor = GridBagConstraints.NORTHWEST; 
    gb.setConstraints(listScroller,gridConst); 
    this.add(listScroller); 

    gridConst = new GridBagConstraints(); 
    gridConst.gridx = 2; 
    gridConst.gridy = 0; 
    gridConst.gridheight = 1; 
    gridConst.gridwidth = 1; 
    gridConst.anchor = GridBagConstraints.NORTHEAST; 
    gb.setConstraints(label2,gridConst); 
    this.add(label2); 

    gridConst = new GridBagConstraints(); 
    gridConst.gridx = 1; 
    gridConst.gridy = 1; 
    gridConst.gridheight = 1; 
    gridConst.gridwidth = 2; 
    gridConst.anchor = GridBagConstraints.NORTHEAST; 
    gb.setConstraints(keywordEdit,gridConst); 
    this.add(keywordEdit); 

    gridConst = new GridBagConstraints(); 
    gridConst.gridx = 2; 
    gridConst.gridy = 3; 
    gridConst.gridheight = 1; 
    gridConst.gridwidth = 1; 
    gridConst.anchor = GridBagConstraints.SOUTHEAST; 
    gb.setConstraints(addBtn,gridConst); 
    this.add(addBtn); 

    gridConst = new GridBagConstraints(); 
    gridConst.gridx = 2; 
    gridConst.gridy = 4; 
    gridConst.gridheight = 1; 
    gridConst.gridwidth = 1; 
    gridConst.anchor = GridBagConstraints.SOUTHEAST; 
    gb.setConstraints(deleteBtn,gridConst); 
    this.add(deleteBtn); 
  } 

  public KeywordsEditorComponent(PropertyEditor editor) { 
    this.editor = editor; 
    initEditor(); 
  } 

  private void addBtn_actionPerformed(ActionEvent e) { 
    keywords.addElement(keywordEdit.getText()); 
  } 

  private void deleteBtn_actionPerformed(ActionEvent e) { 
    Object selectedObj = this.keywordList.getSelectedValue(); 
    if (selectedObj != null){ 
      keywords.remove(keywordList.getSelectedIndex()); 
    } 
  } 

  private void keywords_changed(ListDataEvent e){ 
    if (editor != null){ 
      Vector v = new Vector(); 
      Enumeration enum = keywords.elements(); 
      while (enum.hasMoreElements()){ 
        v.addElement(enum.nextElement()); 
      } 
      editor.setValue(v); 
    } 
  } 

} 

Listing 5:
 
package CodeEditor; 

public class ClassElement { 
  private String displayValue = ""; 
  private String elementValue = ""; 
  public ClassElement() { 
  } 

  public ClassElement(String displayText, String elementText) { 
    elementValue = elementText; 
    displayValue = displayText; 
  } 

  public String getDisplayValue(){ 
    return displayValue; 
  } 

  public String getElementValue(){ 
    return elementValue; 
  } 

  public void setElementValue(String aValue){ 
    this.elementValue = aValue; 
  } 

  public void setDisplayValue(String aValue){ 
    this.displayValue = aValue; 
  } 

  public String toString(){ 
    return displayValue; 
  } 
} 

Listing 6
 
package CodeEditor; 
import java.util.*; 
import java.lang.reflect.*; 

public class ClassLister { 
  private String currentClassName = ""; 
  private Class currentClass = null; 
  private Vector knownPackages = null; 

  public ClassLister(){ 
    currentClassName = ""; 
    knownPackages = new Vector(); 
    knownPackages.addElement("java.lang."); 
  } 

  public ClassLister(String aClassName) { 
    currentClassName = aClassName; 
    knownPackages = new Vector(); 
    knownPackages.addElement("java.lang."); 
  } 

  public ClassLister(String aClassName, Vector aPackageList) { 
    currentClassName = aClassName; 
    if (knownPackages == null){ 
    knownPackages = aPackageList; 
    } 
    else{ 
      Enumeration enum = aPackageList.elements(); 
      while (enum.hasMoreElements()){ 
        String aPackage = (String)enum.nextElement(); 
        knownPackages.addElement(aPackage); 
      } 
    } 
  } 

  public void setClassName(String aClassName){ 
    this.currentClassName = aClassName; 
  } 

  public String getClassName(){ 
    return this.currentClassName; 
  } 

  public boolean isNameAClass(String aClassName){ 
    Enumeration packages = knownPackages.elements(); 
    Class aClass = null; 
    String fullClassName = ""; 
    boolean result = false; 
    while (packages.hasMoreElements()){ 
      try{ 
        fullClassName = (String)packages.nextElement() + aClassName; 
        aClass = Class.forName(fullClassName); 
        result = true;//if we get here then the class was successfully found - find first matching class name 
        break; 
      } 
      catch (Exception ex){ 
          //ex.printStackTrace(); 
        System.out.println("no class"); 
        result = false; 
      } 
    } 
    return result; 
  } 

  public void addPackage(String aPackage){ 
    String s = aPackage.trim(); 
    if (s.charAt(s.length() - 1) == '*'){ 
      aPackage = s.substring(0, s.length() - 1); 
      s = aPackage; 
      System.out.println(s); 
    } 
    if (this.knownPackages.contains(s)){return;} 
    this.knownPackages.addElement(s); 
  } 

  public String listMethodArgs(String aMethod) throws ClassNotFoundException{ 
    String result = ""; 
    currentClass = null; 
    try{ 
      currentClass = Class.forName(currentClassName); 

    } 
    catch (ClassNotFoundException noClassEx){ 
      boolean notFound = true; 
      if (knownPackages == null){ 
        throw noClassEx; 
      } 
      Enumeration packages = knownPackages.elements(); 

      String fullClassName = ""; 
      while (packages.hasMoreElements()){ 
        try{ 
          fullClassName = (String)packages.nextElement() + currentClassName; 
          currentClass = Class.forName(fullClassName); 
          break;//if we get here then the class was successfully found - find first matching class name 
        } 
        catch (ClassNotFoundException ex){ 
          //ex.printStackTrace(); 
          System.out.println("no class"); 
        } 
      } 
      //noClassEx.printStackTrace(); 
    } 
    catch (Exception ex){ 
      //ex.printStackTrace(); 
      System.out.println("Whoops"); 
    } 

    if (currentClass == null) { 
      throw new ClassNotFoundException(); 
    } 
    Method foundMethod = null; 
    Method[] methods = currentClass.getDeclaredMethods(); 
    for (int i=0;i<methods.length;i++){ 
      Method m = methods[i]; 
      if (m.getName().equalsIgnoreCase(aMethod)){ 
        foundMethod = m; 
        break; 
      } 
    } 
    if (foundMethod != null){ 
      Class[] args = foundMethod.getParameterTypes(); 
      for (int i=0;i<args.length;i++){ 
        Class arg = args[i]; 
        result += arg.getName() + " argument" + String.valueOf(i)+ " "; 
        /*e = new ClassElement("Method    " + aMethod.getName() + " : " + 
                         aMethod.getReturnType().getName(), 
                           aMethod.getName()); 
        results.addElement(e);*/ 
      } 
    } 
    return result; 
  } 
  public Vector listMethods() throws ClassNotFoundException{ 
    Vector results = new Vector(); 
    currentClass = null; 
    try{ 
      currentClass = Class.forName(currentClassName); 

    } 
    catch (ClassNotFoundException noClassEx){ 
      boolean notFound = true; 
      if (knownPackages == null){ 
        throw noClassEx; 
      } 
      Enumeration packages = knownPackages.elements(); 

      String fullClassName = ""; 
      while (packages.hasMoreElements()){ 
        try{ 
          fullClassName = (String)packages.nextElement() + currentClassName; 
          currentClass = Class.forName(fullClassName); 
          break;//if we get here then the class was successfully found - find first matching class name 
        } 
        catch (ClassNotFoundException ex){ 
          //ex.printStackTrace(); 
          System.out.println("no class"); 
        } 
      } 
      //noClassEx.printStackTrace(); 
    } 
    catch (Exception ex){ 
      //ex.printStackTrace(); 
      System.out.println("Whoops"); 
    } 

    if (currentClass == null) { 
      throw new ClassNotFoundException(); 
    } 

    Method[] methodList = currentClass.getDeclaredMethods(); 
    ClassElement e = null; 
    for (int i =0; i < methodList.length; i++){ 
      Method aMethod = methodList[i]; 
      e = new ClassElement("Method    " + aMethod.getName() + " : " + 
                         aMethod.getReturnType().getName(), 
                           aMethod.getName()); 
      results.addElement(e); 
    } 

    return results; 
  } 

  public Vector listAll() throws ClassNotFoundException{ 
    Vector results = new Vector(); 
    currentClass = null; 
    try{ 
      currentClass = Class.forName(currentClassName); 

    } 
    catch (ClassNotFoundException noClassEx){ 
      boolean notFound = true; 
      if (knownPackages == null){ 
        throw noClassEx; 
      } 
      Enumeration packages = knownPackages.elements(); 

      String fullClassName = ""; 
      while (packages.hasMoreElements()){ 
        try{ 
          fullClassName = (String)packages.nextElement() + currentClassName; 
          currentClass = Class.forName(fullClassName); 
          break;//if we get here then the class was successfully found - find first matching class name 
        } 
        catch (ClassNotFoundException ex){ 
          //ex.printStackTrace(); 
          System.out.println("no class"); 
        } 
      } 
      //noClassEx.printStackTrace(); 
    } 
    catch (Exception ex){ 
      //ex.printStackTrace(); 
      System.out.println("Whoops"); 
    } 

    if (currentClass == null) { 
      throw new ClassNotFoundException(); 
    } 

    Method[] methodList = currentClass.getDeclaredMethods(); 
    ClassElement e = null; 
    for (int i =0; i < methodList.length; i++){ 
      Method aMethod = methodList[i]; 
      e = new ClassElement("Method    " + aMethod.getName() + " : " + 
                         aMethod.getReturnType().getName(), 
                           aMethod.getName()); 
      results.addElement(e); 
    } 

    Field[] fieldList = currentClass.getDeclaredFields(); 
    for (int i =0; i < fieldList.length; i++){ 
      Field aField = fieldList[i]; 
      e = new ClassElement("Member    " + aField.getName() + " : " + 
                         aField.getClass().getName(), 
                           aField.getName()); 
      results.addElement(e); 
    } 

    return results; 
  } 
} 

Listing 7 

package CodeEditor; 
import java.util.*; 

public class CodeClass { 
  public Vector attributes = new Vector(); //list of CodeAttribute 
  public Vector methods = new Vector();    //list of CodeMethod 
  public Vector constructors = new Vector(); //list of CodeConstructor 
  public String className = ""; 
  public String superClass = ""; 
  public Vector interfaces = new Vector();  //list of strings 
  public String scope = "public"; 

  public CodeClass() { 

  } 

} 

Listing 8:
 
package CodeEditor; 

import com.sun.java.swing.*; 
import com.sun.java.swing.text.*; 
import java.util.*; 
import java.awt.*; 
import java.awt.event.*; 

public class CodeDocument extends DefaultStyledDocument implements ActionListener{ 
  ////////////////////////////////////// 
  //these are for the States 
  /////////////////////////////////////// 
  private static final int STATE_TEXT_INPUT = 10; 
  private static final int STATE_CLASS_INPUT = 11; 
  private static final int STATE_VARIABLE_INPUT = 12; 
  private static final int STATE_PACKAGE_INPUT = 13; 
  private static final int STATE_IMPORT_INPUT = 14; 
  private static final int STATE_VARIABLE_TYPE_INPUT = 15; 

  private static final boolean DEBUG = true; //turns off the diagnostic System.out statements 

  //class reflection stuff 
  private ClassLister classLister = new ClassLister(); 
  private Hashtable codeElements = new Hashtable(); 
  private String currentClassName = ""; 
  private String currentTypeName = ""; 
  private Class currentClass = null; 
  private int currentState = STATE_TEXT_INPUT; 
  private CodePackage thePackage = new CodePackage(); 
  private Vector methodListeners = new Vector(); 
  private String currentMethod = ""; 
  private String currentKeyWord = ""; 
  private String oldKeyWord = ""; 
  private int listOffs = 0; 
  private boolean codeReflectionOn = true; 
  //syntax stuff here 
  private String word = ""; 
  private SimpleAttributeSet bold = new SimpleAttributeSet(); 
  private SimpleAttributeSet string = new SimpleAttributeSet(); 
  private SimpleAttributeSet normal = new SimpleAttributeSet(); 
  private SimpleAttributeSet number = new SimpleAttributeSet(); 
  private SimpleAttributeSet comments = new SimpleAttributeSet(); 

  private int currentPos = 0; 
  private Vector keywords = new Vector(); 
  public static int STRING_MODE = 10; 
  public static int TEXT_MODE = 11; 
  public static int NUMBER_MODE = 12; 
  public static int COMMENT_MODE = 13; 
  private int mode = TEXT_MODE; 

  public CodeDocument() { 
   //set the bold attribute 
   StyleConstants.setBold(bold, true); 
   StyleConstants.setForeground(string, Color.red); 
   StyleConstants.setForeground(number, Color.magenta); 
   StyleConstants.setForeground(comments, Color.blue); 
   StyleConstants.setItalic(comments, true); 
  } 

  //reflection methods 
  /** 
  */ 
  private void checkState(){ 
    switch (this.currentState){ 
      case (this.STATE_CLASS_INPUT):{ 
        this.thePackage.outerClass.className = word; 
        if (DEBUG) { 
          System.out.println("Class is " + thePackage.outerClass.className); 
        } 
      } 
      break; 
      case (this.STATE_IMPORT_INPUT):{ 
        if (DEBUG) { 
          System.out.println(word); 
        } 
        this.thePackage.imports.addElement(word); 
        classLister.addPackage(word); 
      } 
      break; 
      case (this.STATE_PACKAGE_INPUT):{ 
        if (DEBUG) { 
          System.out.println(word); 
        } 
        this.thePackage.packageName = word; 
      } 
      break; 
      case (this.STATE_TEXT_INPUT):{ 
        if (DEBUG) { 
          System.out.println(word); 
        } 
      } 
      break; 
      case (this.STATE_VARIABLE_INPUT):{ 
        if (DEBUG) { 
          System.out.println("Variable: " + word); 
          System.out.println("Variable Type: " + currentTypeName); 
        } 
      } 
      break; 
      case (this.STATE_VARIABLE_TYPE_INPUT):{ 
        if (DEBUG) { 
          System.out.println("Current variable type: " + word); 
        } 
        currentTypeName = word; 
      } 
      break; 
    }//end of switch 
  } 

  /** 
  This method checks for a possible state change 
  */ 
  private void changeState(){ 
    String s = word.trim(); 
    if (s.equalsIgnoreCase("package")){ 
    //package state 
      this.currentState = this.STATE_PACKAGE_INPUT; 
    } 
    else if (s.equalsIgnoreCase("import")){ 
      this.currentState = this.STATE_IMPORT_INPUT; 
    } 
    else if (s.equalsIgnoreCase("class")){ 
      this.currentState = this.STATE_CLASS_INPUT; 
      this.thePackage.outerClass.scope = this.oldKeyWord; 
    } 
    else if (this.currentState != this.STATE_VARIABLE_TYPE_INPUT){ 
      String tmp = word.trim(); 
      if (tmp == ""){ 
        return; 
      } 
      if (classLister.isNameAClass(word)){ 
        this.currentState = this.STATE_VARIABLE_INPUT; 
        this.currentTypeName = word; 
      } 
      else{ 
        this.currentTypeName = ""; 
      } 
      if (DEBUG) { 
        System.out.println("Current variable type: " + currentTypeName); 
      } 
    } 
    else if ((this.currentState == this.STATE_VARIABLE_TYPE_INPUT) && 
             (this.currentTypeName != "")){ 
      this.currentState = this.STATE_VARIABLE_INPUT; 
    } 

    if (this.DEBUG){ 
      stateOut(); 
    } 
  } 

  /** 
  */ 
  private void handleDot(){ 
    SimpleAttributeSet inputAttributes = new SimpleAttributeSet(); 
    classLister.setClassName(this.currentTypeName); 
    try{ 
      Vector listing = classLister.listAll(); 
      JComboBox c = new JComboBox(listing); 
      c.addActionListener(this); 

      StyleConstants.setComponent(inputAttributes, c); 

      super.insertString(currentPos + 1, " ", inputAttributes); 
    } 
    catch (Exception ex){ 
      ex.printStackTrace(); 
    } 
  } 

  /** 
  */ 
  public void handleOpenParen(){ 
    classLister.setClassName(this.currentTypeName); 
    try{ 
      String args = classLister.listMethodArgs(currentMethod); 
      ActionEvent ev = new ActionEvent(this, 0, args); 
      this.fireMethodEvent(ev); 
    } 
    catch (Exception ex){ 
      ex.printStackTrace(); 
    } 
  } 

  /** 
  */ 
  private void checkForStateChange(char chr){ 
    switch (chr){ 
      case ' ': case '\n':{ 
         checkState(); 
         changeState(); 
      } 
      break; 
      case ('.'):{ 
        int oldOffs = currentPos; 
        if ((this.currentState == this.STATE_VARIABLE_INPUT) | 
            (this.currentState == this.STATE_VARIABLE_TYPE_INPUT)){ 
          checkState(); 
          handleDot(); 
        } 
        listOffs = oldOffs + 1; 
        if (this.DEBUG){ 
          stateOut(); 
        } 
      } 
      break; 
      case ('('):{ 
        int oldOffs = currentPos; 
        if ((this.currentState == this.STATE_VARIABLE_INPUT) | 
            (this.currentState == this.STATE_VARIABLE_TYPE_INPUT)){ 
          checkState(); 
          handleOpenParen(); 
        } 
        listOffs = oldOffs + 1; 
        if (this.DEBUG){ 
          stateOut(); 
        } 
      } 
      case (';'):case ('{'):{ 
        oldKeyWord = currentKeyWord; 
        checkState(); 
        this.currentState = this.STATE_TEXT_INPUT; 
        if (this.DEBUG){ 
          stateOut(); 
        } 
      } 
    }// end switch 
  } 

  /** 
  */ 
  private void stateOut(){ 
    String s = ""; 
     switch (this.currentState){ 
       case (this.STATE_CLASS_INPUT):{ 
         s = "STATE_CLASS_INPUT"; 
       } 
       break; 
       case (this.STATE_IMPORT_INPUT):{ 
         s = "STATE_IMPORT_INPUT"; 
       } 
       break; 
       case (this.STATE_PACKAGE_INPUT):{ 
         s = "STATE_PACKAGE_INPUT"; 
       } 
       break; 
       case (this.STATE_TEXT_INPUT):{ 
         s = "STATE_TEXT_INPUT"; 
       } 
       break; 
       case (this.STATE_VARIABLE_INPUT):{ 
         s = "STATE_VARIABLE_INPUT"; 
       } 
       break; 
       case (this.STATE_VARIABLE_TYPE_INPUT):{ 
         s = "STATE_VARIABLE_TYPE_INPUT"; 
       } 
       break; 
     } 
    System.out.println(s); 
  } 

  ////////////////////////////////////////////////////////////////////////////// 
  //events 
  ////////////////////////////////////////////////////////////////////////////// 
  /** 
  */ 
  public void actionPerformed(ActionEvent e) { 
    //TODO: implement this java.awt.event.ActionListener method; 

    try{ 
      JComboBox comp = (JComboBox)e.getSource(); 
      ClassElement elem = (ClassElement) comp.getSelectedItem(); 
      String item = elem.getElementValue(); 
      this.remove(listOffs, 1); 
      super.insertString(listOffs, item, null); 
      currentMethod = item; 
    } 
    catch (Exception ex){ 
      ex.printStackTrace(); 
    } 
  } 

  ////////////////////////////////////////////////////////////////////////////// 
  //Event notification 
  ////////////////////////////////////////////////////////////////////////////// 
  /** 
  */ 
  public void fireMethodEvent(ActionEvent ev){ 
    Enumeration e = methodListeners.elements(); 
    while(e.hasMoreElements()){ 
      MethodListener listener = (MethodListener)e.nextElement(); 
      listener.methodAction(ev); 
    } 
  } 

  ////////////////////////////////////////////////////////////////////////////// 
  //Event registration 
  ////////////////////////////////////////////////////////////////////////////// 
  /** 
  */ 
  public void addMethodListener(MethodListener listener){ 
    methodListeners.addElement(listener); 
  } 

  //////////////////////////////////////////////////////////////////////////// 
  //syntax methods 
  //////////////////////////////////////////////////////////////////////////// 
  private void insertKeyword(String str, int pos){ 
    try{ 
      //remove the old word and formatting 
      this.remove(pos - str.length(), str.length()); 
      /*replace it with the same word, but new formatting 
      *we MUST call the super class insertString method here, otherwise we 
      *would end up in an infinite loop !!!!!*/ 
      super.insertString(pos - str.length(), str, bold); 
    } 
    catch (Exception ex){ 
      ex.printStackTrace(); 
    } 
  } 

  private void insertTextString(String str, int pos){ 
    try{ 
      //remove the old word and formatting 
      this.remove(pos,str.length()); 
      super.insertString(pos, str, string); 
    } 
    catch (Exception ex){ 
      ex.printStackTrace(); 
    } 
  } 

  private void insertNumberString(String str, int pos){ 
    try{ 
      //remove the old word and formatting 
      this.remove(pos,str.length()); 
      super.insertString(pos, str, number); 
    } 
    catch (Exception ex){ 
      ex.printStackTrace(); 
    } 
  } 

  private void insertCommentString(String str, int pos){ 
    try{ 
      //remove the old word and formatting 
      this.remove(pos,str.length()); 
      super.insertString(pos, str, comments); 
    } 
    catch (Exception ex){ 
      ex.printStackTrace(); 
    } 
  } 

  private void checkForString(){ 
    int offs = this.currentPos; 
    Element element = this.getParagraphElement(offs); 
    String elementText = ""; 
    try{ 
      //this gets our chuck of current text for the element we're on 
      elementText = this.getText(element.getStartOffset(), 
                                 element.getEndOffset() - element.getStartOffset()); 
    } 
    catch(Exception ex){ 
      //whoops! 
      System.out.println("no text"); 
    } 
    int strLen = elementText.length(); 
    if (strLen == 0) {return;} 
    int i = 0; 

    if (element.getStartOffset() > 0){ 
      //translates backward if neccessary 
      offs = offs - element.getStartOffset(); 
    } 
    int quoteCount = 0; 
    if ((offs >= 0) && (offs <= strLen-1)){ 
      i = offs; 
      while (i >0){ 
      //the while loop walks back until we hit a delimiter 

        char charAt = elementText.charAt(i); 
        if ((charAt == '"')){ 
         quoteCount ++; 
        } 
        i--; 
      } 
      int rem = quoteCount % 2; 
      //System.out.println(rem); 
      mode = (rem == 0) ? TEXT_MODE: STRING_MODE; 
    } 
  } 

  private void checkForKeyword(){ 
    if (mode != TEXT_MODE) { 
      return; 
    } 
    int offs = this.currentPos; 
    Element element = this.getParagraphElement(offs); 
    String elementText = ""; 
    try{ 
      //this gets our chuck of current text for the element we're on 
      elementText = this.getText(element.getStartOffset(),
	  element.getEndOffset() - element.getStartOffset()); 
    } 
    catch(Exception ex){ 
      //whoops! 
      System.out.println("no text"); 
    } 
    int strLen = elementText.length(); 
    if (strLen == 0) {return;} 
    int i = 0; 

    if (element.getStartOffset() > 0){ 
      //translates backward if neccessary 
      offs = offs - element.getStartOffset(); 
    } 
    if ((offs >= 0) && (offs <= strLen-1)){ 
      i = offs; 
      while (i >0){ 
      //the while loop walks back until we hit a delimiter 
        i--; 
        char charAt = elementText.charAt(i); 
        if ((charAt == ' ') | (i == 0) | (charAt =='(') | (charAt ==')') | 
            (charAt == '{') | (charAt == '}')){ //if i == 0 then we're at the begininng 
          if(i != 0){ 
            i++; 
          } 
          word = elementText.substring(i, offs);//skip the period 

          String s = word.trim().toLowerCase(); 
          //this is what actually checks for a matching keyword 
		            if (keywords.contains(s)){ 
            insertKeyword(word, currentPos); 
          } 
          break; 
        } 
      } 
    } 
  } 

  private void checkForNumber(){ 
    int offs = this.currentPos; 
    Element element = this.getParagraphElement(offs); 
    String elementText = ""; 
    try{ 
      //this gets our chuck of current text for the element we're on 
      elementText = this.getText(element.getStartOffset(), 
                                 element.getEndOffset() - element.getStartOffset()); 
    } 
    catch(Exception ex){ 
      //whoops! 
      System.out.println("no text"); 
    } 
    int strLen = elementText.length(); 
    if (strLen == 0) {return;} 
    int i = 0; 

    if (element.getStartOffset() > 0){ 
      //translates backward if neccessary 
      offs = offs - element.getStartOffset(); 
    } 
    mode = TEXT_MODE; 
    if ((offs >= 0) && (offs <= strLen-1)){ 
      i = offs; 
      while (i >0){ 
      //the while loop walks back until we hit a delimiter 
        char charAt = elementText.charAt(i); 
        if ((charAt == ' ') | (i == 0) | (charAt =='(') | (charAt ==')') | 
            (charAt == '{') | (charAt == '}')){ //if i == 0 then we're at the begininng 
          if(i != 0){ 
            i++; 
          } 
          mode = NUMBER_MODE; 
          break; 
        } 
        else if (!(charAt >= '0' & charAt <= '9' | charAt=='.' 
                  | charAt=='+' | charAt=='-' 
                  | charAt=='/' | charAt=='*'| charAt=='%' | charAt=='=')){ 
          mode = TEXT_MODE; 
          break; 
        } 
        i--; 
      } 
    } 
  } 

  private void checkForComment(){ 
    int offs = this.currentPos; 
    Element element = this.getParagraphElement(offs); 
    String elementText = ""; 
    try{ 
      //this gets our chuck of current text for the element we're on 
      elementText = this.getText(element.getStartOffset(),                   element.getEndOffset() - element.getStartOffset()); 
    } 
    catch(Exception ex){ 
      //whoops! 
      System.out.println("no text"); 
    } 
    int strLen = elementText.length(); 
    if (strLen == 0) {return;} 
    int i = 0; 

    if (element.getStartOffset() > 0){ 
      //translates backward if neccessary 
      offs = offs - element.getStartOffset(); 
    } 
    if ((offs >= 1) && (offs <= strLen-1)){ 
      i = offs; 
      char commentStartChar1 = elementText.charAt(i-1); 
      char commentStartChar2 = elementText.charAt(i); 
      if (commentStartChar1 == '/' && commentStartChar2 == '*'){ 
          mode = COMMENT_MODE; 
          this.insertCommentString("/*", currentPos-1); 
      } 
      else if (commentStartChar1 == '*' && commentStartChar2 == '/'){ 
          mode = TEXT_MODE; 
          this.insertCommentString("*/", currentPos-1); 
      } 
    } 
  } 

  private void processChar(String str){ 
    char strChar = str.charAt(0); 
    if (mode != this.COMMENT_MODE){ 
      mode = TEXT_MODE; 
    } 
      switch (strChar){ 
        case ('{'):case ('}'):case (' '): case('\n'): 
        case ('('):case (')'):case (';'):case ('.'):{ 
          checkForKeyword(); 
          if (mode == STRING_MODE && strChar == '\n'){ 
            mode = TEXT_MODE; 
          } 
          if (codeReflectionOn){ 
            checkForStateChange(strChar); 
          } 
        } 
        break; 
        case ('"'):{ 
          insertTextString(str, currentPos); 
          this.checkForString(); 
        } 
        break; 
        case ('0'):case ('1'):case ('2'):case ('3'):case ('4'): 
        case ('5'):case ('6'):case ('7'):case ('8'):case ('9'):{ 
          checkForNumber(); 
        } 
        break; 
        case ('*'):case ('/'):{ 
          checkForComment(); 
        } 
        break; 
      } 
      if (mode == this.TEXT_MODE){ 
        this.checkForString(); 
      } 
      if (mode == this.STRING_MODE){ 
        insertTextString(str, this.currentPos); 
      } 
      else if (mode == this.NUMBER_MODE){ 
        insertNumberString(str, this.currentPos); 
      } 
      else if (mode == this.COMMENT_MODE){ 
        insertCommentString(str, this.currentPos); 
      } 

  } 

  private void processChar(char strChar){ 
      char[] chrstr = new char[1]; 
      chrstr[0] = strChar; 
      String str = new String(chrstr); 
      processChar(str); 
  } 

  public void insertString(int offs, 
                          String str, 
                          AttributeSet a) throws BadLocationException{ 
    super.insertString(offs, str, normal); 

    int strLen = str.length(); 
    int endpos = offs + strLen; 
    int strpos; 
    codeReflectionOn = strLen == 1; 
    for (int i=offs;i<endpos;i++){ 
      currentPos = i; 
      strpos = i - offs; 
      processChar(str.charAt(strpos)); 
    } 
    currentPos = offs; 
  } 

  public Vector getKeywords(){ 
    return this.keywords; 
  } 

  public void setKeywords(Vector aKeywordList){ 
    if (aKeywordList != null){ 
      this.keywords = aKeywordList; 
    } 
  } 
} 

Listing 9: 
  

package CodeEditor; 
import java.util.*; 

public class CodePackage { 
  public String packageName = ""; 
  public Vector imports = new Vector(); 
  public CodeClass outerClass = new CodeClass(); 
  public Vector innerClasses = new Vector(); 
  public CodePackage() { 
  } 
} 

Listing 10:
 
package CodeEditor; 
import java.awt.event.*; 

public interface MethodListener { 
  public void methodAction(ActionEvent e); 

} 
  
  
      
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: info@sys-con.com

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.