java自己造 编程IDE【3】,对…

来源:互联网 发布:世界人工智能大会 北京 编辑:程序博客网 时间:2024/06/04 19:52
效果图:
java自己造 <wbr>编程IDE【3】,对Document直接处理
可以看到,终于达到了当时设想的预期,能够真正超越边界的代码提示。当然,目前仅仅用了国家代号作为代码库。基本的判断也是很简单的,就是查看光标前到空格处的文字,是否能在代码库里面搜索到相应的内容。

java自己造 <wbr>编程IDE【3】,对Document直接处理
这次将整个代码提示控件封装成了一个类,用界面编辑器绘制好界面以后,只需要将JEditorPane塞到构造函数里面就可以了,这个类将为JEditorPane添加相应的监听器,捕捉事件,并在相应的时候弹出代码提示框。
下一步考虑如何将判断逻辑抽象出来,毕竟提示什么样的代码,是语言相关的。

importjava.awt.Point;
importjava.awt.Toolkit;
importjava.awt.event.FocusEvent;
importjava.awt.event.FocusListener;
importjava.awt.event.KeyEvent;
importjava.awt.event.KeyListener;
importjava.util.ArrayList;
importjava.util.Locale;
importjava.util.logging.Level;
importjava.util.logging.Logger;
importjavax.swing.DefaultListModel;
importjavax.swing.JEditorPane;
importjavax.swing.JList;
importjavax.swing.JPopupMenu;
importjavax.swing.JScrollPane;
importjavax.swing.event.CaretEvent;
importjavax.swing.event.CaretListener;
importjavax.swing.text.BadLocationException;
importjavax.swing.text.Caret;

public classJCodeCompletePopupMenu {
   private final JEditorPane jep1;
   private DefaultListModel dlm;
   private JList jl1;
   private JPopupMenu popupMenu;
   private finalArrayList<String> items;
   private String curtAnalysStr;
   private int rate;

   public String getCurtAnalysStr() {
       returncurtAnalysStr;
   }
   
   public JCodeCompletePopupMenu(JEditorPane jep1,ArrayList<String> items){
       this.jep1= jep1;
       this.items= items;
      initComponent();
   }
   
   public JCodeCompletePopupMenu(JEditorPane jep1){
       this.jep1= jep1;
       Locale[]locales = Locale.getAvailableLocales();
     
       items =new ArrayList<>();
       for(Locale locale : locales) {
          String item =locale.getDisplayName();
          items.add(item);
      }
      initComponent();
   }
   
   private void initComponent(){
      
       rate =Toolkit.getDefaultToolkit().getScreenResolution()/288;
      
       dlm = newDefaultListModel();
       jl1 = newJList();
      jl1.setModel(dlm);
      jl1.addFocusListener(new FocusListener(){
          @Override
          public voidfocusGained(FocusEvent fe) {
             jep1.requestFocus();
          }
          @Override public voidfocusLost(FocusEvent fe) {}
      });
      JScrollPane jsp1=new JScrollPane(jl1);
      
       popupMenu= new JPopupMenu();
      popupMenu.add(jsp1);
      jep1.addKeyListener(new mKeyListener());
      jep1.addCaretListener(new mCaretListener());
      
   }
   
   private class mKeyListener implementsKeyListener{
      //用于监听所有在文本框的按键指令
          @Override public voidkeyTyped(KeyEvent e) {
             
          }
          @Override public voidkeyPressed(KeyEvent e) {
            
             int keycode = e.getKeyCode();
             if(keycode == KeyEvent.VK_DOWN || keycode ==KeyEvent.VK_UP){
                 //如果输入的上下方向键
                 if(popupMenu.isShowing()) { //所以增加该窗口是否show的判断
                    e.setSource(jl1);   //设置新的event源
                   jl1.dispatchEvent(e);//传输给jl1,dispatch: vt. 派遣;分派
                }
             }else if(keycode ==KeyEvent.VK_ENTER){
                //System.out.println("e.getKeyCode()=="+e.getKeyCode());
               
                e.setSource(popupMenu);
                popupMenu.dispatchEvent(e);
                if(popupMenu.isVisible()){
                    StringselectedValue=jl1.getSelectedValue().toString();
                   System.out.println("SelectedValue==" + selectedValue);
                    int removeWords =getCurtAnalysStr().length();
                   
                    try {
                      jep1.getDocument().remove(jep1.getCaretPosition()-removeWords,removeWords);
                    } catch (BadLocationExceptionex) {
                      Logger.getLogger(JCodeCompletePopupMenu.class.getName()).log(Level.SEVERE,null, ex);
                    }
                   
                    try {
                      jep1.getDocument().insertString(jep1.getCaretPosition(),selectedValue, null);
                    } catch (BadLocationExceptionex) {
                      Logger.getLogger(JCodeCompletePopupMenu.class.getName()).log(Level.SEVERE,null, ex);
                    }
                   
                   popupMenu.setVisible(false);
                }
                
             }else if (e.isControlDown()&& e.getKeyCode() ==KeyEvent.VK_BACK_SLASH &&!popupMenu.isShowing()) {
                //按键k开启提示窗口
                 Caret crt= jep1.getCaret();
                 Point p =crt.getMagicCaretPosition();
                 if (p ==null) {
                 } else{
                    int x =(int)p.getX();
                    int y =(int)p.getY();
                   //设置窗体的显示位置,相对于母组件
                   popupMenu.show(e.getComponent(), x,y+jl1.getFont().getSize());
                   jl1.setSelectedIndex(0);
                   //System.out.println(x+""+y+20);
                   
                   jep1.requestFocusInWindow(); 
                }
             }else{
               
             }
             
          }
          @Override public voidkeyReleased(KeyEvent e) {
             //throw newUnsupportedOperationException("Not supportedyet.");
          }
   }

   private class mCaretListener implementsCaretListener{
      @Override
          public voidcaretUpdate(CaretEvent ce) {
             //该【光标监听器】用于获取光标附近所取得的文本,用于判断和显示提示符
             int dotposi = ce.getDot();
             
             Caret crt = jep1.getCaret();
             Point p =crt.getMagicCaretPosition();//获取该光标的像素点位置,用于打印
             if (p == null) {
                //System.out.println(";
             } else {
                 String str= jep1.getText();
                 //i从光标处的前一个字符开始历遍,直到找到空格
                 int i =ce.getDot()-1;
               
                str=rmMicroSoftWindowsEnter(str);
               
                for(;i>0;i--){
                    if(i==0 ||str.charAt(i)==' '){
                       break;
                    }elseif(str.charAt(i)=='\n'){
                       break;
                    }
                }
               
                 Stringtmp;
                if(dotposi!=0 &&i==0){
                    tmp = str.substring(i,dotposi);
                 }elseif(dotposi!=0 &&i!=0){
                    tmp = str.substring(i+1,dotposi);
                }else{
                    tmp ="";
                }
                curtAnalysStr=tmp;
                if(updateList(tmp)){
                   
                    p =crt.getMagicCaretPosition();
                    //crt.get
                    int x =(int)p.getX();
                    int y =(int)p.getY();
                    //设置窗体的显示位置,相对于母组件30*rate
                   
                    popupMenu.show(jep1, x,y+jl1.getFont().getSize());
                   jl1.setSelectedIndex(0);
                   
                   jep1.requestFocusInWindow(); 
                }else{
                   popupMenu.setVisible(false);
                }
             }
          }
   }
   
   private boolean updateList(Stringinput){
      dlm.removeAllElements();
       if(!input.isEmpty()) {
          items.stream().filter((item)->(item.toLowerCase().startsWith(input.toLowerCase()))).forEach((item)-> {
             dlm.addElement(item);
             //dlm.set(5, item);
          });
      }
       returndlm.size()!=0;
   }
   
   private void showPopupList(){
     
   }
   
   private String rmMicroSoftWindowsEnter(Stringstr){
     
       String[]strArry =str.split("\r");
       intlineCount = strArry.length;
      StringBuilder sb = new StringBuilder();
       for(String stmp : strArry) {
          sb.append(stmp);
      }
       returnsb.toString();
   }
   
}







0 0
原创粉丝点击