2016-06-23 5 views
0

Я тестирую код с JTree, и я заметил, что model.reload() дает отличный результат, чем model.nodeChanged(currentNode). Правильный выход получается от model.reload(). Вот мои два выхода для того же кода:JTree model.nodechanged (Node) теряет данные

enter image description here

Мой код выглядит следующим образом:

public class test { 

    private JFrame frame; 
    JTree tree; 
    DefaultMutableTreeNode root; 
    DefaultTreeModel model; 
    private Map<String, DefaultMutableTreeNode> treeMap; 

    public static void main(String[] args) { 
     test t = new test(); 
     try { 
      Thread.sleep(1000 * 5); 
     } catch (Exception e) { 

     } 
     t.add_new_folder("Data", "trial 0"); 
     t.add_new_folder("Data/trial 0", "trial 1"); 
     t.add_new_folder("Data/trial 0/trial 1", "trial 2"); 
     t.add_new_folder("Data", "trial 1"); 

     try { 
      Thread.sleep(1000 * 5); 
     } catch (Exception e) { 

     } 
     t.add_new_folder("Data/trial 1", "trial 2"); 
     t.add_new_folder("Data", "trial 2"); 
    } 

    public test() { 
     frame = new JFrame("using reload"); 
     tree = new JTree(); 
     root = new DefaultMutableTreeNode("Data"); 
     model = new DefaultTreeModel(root); 
     tree.setModel(model); 
     frame.getContentPane().add(tree, BorderLayout.WEST); 
     frame.setVisible(true); 
     frame.setSize(500, 500); 
     treeMap = new HashMap<>(); 
     treeMap.put("Data", root); 
    } 

    public void add_new_folder(String path, String name) { 
     DefaultMutableTreeNode currentNode = treeMap.get(path); 
     DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(name); 
     currentNode.add(childNode); 
     treeMap.put(path + "/" + name, childNode); 
     model.reload(); 
     //model.nodeChanged(currentNode); 
    } 
} 

мне нужно также использовать model.nodeChanged(), как он держит путь расширяется и то же в отличие от model.reload. Любое объяснение и как исправить?

+1

Используйте логическую и последовательную форму отступов строк кода и блоков. Отступы предназначены для того, чтобы поток кода стал проще следовать! В IDE обычно есть [ярлык для кода форматирования] (https://www.google.com.au/?ion=1&espv=2#q=eclipse%20format%20code). –

+0

Я сделал автоматический формат, но не помог –

+1

Ну, удачи в этом. Жизнь слишком коротка, чтобы иметь дело с неуправляемым кодом. –

ответ

2

Любая идея, почему эта проблема стоит перед мной с помощью Tree?

Как показано ниже, когда правильно synchronized, результаты такие же. Как показано here, вы можете управлять видимостью с помощью expandRow() и scrollPathToVisible(). Использование Thread.sleep() будет просто блокировать поток, на который он вызывается. Поскольку Swing single-threaded, результаты непредсказуемы. Вместо этого используйте java.swing.Timer или SwingWorker при необходимости.

Попробуйте поспать между добавлением узлов и расширением любого пути, а в коде продолжения появится проблема, указанная в моем вопросе.

По причинам mentioned, результаты с использованием Thread.sleep() не являются надежными. Использование java.swing.Timer показывает проблему: nodeChanged() отражает изменения самого узла. Поскольку вы изменили дочерние узлы узла, вместо этого вызовите nodeStructureChanged().

image

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.HashMap; 
import java.util.Map; 
import javax.swing.JFrame; 
import javax.swing.JTree; 
import javax.swing.Timer; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 

public class Test { 

    private final JFrame frame; 
    private final JTree tree; 
    private final DefaultMutableTreeNode root; 
    private final DefaultTreeModel model; 
    private final Map<String, DefaultMutableTreeNode> treeMap; 
    private final boolean reload; 
    private int index; 
    private final String[] folders = { 
     "Data", "trial 0", 
     "Data/trial 0", "trial 1", 
     "Data/trial 0/trial 1", "trial 2", 
     "Data", "trial 1", 
     "Data/trial 1", "trial 2", 
     "Data", "trial 2" 
    }; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> { 
      new Test(true); 
      new Test(false); 
     }); 
    } 

    public Test(boolean reload) { 
     this.reload = reload; 
     frame = new JFrame(String.valueOf(reload)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     treeMap = new HashMap<>(); 
     root = new DefaultMutableTreeNode("Data"); 
     model = new DefaultTreeModel(root); 
     tree = new JTree(model); 
     treeMap.put("Data", root); 
     frame.add(tree, BorderLayout.WEST); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
     Timer t = new Timer(100, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (index < folders.length) { 
        addNewFolder(folders[index++], folders[index++]); 
        for (int i = 0; i < tree.getRowCount(); i++) { 
         tree.expandRow(i); 
        } 
        frame.pack(); 
       } 
      } 
     }); 
     t.start(); 
    } 

    private void addNewFolder(String path, String name) { 
     DefaultMutableTreeNode currentNode = treeMap.get(path); 
     DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(name); 
     currentNode.add(childNode); 
     treeMap.put(path + "/" + name, childNode); 
     if (reload) { 
      model.reload(); 
     } else { 
      model.nodeStructureChanged(currentNode); 
     } 
    } 
} 
+0

У меня такие же результаты, когда все это делается без возможности расширения любого пути. Чтобы быть более конкретным, я получил эту разницу, когда я расширяю любой путь, пока поток во сне. –

+0

попробуйте поспать между добавлением узлов и расширением любого пути, а в коде продолжения появится проблема, указанная в моем вопросе –

+0

. Я подробно рассмотрел выше. – trashgod

Смежные вопросы