AmpersandCompletionDialog.java :  » IDE » tIDE » tide » editor » completions » Java Open Source

Java Open Source » IDE » tIDE 
tIDE » tide » editor » completions » AmpersandCompletionDialog.java
package tide.editor.completions;

import tide.editor.MainEditorFrame;
import snow.sortabletable.*;
import tide.utils.SyntaxUtils;
import java.util.*;
import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.EventQueue;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

/** Javadoc or annotations, depending on context.
*   BAD NAME, should not be Ampersand but "At"
*  TODO: fetch available annotations (types).
*/
public class AmpersandCompletionDialog extends JDialog implements CompletionDialog
{
  final private CompletionModel cm = new CompletionModel();
  private final SortableTableModel stm = new SortableTableModel(cm);
  final private AdvancedSearchPanel asp = new AdvancedSearchPanel("@ ", null, stm, false);
  private final JTable table = new JTable(stm);
  private final JPanel optsPanel = new JPanel();
  private final String preceedingTokenOfInterrest;

  private boolean wasCancelled = true;

  public AmpersandCompletionDialog( final boolean inComment, JFrame owner, int x, int y,
     final Document doc, final int docOffset, final String preceedingTokenOfInterrest )
  {
    super(owner, "Completion", true);

    this.preceedingTokenOfInterrest = preceedingTokenOfInterrest;
    setLayout(new BorderLayout(0,0));

    add(new JScrollPane(table), BorderLayout.CENTER);
    stm.installGUI(table);
    stm.setSortedColumnAndOrder(-1,true);  // avoid sorting.
    table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);


    add(optsPanel, BorderLayout.SOUTH);
    optsPanel.setVisible(false);

    add(asp, BorderLayout.NORTH);

    final int fontSize = UIManager.getFont("Label.font").getSize();

    // fixed, but fontsize relative size :
    this.setSize( fontSize*45 ,fontSize*30  );
    this.setLocation(x,y);


    CompletionUtils.controlTableWithFieldKeys(asp.getTextField(), table, this, "");

    table.addKeyListener(new KeyAdapter()
    {
       @Override public void keyTyped(KeyEvent ke)
       {
          char c = ke.getKeyChar();
          if(Character.isLetterOrDigit(c))
          {
            asp.getTextField().setText( asp.getTextField().getText()+c );
            asp.doSearch();
          }
       }
    });

    ((JComponent) getContentPane()).registerKeyboardAction(new ActionListener()
    {
       public void actionPerformed(ActionEvent ae)
       {
          wasCancelled = true;
          setVisible(false);
          return;
       }
    }, "Escape", KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

    ((JComponent) getContentPane()).registerKeyboardAction(new ActionListener()
    {
       public void actionPerformed(ActionEvent ae)
       {
          wasCancelled = false;
          setVisible(false);
          return;
       }
    }, "Enter", KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

    // immediately show the dialog, delay the construction of the model to later !!
    // so the user have an immediate completion
    Thread t = new Thread()
    {
     public void run()
     {
       List<String>[] args = null;

       try
       {

          if(inComment)
          {
            String txtAfter= doc.getText(docOffset,doc.getLength()-docOffset); //offset,length
            args = SyntaxUtils.parseSignatureAfterForJavaDoc(txtAfter, 0);
            if(args!=null && args[1]!=null && args[1].size()>0)
            {
               offerAddingAll(args);
            }
            else
            {
              // System.out.println("NO arg compl");
            }

          }
       }
       catch(Exception e)
       {
          e.printStackTrace();
       }
       // Quick !
       cm.initialize(inComment, args);

       EventQueue.invokeLater(new Runnable() { public void run() {
          setTitle( (inComment ? "Javadoc tag completion" :"Annotation completion") );
       }});
     }
    };
    t.setPriority(Thread.NORM_PRIORITY-1);
    t.start();

    this.setVisible(true);
  } // initialize

  String customReplace = null;

 /** Generates the param tags for all entries...
 */
  private void offerAddingAll(final List<String>[] params)
  {

    EventQueue.invokeLater(new Runnable() { public void run() {

     //System.out.println("adding all params: "+Arrays.toString(params));

     JButton addAll = new JButton("Add javadoc tags for all parameters");
     addAll.setMargin(new Insets(0,1,0,1));
     addAll.setFocusPainted(false);
     optsPanel.add(addAll);
     optsPanel.setPreferredSize(optsPanel.getPreferredSize());
     optsPanel.setVisible(true);

     // must restitue the focus !
     asp.getTextField().requestFocus();

     addAll.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae)
     {
        StringBuilder sb = new StringBuilder();
        for( String pn: params[1] )
        {
           // TODO: look for the correct indent !
           sb.append("\n  * @param "+pn+" ");
        }
        customReplace = ""+sb;
        selectAndQuit();
     } });

    }});

  }


  public void selectAndQuit()
  {
    this.wasCancelled = false;
    setVisible(false);
  }

  public void cancelDialog()
  {
    this.wasCancelled = true;
    setVisible(false);
  }


  public boolean getWasCancelled()
  {
    return wasCancelled;
  }

  public String getSelection()
  {
     if(customReplace!=null) return customReplace;

    if(table.getSelectedRow()==-1)
    {
      // no selection, return the typed text, with @
      return "@"+asp.getTextField().getText();
    }
    // return the selected table element followed by a space
    int pos = stm.getIndexInUnsortedFromTablePos( table.getSelectedRow() );
    String sel = ""+cm.getValueAt(pos,0)+" ";
    if(sel.startsWith("{")) sel = sel.substring(1);  // don't repeat several "{"
    return sel;
  }


  static class CompletionModel extends FineGrainTableModel
  {
     List<Item> items = new ArrayList<Item>();
     int columns = 2;

     public void initialize(boolean isInComment, List<String>[] parsedMethodArgs)
     {
       if(isInComment)
       {
          columns=1;

          items.add(new Item("@author",  "",    "1.0"));
          items.add(new Item("@deprecated", "", "1.0"));
          items.add(new Item("@exception",  "", "1.0"));
          items.add(new Item("@return",  "",    "1.0"));
          items.add(new Item("@see",     "syntax: @see fullClassName or #methodName",    "1.0"));
          items.add(new Item("@serial",   "",   "1,2"));
          items.add(new Item("@serialData",  "","1.2"));
          items.add(new Item("@serialField", "","1.2"));
          items.add(new Item("@since",     "",  "1.1"));
          items.add(new Item("@throws",    "",  "1.2"));
          items.add(new Item("@version",   "",  "1.0"));
          //items.add(new Item("@beaninfo\n  attribute: xxx\n  description: yyy", "",  "1.0"));

          items.add(new Item("{@value  }",   "",  "1.4"));
          items.add(new Item("{@code  }",  "",    "1.5"));
          items.add(new Item("{@docRoot  }",  "", "1.3"));
          items.add(new Item("{@inheritDoc  }","","1.4"));
          items.add(new Item("{@link  }",     "", "1.2"));
          items.add(new Item("{@linkplain  }","", "1.4"));
          items.add(new Item("{@literal  }",  "", "1.5"));

          if(parsedMethodArgs!=null)
          {
             @SuppressWarnings("unchecked")
             List<String> ls = parsedMethodArgs[1];
             for(String pn : ls)
             {
                items.add(new Item("@param "+pn,   "parameter"));
             }

             if(ls.size()>0)
             {
                // offer adding all
             }
          }
          else
          {
             items.add(new Item("@param",   ""));
          }
       }
       else
       {
          columns=2;  // not ok, needs a structchanged... but also need to be improved... why not javadoc ?... TODO.
          items.add(new Item("@SuppressWarnings(\"unchecked\")", "Suppress the compiler Xlint warnings for unchecked generic types."));
          items.add(new Item("@Deprecated", "Annotate deprecated methods"));
          items.add(new Item("@Override", "Annotate methods that override the parent method."));
          items.add(new Item("@WebService", "defines a web service (compiler wil generate WSDL)."));
          items.add(new Item("@SOAPBinding(style=SOAPBinding.Style.RPC)", "Specifies the communication type for a WebService."));
          items.add(new Item("@WebOperation(exclude=true)", "Excludes the method from WebService."));
          items.add(new Item("@org.junit.Test", "mark a method to test. (Requires JUnit)."));

          if(MainEditorFrame.instance.sourcesTreePanel.getTreeModel().knownAnnotations.size()>0)
          {
            // TODO: lock ?
            for(String s : MainEditorFrame.instance.sourcesTreePanel.getTreeModel().knownAnnotations)
            {
               items.add(new Item("@"+s, "(in project)"));
            }
          }

          if(MainEditorFrame.instance.librariesPanel.getTreeModel().knownAnnotations.size()>0)
          {
            // TODO: lock ?
            for(String s : MainEditorFrame.instance.librariesPanel.getTreeModel().knownAnnotations)
            {
               if(s.startsWith("java.lang."))
               {
                  s = s.substring(10);
               }
               items.add(new Item("@"+s, "(found in classpath)"));
            }
          }

          // TODO: add also the inner annotations... (not declared as toplevel, iff contained in super or this scope).
       }
       this.setRowSelection(0,true);

       EventQueue.invokeLater(new Runnable() { public void run() {
          fireTableDataChanged();
          fireTableModelHasChanged();
       }});

     }

     public Object getValueAt(int row, int col)
     {
       if(row<0 || row>=items.size()) return ""; //"bad row "+row;

       if(col==0)
       {
         return items.get(row).value;
       }
       return items.get(row).descr;
     }

     public int getRowCount() { return items.size(); }
     public int getColumnCount() { return columns; }

     @Override
     public String getColumnName(int c)
     {
        if(c==0) return "Item";
        if(c==1) return "Descr";
        return "??";
     }
  }


  static class Item
  {
     final String value;
     final String descr;
     final String since;

     public Item(String value, String descr)
     {
        this(value, descr, "1.0");
     }

     public Item(String value, String descr, String since)
     {
        this.value = value;
        this.descr = descr;
        this.since = since;
     }
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.