Java Swing JList配合JTextField过滤正常但文本高亮失效求助
问题修复方案
1. 修复JListFilterDecorator,过滤后强制刷新列表
当前过滤逻辑仅更新了列表模型,没有触发JList重新渲染单元格,导致渲染器的高亮逻辑始终未被调用。需要修改JListFilterDecorator类:
public class JListFilterDecorator { private JTextField filterField; // 新增成员变量保存JList实例 private JList<?> targetList; public static <T> JListFilterDecorator decorate(JList<T> list, BiPredicate<T, String> userFilter) { if (!(list.getModel() instanceof DefaultListModel)) { throw new IllegalArgumentException("List model must be an instance of DefaultListModel"); } DefaultListModel<T> model = (DefaultListModel<T>) list.getModel(); List<T> items = getItems(model); JTextField textField = new JTextField(); textField.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { filter(); } @Override public void removeUpdate(DocumentEvent e) { filter(); } @Override public void changedUpdate(DocumentEvent e) { filter(); } private void filter() { model.clear(); String s = textField.getText(); for (T item : items) { if(userFilter.test(item, s)){ model.addElement(item); } } // 新增:过滤完成后强制刷新列表渲染 list.repaint(); } }); JListFilterDecorator decorator = new JListFilterDecorator(); decorator.filterField = textField; decorator.targetList = list; return decorator; } // 其余原有代码保持不变 }
2. 修复单元格渲染器,同步字体属性
创建LabelHighlighted实例时没有同步原渲染器的字体,导致FontMetrics计算高亮位置时使用默认字体,和实际显示字体不匹配,高亮区域会完全错位甚至不可见。修改渲染器代码:
private ListCellRenderer<? super PacienteDTO> createListPacientesRenderer(JTextField filterField) { return new DefaultListCellRenderer() { private static final long serialVersionUID = 1L; @Override public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (c instanceof JLabel) { PacienteDTO emp = (PacienteDTO) value; JLabel original = (JLabel) c; LabelHighlighted label = new LabelHighlighted(); label.setText(emp.toString()); label.setBackground(original.getBackground()); label.setForeground(original.getForeground()); label.setOpaque(original.isOpaque()); label.setHorizontalTextPosition(original.getHorizontalTextPosition()); // 新增:同步原渲染器的字体 label.setFont(original.getFont()); // 新增:过滤占位符,避免把默认提示文本当搜索词 String filterText = filterField.getText(); if ("Busque aquí...".equals(filterText) || filterText.isBlank()) { label.reset(); } else { label.highlightText(filterText); } return label; } return c; } }; }
可选优化
如果需要选中状态下高亮也正常显示,可以调整LabelHighlighted的高亮颜色透明度,或者在选中时切换高亮色,避免和选中背景色冲突。
内容的提问来源于stack exchange,提问作者diegogs_
相关产品推荐
相关产品推荐

