Как выделить несколько узлов в JTree на основе списка - PullRequest
0 голосов
/ 19 июня 2019

Я создаю приложение, которое использует 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;
  }
}

Под узлом "Спорт" должны быть выделены "футбол" и "футбол", но выделяется только последний элемент из списка: "футбол".

Ответы [ 2 ]

0 голосов
/ 24 июня 2019

Я отправил весь список в виде строки в методе renderer.setQuery ().Затем я проверил, содержал ли запрос «значение» (аргумент getTreeCellRendererComponent ()).

Всего:

строка 26: renderer.setQuery (list.toString ());строка 93: rollOver = Objects.nonNull (запрос) &&! query.isEmpty () && query.contains (value.toString ());

0 голосов
/ 20 июня 2019

Вы вызываете setQuery () дважды, второй вызов просто заменяет запрос в рендерере. Используйте набор запросов или, возможно, регулярные выражения для объединения шаблонов, таких как "^ (football | soccer). *"

...