Лучший способ реализовать всплывающие подсказки для JTree?

Поскольку JTree и TreeModel не предоставляют всплывающие подсказки прямо из коробки, как вы думаете, как лучше всего иметь всплывающие подсказки для конкретных элементов для JTree?

Обновлено: (отвечая на мой собственный вопрос позже.)

@Zarkonnen: Спасибо за идею getTooltipText.

Я нашел другой (может быть, еще более приятный) способ переопределения DefaultTreeCellRenderer и решил поделиться им:

public class JTreeWithToolTips {
    private static class OwnRenderer extends DefaultTreeCellRenderer {
        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean sel, boolean expanded, boolean leaf, int row,
                boolean hasFocus) {
            setToolTipText("foobar" + row);
            return super.getTreeCellRendererComponent(tree, value, sel,
                    expanded, leaf, row, hasFocus);
        }
    }

    public static void main(String[] args) {
        JTree tree = new JTree(new Object[] { "foo", "bar", "foobar" });
        tree.setCellRenderer(new OwnRenderer());
        ToolTipManager.sharedInstance().registerComponent(tree);

        JFrame frame = new JFrame();
        frame.getContentPane().add(tree);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

Ваш ответ должен быть в ответе, чтобы люди могли проголосовать за него.

Michael Myers 07.11.2008 18:28

DefaultTreeCellRenderer # getTreeCellRendererComponent вызывается очень часто, и если сделать его слишком тяжелым, это может привести к тому, что все будет работать не так, как ожидалось. Как всплывающие подсказки, которые должны появиться, но их нет. Переопределение JTree # getToolTipText (MouseEvent e) вызывается только при необходимости, и поэтому это гораздо лучшее решение!

NomeN 11.07.2013 20:43

Когда я попробовал это, всплывающая подсказка не появилась. Однако ответ Зарконнена сработал.

Amber 15.11.2016 01:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
19
3
11 584
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

См. getTooltipText на JTree. Это должно позволить вам показывать всплывающие подсказки в зависимости от того, над чем в дереве наведен курсор. (Тем не менее, прочтите документацию, вам необходимо зарегистрировать JTree с помощью ToolTipManager.)

+1 за то, что отметили, что вам нужно зарегистрироваться в ToolTipManager. Несмотря на то, что это есть в документации, его легко пропустить.

Rangi Keen 11.06.2015 22:29

Да, вы можете использовать onMouseMoved, а затем использовать метод (я не помню название), который сообщает вам, на каком узле вы закончили. Если вы получили значение null, очевидно, что вы не вышли за узел.

Поскольку это нигде не упоминается: методы, связывающие позицию мыши с узлом дерева, - это getPathForLocation(int, int) и getRowForLocation(int, int). Как предполагают другие ответы, реализация настраиваемого средства визуализации или переопределение getToolTipText(MouseEvent) чище, чем добавление MouseListener.

Hollis Waite 18.12.2013 17:40

Имея дело с конкретными подклассами TreeNode, основываясь на вашем собственном ответе и комментариях, я придумал интерфейс для реализации моего TreeNode.

Обратите внимание, как мы проверяем, является ли value интансом Tooltipable в TreeCellRenderer:

public static interface Tooltipable {
    public String getToolTip();
}

public static class TheNode extends DefaultMutableTreeNode implements Tooltipable {

    private String shortDesc, longDesc;

    public TheNode(String shortDesc, String longDesc) {
        super();
        this.shortDesc = shortDesc;
        this.longDesc = longDesc;
    }

    @Override
    public String getToolTip() {
        return longDesc;
    }

    @Override
    public String toString() {
        return shortDesc;
    }
}

public static class TheModel extends DefaultTreeModel {
    public TheModel() {
        super(new TheNode("Root", "The base of everything"));
        TheNode root = (TheNode)getRoot();
        root.add(new TheNode("Second", "I am a number two"));
        TheNode node = new TheNode("Third", "Another one bites the dust");
        root.add(node);
        node.add(new TheNode("Last", null)); // No tooltip for this one
    }
}

public static class TreeTooltipRenderer extends DefaultTreeCellRenderer {
    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        if (value instanceof Tooltipable)
            setToolTipText(((Tooltipable)value).getToolTip());
        return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
    }
}

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setBounds(100, 100, 300, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTree tree = new JTree(new TheModel());
    ToolTipManager.sharedInstance().registerComponent(tree);
    tree.setCellRenderer(new TreeTooltipRenderer());
    frame.add(new JScrollPane(tree), BorderLayout.CENTER);
    frame.setVisible(true);
}

Другие вопросы по теме