Java實現文本編輯時基於拼音輸入的補全原型

續前文Java實現"命令式"簡易文本編輯器原型. 效果以下:
java

所在源碼庫同上文, 還沒有和上文的編輯器右側的命令區集成. 代碼由How to show autocomplete as I type in JTextArea?修改得來.算法

基本功能

  • 英文輸入至少一個匹配詞典的字母后, 顯示提示框
  • 上下光標選中某提示項後按空格鍵自動替換
  • 彈出提示框後, 若是繼續鍵入, 提示框隱藏後, 根據新鍵入繼續提示. 好比上面輸入't'後提示"退出"和"粘貼"兩項, 繼續輸入'c'後就只顯示"退出"

IDE和中文輸入法的深度集成是必然趨勢. 雖然如今第三方的中文輸入法能夠解決"輸入"的基本功能, 但在IDE自動補全/智能提示功能日益成爲開發效率提高的必需輔助功能的現今, 只有實現了中文輸入法和IDE補全/提示的集成, 中文編程才能更接近實用. 這早已在易語言開發環境中實現, 期待早日看到開源項目實現相似功能.編程

源碼簡單說明

監聽文本框的按鍵輸入, 並準備彈出提示框:編輯器

文本區.addKeyListener(new KeyListener() {

      @Override
      public void keyTyped(KeyEvent e) {
        隨後顯示提示();
      }
...
    });

彈出以前, 先獲取這次輸入的字符串, 並基於它生成/更新提示框:ide

private void 顯示提示() {
    final int 文本位置 = 文本區.getCaretPosition();
    Point 界面位置;
    try {
      界面位置 = 文本區.modelToView(文本位置).getLocation();
    } catch (BadLocationException e2) {
      e2.printStackTrace();
      return;
    }

    final String 提示源詞 = 取提示源詞(文本位置);
    if (提示源詞 == null) {
      return;
    }

    if (提示 == null) {
      提示 = new 提示框(文本區, 文本位置, 提示源詞, 界面位置);
    } else {
      提示.更新(文本位置, 提示源詞, 界面位置);
    }
  }

提示框部分, 由一個列表來管理提示項的選擇, 文本的替換:spa

private JList<String> 建立提示列表(final String[] 提示列表) {
    JList<String> 列表 = new JList<>(提示列表);
    列表.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    列表.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    列表.setSelectedIndex(0);
    列表.addKeyListener(new KeyListener() {

      @Override
      public void keyTyped(KeyEvent e) {
        if (e.getKeyChar() == KeyEvent.VK_SPACE) {
          if (插入選擇文本()) {
            隱藏();
          }
        } else {
          隱藏();
          文本區.requestFocusInWindow();
          文本區.dispatchEvent(e);
        }
      }

      @Override
      public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
          下移();
        } else if (e.getKeyCode() == KeyEvent.VK_UP) {
          上移();
        }
      }
...
    });
    return 列表;
  }

固然少不了一個字符->中文詞典(以下), 實際應用時須要基於拼音生成提示的算法code

private static final HashMap<String, String[]> 提示詞典 = new HashMap<>();
  static {
    提示詞典.put("xj", new String[] {"新建"});
    提示詞典.put("dk", new String[] {"打開"});
    提示詞典.put("bc", new String[] {"保存"});
    提示詞典.put("jq", new String[] {"剪切"});
    提示詞典.put("fz", new String[] {"複製"});
    提示詞典.put("nt", new String[] {"粘貼"});
    提示詞典.put("zt", new String[] {"粘貼"});
    提示詞典.put("tc", new String[] {"退出"});
    提示詞典.put("j", new String[] {"新建", "剪切"});
    提示詞典.put("t", new String[] {"退出", "粘貼"});
  }
相關文章
相關標籤/搜索