JTree: ускорить отрисовку 1000+ дочерних узлов из объектов, извлеченных из базы данных? - PullRequest
5 голосов
/ 01 ноября 2011

Когда я получаю более 1000 java-объектов из базы данных, это делается очень быстро. В итоге List<Object> соответствует моему запросу.

Проблема заключается в рисовании этих объектов на Jtree.

Например, у меня есть parentID данного узла. Если дважды щелкнуть по этому узлу (DefaultMutableTreeNode) (TreeMouseListener.class), он отобразит прямых потомков этого узла, а не всех потомков (хотя это может потребоваться позже, если это возможно, но не сейчас).

Проблема в том, что эта операция рисования jtree занимает очень много времени, чтобы завершить добавление 1000+ дочерних элементов DefaultMutableTreeNodes для выбранного родительского узла.

ex) 1000 из new DefaultMutableTreeNode(Person person);

Как ускорить процесс рисования?

Я не использую никаких пользовательских средств визуализации ячеек и не отображаю ничего, кроме небольших фрагментов текста для каждого узла.

Ответы [ 3 ]

5 голосов
/ 01 ноября 2011

Вам понадобится время, когда замедление будет, но я сомневаюсь, что это просто создание DefaultMutableTreeNodes, которое должно быть быстрее, чем загрузка объектов Person из базы данных.Это вряд ли будет рисование (если только ваш Person # toString () не очень медленный), поскольку на экране не будет тысячи узлов.

Я предполагаю, что вы добавляете узлы по одномуодин, вызывающий тысячу событий изменения вместо добавления всех потомков одновременно.Вы должны добавить тысячу дочерних узлов непосредственно к родительскому узлу и затем вызвать DefaultTreeModel # nodeStructureChanged (node) на родительском узле.

Если это все еще медленно, пришло время для SSCCE.Например, нажатие кнопки в моей системе вообще не показывает задержки:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

public class TestJTree {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                final DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
                final DefaultTreeModel model = new DefaultTreeModel(root);
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.getContentPane().add(new JScrollPane(new JTree(model)));
                frame.getContentPane().add(new JButton(
                        new AbstractAction("Add thousand children") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int offset = root.getChildCount() + 1;
                        for (int i = 0; i < 1000; i++) {
                            DefaultMutableTreeNode child = new DefaultMutableTreeNode(
                                    "Person " + (i + offset));
// adding child with event (but isn't much slower really)
//                                model.insertNodeInto(child, root, root.getChildCount());
                            root.add(child);
                        }
                        model.nodeStructureChanged(root);
                    }
                }), BorderLayout.PAGE_END);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
2 голосов
/ 01 ноября 2011

Вы, вероятно, создаете 1000+ DefaultMutableTreeNodes, чтобы поместить свой список. Проблема заключается в том, чтобы быстро создать такое количество объектов и преобразовать ваши объекты в DefaultMutableTreeNode. Если вы не создадите все эти объекты, вы можете улучшить свою производительность. Я бы предложил написать свою собственную реализацию TreeModel, которая работает непосредственно с вашей объектной моделью, чтобы вам не приходилось заново создавать столько объектов заново. Это должно значительно улучшить вашу скорость. Я поместил 10 000 объектов в JTree раньше (я сделал это, но, возможно, это была не очень хорошая идея), но мне пришлось написать свой собственный TreeModel, чтобы мне не пришлось воссоздавать эти объекты.

Однако, как и в случае всех проблем с производительностью, вы должны сначала профилировать их, чтобы выяснить, на что вы тратите время, и решить эту проблему. Если выясняется, что это проблема, вы можете это сделать. Вам не нужно пытаться создавать свои собственные графические процедуры рисования, потому что это значительно больше работы, чем написание собственной TreeModel.

Другим вариантом является выбор дерева по требованию. Так что извлекайте корень тогда, когда пользователь расширяет каждый узел, выбирайте его дочерние элементы с сервера. Пользователь не может просматривать все 1000+ узлов одновременно, так что это значительно сократит объем передаваемых данных по сети и сократит время, затрачиваемое на сервер.

0 голосов
/ 01 ноября 2011

Напишите ваше собственное JTree, используя JPanel для графики: P.

Или вы можете создать класс, расширяющий JTree, и переопределить метод paint(Graphics g)

...