JComboBoxのリストアイテムをHighlighterで強調表示する
Total: 1556, Today: 1, Yesterday: 4
Posted by aterai at 
Last-modified: 
Summary
JComboBoxのセルレンダラーにJTextFieldを使用して、エディタで入力中の文字列とマッチするリストアイテム内の文字列をハイライト表示します。
Screenshot

Advertisement
Source Code Examples
Highlighter.HighlightPainter highlightPainter =
    new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
JComboBox<String> combo = new JComboBox<String>(model) {
  @Override public void updateUI() {
    super.updateUI();
    JTextField field = new JTextField(" ");
    field.setOpaque(true);
    field.setBorder(BorderFactory.createEmptyBorder());
    ListCellRenderer<? super String> renderer = getRenderer();
    setRenderer((list, value, index, isSelected, cellHasFocus) -> {
      String pattern = ((JTextField) getEditor().getEditorComponent()).getText();
      if (index >= 0 && !pattern.isEmpty()) {
        Highlighter highlighter = field.getHighlighter();
        highlighter.removeAllHighlights();
        String txt = Objects.toString(value, "");
        field.setText(txt);
        addHighlight(highlighter, Pattern.compile(pattern).matcher(txt));
        field.setBackground(isSelected ? new Color(0xAA_64_AA_FF, true)
                                       : Color.WHITE);
        return field;
      }
      return renderer.getListCellRendererComponent(
          list, value, index, isSelected, cellHasFocus);
    });
  }
  private void addHighlight(Highlighter highlighter, Matcher matcher) {
    int pos = 0;
    try {
      while (matcher.find(pos) && !matcher.group().isEmpty()) {
        int start = matcher.start();
        int end = matcher.end();
        highlighter.addHighlight(start, end, highlightPainter);
        pos = end;
      }
    } catch (BadLocationException ex) {
      // should never happen
      RuntimeException wrap = new StringIndexOutOfBoundsException(
          ex.offsetRequested());
      wrap.initCause(ex);
      throw wrap;
    }
  }
};
Description
- JComboBoxを編集可能に設定し、そのエディタで入力中の文字列から- Patternを生成
- ListCellRendererでリストアイテム文字列を上記のパターンで検索- 一致する場合はJTextField#getHighlighter().addHighlight(...)でハイライトを追加したJTextFieldをセルレンダラーコンポーネントとして返す
- 一致しない場合はデフォルトのJLabelをセルレンダラーコンポーネントとして返す
 
- 一致する場合は
Reference
- JTableの検索結果をRowFilterとHighlighterで強調表示する
- JComboBoxで候補一覧を表示
- JComboBoxのリストアイテムのフィルタリングは、このリンク先のサンプルとほぼ同じものを使用