java自己造 编程IDE【2】,消…

来源:互联网 发布:世界人工智能大会 北京 编辑:程序博客网 时间:2024/05/16 07:13
  在jEditorPane编辑,有时候要把一些命令转给其他控件。IDE中最重要的功能之一就是能够“按·上下键”选择备选函数,或者备选的自动补完策略。这点上,一直有个矛盾:
  之前的思路,是在编辑器里监视按键event,然后直接操作另一个控件的focus点……但这样总觉得怪怪的。有时候操作不上,有时候操作上了,直接focus过去了,消息无法回到jEditorPane。之后又绕着弯子,在jlist上也建立一个监听器,当focus到jlist之后,监听到除了上下按键以外的键盘事件,又focus回editor。感觉好傻逼啊,还得计算光标在哪里,回到jEditorPane后还得计算按了哪个按键,根据这个按键在jEditorPane的相应文本处插入键盘想要输入的字符……#¥%@#¥%%¥#@%……
  有没有更好的操作思路呢?
  答案是:当然有了!
  直接把jEditorPane监听到的event送给jList不就好了吗?有这样的函数和功能吗?答案是dispatchEvent()
(思路总结,弹出窗口用JPopupMenu,JList充当选项列表,dispatchEvent来分派event到JList):

import java.awt.Color;
importjava.awt.Dimension;
importjava.awt.Point;
importjava.awt.event.KeyEvent;
importjava.awt.event.KeyListener;
importjava.awt.event.WindowAdapter;
importjava.awt.event.WindowEvent;
importjavax.swing.DefaultListModel;
importjavax.swing.JEditorPane;
importjavax.swing.JFrame;
importjavax.swing.JLayeredPane;
importjavax.swing.JList;
importjavax.swing.JPopupMenu;
importjavax.swing.event.CaretEvent;
importjavax.swing.text.Caret;
public final class V_IDEextends JFrame {
   private static final long serialVersionUID =1L;
   private DefaultListModel dlm;
   private JList jl1;
   private JEditorPane jep1;
   private JPopupMenu popupMenu;
   public V_IDE() {
      super("V_IDE.;
       jl1 = newJList();
       dlm = newDefaultListModel();
      dlm.addElement("asdfwfewfw");
      dlm.addElement("asdfwfewfw");
      dlm.addElement("asdfwf124234ewfw");
      dlm.addElement("asdfwf123ewfw");
      dlm.addElement("asdfwf123ewfw");
      jl1.setModel(dlm);
      
       popupMenu= new JPopupMenu();
      popupMenu.add(jl1);
      
       jep1 = newJEditorPane();
      jep1.setBackground(Color.yellow);
      jep1.setBounds(0, 0, 600, 600); //在这里调整控件的显示位置和大小
      
      jl1.setBounds(100,100,100,400); //在这里调整控件的显示位置和大小
      JLayeredPane layeredPane = getLayeredPane();
      layeredPane.add(jep1, 10, 1);
//      layeredPane.add(jl1, 10, 0);
      setSize(new Dimension(280, 280));
      addWindowListener(new WindowAdapter() {
          @Override
          public voidwindowClosing(WindowEvent e) {
             System.exit(0);
          }
      });

      jep1.addKeyListener(new KeyListener() {
         //用于监听所有在文本框的按键指令
          @Override public voidkeyTyped(KeyEvent e) {
             if (e.getKeyChar() =='k') {
                //按键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+20);
                   
                   jl1.setSelectedIndex(0);
                   System.out.println(x+""+y+20);
                    jep1.requestFocusInWindow();//Mac is of no use, Win10 it works
                }
             }
             
          }
          @Override public voidkeyPressed(KeyEvent e) {
            
             switch(e.getKeyCode()){
                 caseKeyEvent.VK_DOWN:
                    if(popupMenu.isShowing()){//所以增加该窗口是否show的判断
                       e.setSource(jl1);//设置新的event源
                       jl1.dispatchEvent(e);//传输给jl1,dispatch: vt. 派遣;分派
                    }
                    break;
                 caseKeyEvent.VK_UP:
                    if(popupMenu.isShowing()){//所以增加该窗口是否show的判断
                       e.setSource(jl1);
                       jl1.dispatchEvent(e);
                    }
                    break;
             }
             //throw newUnsupportedOperationException("Not supportedyet.");
          }
          @Override public voidkeyReleased(KeyEvent e) {
             //throw newUnsupportedOperationException("Not supportedyet.");
          }
      });
      
      
      jep1.addCaretListener((CaretEvent ce) ->{
         //该【光标监听器】用于获取光标附近所取得的文本,用于判断和显示提示符
          int dotposi =ce.getDot();
         dlm.setElementAt("MARK==" +ce.getMark(), 1);
         dlm.setElementAt("DOT==" +dotposi, 2);
          Caret crt =jep1.getCaret();
          Point p =crt.getMagicCaretPosition();//获取该光标的像素点位置,用于在相应位置显示备选菜单
         //crt.setBlinkRate(32);
          if (p == null) {
            //System.out.println(";
          } else {
             String str = jep1.getText();
             int l = str.length();
             String tmp = null;
             // i从光标处的前一个字符开始历遍,直到找到空格
             int i = ce.getDot()-1;
            
            
             String[] strArry =str.split("\r");
             int lineCount = strArry.length;
             StringBuilder sb = newStringBuilder();
             for (String stmp : strArry) {
                sb.append(stmp);
             }
             str = sb.toString();
             
             for(;i>0;i--){
                 if(i==0 ||str.charAt(i)==' '){
                    break;
                 }elseif(str.charAt(i)=='\n'){
                    break;
                }
             }
             
             if(dotposi!=0 &&i==0){
                 tmp =str.substring(i, dotposi);
             }else if(dotposi!=0&& i!=0){
                 tmp =str.substring(i+1, dotposi);
             }else{
                 tmp ="";
             }
            dlm.setElementAt("<"+tmp+">",0);
            dlm.setElementAt("x==" +p.getX(), 3);
            //dlm.setElementAt("y==" +p.getY(), 4);
            dlm.setElementAt("i==" + i,4);
             int x = (int)p.getX();
             int y = (int)p.getY();
          }
      });
      this.setVisible(true);
   }
}



0 0