可以看到,终于达到了当时设想的预期,能够真正超越边界的代码提示。当然,目前仅仅用了国家代号作为代码库。基本的判断也是很简单的,就是查看光标前到空格处的文字,是否能在代码库里面搜索到相应的内容。编程IDE【3】,对Document直接处理" TITL_java n-ide">
当前位置:   article > 正文

java自己造 编程IDE【3】,对…_java n-ide

java n-ide
效果图:
java自己造 <wbr>编程IDE【3】,对Document直接处理
可以看到,终于达到了当时设想的预期,能够真正超越边界的代码提示。当然,目前仅仅用了国家代号作为代码库。基本的判断也是很简单的,就是查看光标前到空格处的文字,是否能在代码库里面搜索到相应的内容。

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

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

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

    public String getCurtAnalysStr() {
        return curtAnalysStr;
    }
    
    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 = new DefaultListModel();
        jl1 = new JList();
        jl1.setModel(dlm);
        jl1.addFocusListener(new FocusListener(){
            @Override
            public void focusGained(FocusEvent fe) {
                jep1.requestFocus();
            }
            @Override public void focusLost(FocusEvent fe) {}
        });
        JScrollPane jsp1=new JScrollPane(jl1);
        
        popupMenu = new JPopupMenu();
        popupMenu.add(jsp1);
        jep1.addKeyListener(new mKeyListener());
        jep1.addCaretListener(new mCaretListener());
        
    }
    
    private class mKeyListener implements KeyListener{
        //用于监听所有在文本框的按键指令
            @Override public void keyTyped(KeyEvent e) {
                
            }
            @Override public void keyPressed(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()){
                        String selectedValue=jl1.getSelectedValue().toString();
                        System.out.println("Selected Value==" + selectedValue);
                        int removeWords = getCurtAnalysStr().length();
                        
                        try {
                            jep1.getDocument().remove(jep1.getCaretPosition()-removeWords, removeWords);
                        } catch (BadLocationException ex) {
                            Logger.getLogger(JCodeCompletePopupMenu.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        
                        try {
                            jep1.getDocument().insertString(jep1.getCaretPosition(), selectedValue, null);
                        } catch (BadLocationException ex) {
                            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 void keyReleased(KeyEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }
    }

    private class mCaretListener implements CaretListener{
        @Override
            public void caretUpdate(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;
                        }else if(str.charAt(i)=='\n'){
                            break;
                        }
                    }
                   
                    String tmp;
                    if(dotposi!=0 && i==0){
                        tmp = str.substring(i, dotposi);
                    }else if(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(String input){
        dlm.removeAllElements();
        if (!input.isEmpty()) {
            items.stream().filter((item) -> (item.toLowerCase().startsWith(input.toLowerCase()))).forEach((item) -> {
                dlm.addElement(item);
                //dlm.set(5, item);
            });
        }
        return dlm.size()!=0;
    }
    
    private void showPopupList(){
       
    }
    
    private String rmMicroSoftWindowsEnter(String str){
       
        String[] strArry = str.split("\r");
        int lineCount = strArry.length;
        StringBuilder sb = new StringBuilder();
        for (String stmp : strArry) {
            sb.append(stmp);
        }
        return sb.toString();
    }
    
}







声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/994109
推荐阅读
相关标签
  

闽ICP备14008679号