JComboBoxのリストアイテムをHighlighterで強調表示する
Total: 1301
, Today: 1
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
JComboBox
のセルレンダラーにJTextField
を使用して、エディタで入力中の文字列とマッチするリストアイテム内の文字列をハイライト表示します。
Screenshot
Advertisement
サンプルコード
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;
}
}
};
View in GitHub: Java, Kotlin解説
JComboBox
を編集可能に設定し、そのエディタで入力中の文字列からPattern
を生成ListCellRenderer
でリストアイテム文字列を上記のパターンで検索- 一致する場合は
JTextField#getHighlighter().addHighlight(...)
でハイライトを追加したJTextField
をセルレンダラーコンポーネントとして返す - 一致しない場合はデフォルトの
JLabel
をセルレンダラーコンポーネントとして返す
- 一致する場合は
参考リンク
- JTableの検索結果をRowFilterとHighlighterで強調表示する
- JComboBoxで候補一覧を表示
JComboBox
のリストアイテムのフィルタリングは、このリンク先のサンプルとほぼ同じものを使用