Алгоритм преобразования дерева каталогов (файл .txt) в JTree

Я делаю программу, которая будет генерировать текстовый файл, содержащий дерево каталогов. Я выполнил часть обхода файлов, поэтому у меня готов текстовый файл. Затем я хочу использовать этот текстовый файл, прочитать его и преобразовать данные в JTree. Я застрял с алгоритмом в течение 2 дней!! У кого-нибудь есть предложения? плиз помогите.

* обратите внимание, что я использовал "\t" для интервала.

Некоторая часть моего path.txt

путь.txt

Arcana Advanced
        ABC
        ABC
        AcnMiniGame
        client
        Data
        error
        patch
        patch_03451
        patch_03452
        patch_03453
        patch_03454
        patch_03455
        patch_03456
        patch_03458
        SaveDeck
                ModifiedDeck1 Earth Water
                ModifiedDeck2 Wind Fire
                ModifiedDeck3 Wind Earth
                ModifiedDeck4 Earth Fire
                ModifiedDeck5 Wind Water
                ModifiedDeck6 Fire Water
                Starter1 Earth Water
                Starter2 Fire Wind
                Starter3 Earth Wind
                Starter4 Earth Fire
                Starter5 Water Wind
                Starter6 Water Fire
        Tutorial
        unicows
        unins000
        unins000
ASActiveX
        Au_activeX
                ThaiGameStart
        nProtect
                npkcx
                        npkagt
                        npkcrypt
                        npkcrypt
                        npkcrypt
                        npkcsvc
                        npkcusb
                        npkcx
                        npkcx
                        npkpdb
                        npkuninst

Это то, что я пробовал до сих пор:

public final class FileTree extends JPanel {


JTree tree;
DefaultMutableTreeNode root;
Path path;
List<String> lines;

public FileTree(String filepath) {
    try {
        root = new DefaultMutableTreeNode("root", true);
        this.path = Paths.get(filepath);
        lines = Files.readAllLines(path);
        getList(root, 0);
        setLayout(new BorderLayout());
        tree = new JTree(root);
        tree.setRootVisible(false);
        add(new JScrollPane((JTree) tree), "Center");
    } catch (IOException ex) {
        Logger.getLogger(FileTree.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public int getTab(int line) {
    String text = lines.get(line);
    return text.lastIndexOf("\t");

}

public boolean noChild(int line) {
    if (getTab(line) < getTab(line + 1)) {
        return false;
    }
    return true;

}

public int getLastLine(int line) {
    int myTab = getTab(line);
    int myLine = line+1;
    int i = line+1;
    while (true) {
        if (myTab == getTab(myLine)) {
            return i;
        } else {
            myLine++;
            i++;
        }
    }
}

public int getChildList(int line) {
    int i = 0;
    int ChildTab = getTab(line + 1);
    int myLine = line + 1;
    while (true) {
        if (ChildTab == getTab(myLine)) {
            myLine++;
            i++;
        } else if (ChildTab < getTab(myLine)) {
            myLine++;
        } else if (ChildTab > getTab(myLine)) {
            return i;
        }
    }
}



public void getList(DefaultMutableTreeNode node, int line) {
    try {
        if (noChild(line)) {
            System.out.println("FILE  -  " + lines.get(line));
            DefaultMutableTreeNode child = new DefaultMutableTreeNode(lines.get(line).trim());
            node.add(child);
        } else {
            System.out.println("DIRECTORY  -  " + lines.get(line));
            DefaultMutableTreeNode child = new DefaultMutableTreeNode(lines.get(line).trim());
            node.add(child);
            int ChildList = getChildList(line);
            for (int i = 0; i < ChildList; i++) {
                getList(child, line + i + 1);
            }

        }
    } catch (Exception e) {
    }

}

}

результат: http://www.uppic.org/image-5E7B_55C470B7.jpg

Моя проблема с кодом, похоже, заключается в том, что после того, как он закончил изучение папки, фактическая строка не знает об этом и продолжает читать следующую строку, которая является файлом в исследуемой папке. (Это сложно объяснить словами, извините за мой плохой английский)

И вторая проблема заключается в том, что она не читает все основные папки, как вы можете видеть на картинке, программа перестает работать после изучения папки «Arcana Advanced». Я понимаю причину этой проблемы, поэтому я попытался использовать другой метод, чтобы проверить, сколько у них основных папок, и выполнить цикл for. Но это очень грязно и отнимает много времени, у кого-нибудь есть более простой способ сделать это?


person Kongpon Charanwattanakit    schedule 07.08.2015    source источник
comment
Я предлагаю опубликовать код, который у вас есть с конкретной проблемой.   -  person StanislavL    schedule 07.08.2015


Ответы (3)


Это было мое решение: (Обратите внимание, когда я копировал и вставлял ваш файл, я получил 8 пробелов, заменяющих каждую вкладку.)

    public void LoadTree(String filename, JTree tree) {

        try (BufferedReader br = Files.newBufferedReader(Paths.get(filename))) {
            int last_tab_length = -1;
            String line;
            DefaultMutableTreeNode parentNode = new DefaultMutableTreeNode("root");
            DefaultMutableTreeNode lastNode = parentNode;
            DefaultTreeModel model = new DefaultTreeModel(parentNode);
            tree.setModel(model);
            while ((line = br.readLine()) != null) {
                int tab_length = 0;
                while (line.startsWith("\t")) {
                    tab_length++;
                    line = line.substring(1);
                }
                String eightSpaces = "        ";
                while (line.startsWith(eightSpaces)) {
                    tab_length++;
                    line = line.substring(eightSpaces.length());
                }
                DefaultMutableTreeNode node = new DefaultMutableTreeNode(line.trim() + ":" + tab_length);

                if (tab_length > last_tab_length) {
                    parentNode = lastNode;
                }
                for (int i = last_tab_length; i > tab_length; i--) {
                    parentNode = (DefaultMutableTreeNode) parentNode.getParent();
                }
                parentNode.add(node);
                last_tab_length = tab_length;
                lastNode = node;
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
person WillShackleford    schedule 07.08.2015
comment
Благодарю вас! У меня есть некоторые идеи из вашего кода, и я пытаюсь изменить его по-своему! - person Kongpon Charanwattanakit; 07.08.2015

Я не могу написать правильный код Java прямо сейчас, но вот некоторый псевдокод, который должен работать:

File f = new File () ;
Stack s = new Stack () ;
Node r = new Root () ;
int nTabs = 0 ; // Current number of tabs
while (f) { // while there are remaining lines in f
    String line = f.readLine () ;
    int n = countTabs (line) ;
    if (nTabs == n) {
        r.addChild (new Node(line)) ;
    }
    else if (nTabs == n + 1) {
        Node node = new Node(line) ;
        r.addChild (node) ;
        s.push(r) ;
        r = node ;
        nTabs = nTabs + 1 ;
    }
    else {
        while (n < nTabs) {
            nTabs = nTabs - 1;
            r = s.pop () ;
        }
    }
}
person Holt    schedule 07.08.2015
comment
Я не совсем привык к классу Stack и не хочу с ним связываться. кстати, спасибо! - person Kongpon Charanwattanakit; 07.08.2015
comment
@KongponCharanwattanakit В основном это та же идея, что и у WillShackleford, я просто использую Stack для хранения родительских узлов текущего узла. Если вы можете подняться в своем дереве (используя getParent), то вам не нужен стек, как показано в сообщении WillShackleford. - person Holt; 07.08.2015

Наконец-то я получил решение своего вопроса.

public final class FileTree extends JPanel {

JTree tree;
DefaultMutableTreeNode root;
Path path;
List<String> lines;

public FileTree(String filepath) {
    try {
        root = new DefaultMutableTreeNode("root", true);
        this.path = Paths.get(filepath);
        lines = Files.readAllLines(path);
        getList(root, 0);
        setLayout(new BorderLayout());
        tree = new JTree(root);
        tree.setRootVisible(false);
        add(new JScrollPane((JTree) tree), "Center");
    } catch (IOException ex) {
        Logger.getLogger(FileTree.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public int getTab(int line) {
    String text = lines.get(line);
    return text.lastIndexOf("\t");

}

public boolean noChild(int line) {
    if (getTab(line) < getTab(line + 1)) {
        return false;
    }
    return true;

}


public TreeNode getNewNode(int line, int line2, DefaultMutableTreeNode node) {
    TreeNode treenode = node;
    int time = getTab(line) - getTab(line2);
    for (int i = 0; i < time; i++) {
        treenode = treenode.getParent();
    }
    return treenode;

}

public void getList(DefaultMutableTreeNode node, int line) {
    DefaultMutableTreeNode child = new DefaultMutableTreeNode(lines.get(line).trim());
    node.add(child);
    if (line + 1 > lines.size() - 1) {
        System.out.println("Finished");
        return;
    }
    if (!noChild(line)) { // have Children
        getList(child, line + 1);
    } else {             // no Children
        if (getTab(line) > getTab(line + 1)) {
            getList((DefaultMutableTreeNode) getNewNode(line, line + 1, node), line + 1);
        } else if (getTab(line) == getTab(line + 1)) {
            getList(node, line + 1);
        }
    }




}

}

person Kongpon Charanwattanakit    schedule 07.08.2015