【问题标题】:How to highlight multiple nodes in JTree based on a list如何根据列表突出显示JTree中的多个节点
【发布时间】:2019-06-19 16:05:14
【问题描述】:

我正在构建一个使用 JTree 的应用程序。我无法根据列表中的结果突出显示多个节点。

我尝试使用 DefaultTreeRenderer 进行渲染,但它突出显示了列表中的最后一项。每次遍历列表时,我都会调用 JTree setcellrenderer。

import java.awt.*;
import java.util.ArrayList;
import java.util.Objects;
import javax.swing.*;
import javax.swing.tree.DefaultTreeCellRenderer;


public final class MainPanel extends JPanel {
  private final JTree tree = new JTree();
  private final HighlightTreeCellRenderer renderer = new HighlightTreeCellRenderer();
  private ArrayList<String> list = new ArrayList<String>();

  public MainPanel() {
    super(new BorderLayout(5, 5));
    list.add("football");
    list.add("soccer");

    JPanel n = new JPanel(new BorderLayout());

    n.setBorder(BorderFactory.createTitledBorder("Highlight Search"));

    tree.setCellRenderer(renderer);
    for(String str:list)
    renderer.setQuery(str);


    setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    add(n, BorderLayout.NORTH);
    add(new JScrollPane(tree));
    setPreferredSize(new Dimension(320, 240));
  }







  public static void main(String... args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGui();
      }
    });
  }

  public static void createAndShowGui() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
      Toolkit.getDefaultToolkit().beep();
    }
    JFrame frame = new JFrame("@title@");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MainPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}

class HighlightTreeCellRenderer extends DefaultTreeCellRenderer {
  private static final Color ROLLOVER_ROW_COLOR = new Color(0xDC_F0_FF);
  private String query;
  private boolean rollOver;

  @Override public void updateUI() {
    setTextSelectionColor(null);
    setTextNonSelectionColor(null);
    setBackgroundSelectionColor(null);
    setBackgroundNonSelectionColor(null);
    super.updateUI();
  }

  public void setQuery(String query) {
    this.query = query;
  }

  @Override public Color getBackgroundNonSelectionColor() {
    return rollOver ? ROLLOVER_ROW_COLOR : super.getBackgroundNonSelectionColor();
  }

  @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
    Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
    if (selected) {
      c.setForeground(getTextSelectionColor());
    } else {
      rollOver = Objects.nonNull(query) && !query.isEmpty() && Objects.toString(value, "").startsWith(query);
      c.setForeground(getTextNonSelectionColor());
      c.setBackground(getBackgroundNonSelectionColor());
    }

    return c;
  }
}

在“体育”节点下,“足球”和“足球”都应突出显示,但只有列表中的最后一项:“足球”被突出显示。

【问题讨论】:

    标签: java swing awt rendering jtree


    【解决方案1】:

    您调用 setQuery() 两次,第二次调用只是替换渲染器中的查询。使用查询集合或正则表达式来合并模式,例如“^(football|soccer).*”

    【讨论】:

    • 我也调用了两次,但只有最后一个调用被打印了。
    • 第二个建议有效,我使用了字符串方法“.contains()”
    【解决方案2】:

    我在 renderer.setQuery() 方法中将整个列表作为字符串发送。然后我检查了查询是否包含“值”(getTreeCellRendererComponent() 的一个参数)。

    总之:

    第 26 行:renderer.setQuery(list.toString()); 第 93 行:翻转 = Objects.nonNull(query) && !query.isEmpty() && query.contains(value.toString());

    【讨论】:

      猜你喜欢
      • 2013-06-11
      • 1970-01-01
      • 2015-10-30
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-11
      • 2021-07-31
      相关资源
      最近更新 更多