2017-01-10 10 views
0

Я работаю с JTree Java swing и должен найти соответствующий индекс строки выбранного узла в своем пути. Например, когда я выбираю Polygon 2 в рисунке,Получение правильной позиции строки узлов JTree

enter image description here

-И использовать этот кусок кода,

tree.getRowForPath(/*path of polygon node*/); 

-I получить значение 2, что является правильным. Однако, когда я выбираю Polygon 3, я получаю значение 6. Это происходит потому, что он принимает узлы, которые Polygon 2 расширяется в счет при поиске соответствующего узла. Я не хочу этого, так как мне нужно вернуть значение 3, когда выбрано Polygon 3, независимо от того, были ли они расширены или нет.

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

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

Любая помощь приветствуется.

+0

Я думаю, вопрос в том, почему? Чего вы пытаетесь достичь, в результате чего вы получаете «3»? Из звуков вещей вы можете получить узел без проблем, зачем вам значение строки? Если вы используете что-то вроде 'DefaultMutableTreeNode', вы можете предоставить' userObject', который может содержать дополнительную информацию, которая может помочь вам достичь вашей цели. – MadProgrammer

+0

@MadProgrammer. В этом JTree есть узлы, которые изменяются, если пользователь добавляет или удаляет многоугольник. У меня есть отдельный ArrayList, который содержит многоугольники, и, основываясь на этом, этот JTree обновляет свой список, если что-то меняется. Если я хочу выбрать многоугольник в JTree, мне нужно знать строку, чтобы я мог подключиться к ArrayList и изменить все, что захочу, для этого многоугольника. Я думаю, было бы проще, если бы у меня был алгоритм, который рассчитал это, а не расширение 'DefaultMutableTreeNode'. Я могу ошибаться. – Eric

+0

Мое предпочтительное решение состояло в том, чтобы 'DefaultMutableTreeNode' управлял' Polygon' или имел некоторую ссылку на модель, которую он может обновить, но это я: P ...в основном, вы хотите свести к минимуму количество сцепления между «JTree» и существующей моделью – MadProgrammer

ответ

1

В заключение я решил написать решение, основанное на предложении @ MadProgrammer. Я создал класс узла дерева следующим образом:

public class CustomTreeNode extends DefaultMutableTreeNode { 

    private int position; 

    public CustomTreeNode(String text, int position){ 
     super(text); 
     this.position = position; 
    } 

    public int getPosition(){ 
     return this.position; 
    } 

} 

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

Я инициализируются объекты как так (это было в цикле):

//root node 
CustomTreeNode polygon = new CustomTreeNode("Polygon " + (i+1), i); 

Я использовал узлы, как это:

@Override 
public void valueChanged(TreeSelectionEvent e) { 

    TreePath[] selectedPaths = tree.getSelectionPaths(); 
    TreePath parentPath = tree.getClosestPathForLocation(1, 1); 

    if (selectedPaths == null) 
     return; 

    ArrayList<Integer> validRows = new ArrayList<>(); 

    for (TreePath tp : selectedPaths){ 

     if (tp.getParentPath() != parentPath) 
      continue; 

     //get node that current selected path points too, then get the custom index of that 
     CustomTreeNode selectedNode = (CustomTreeNode) tp.getLastPathComponent(); 

     System.out.println(selectedNode.getPosition()); 

     validRows.add(selectedNode.getPosition()); 

} 

Обратите внимание, как я легко смог населить ArrayList validRows без повторения каждого узла и устранения расширенных.

1

Вот пример того, что вы хотите (если я правильно понимаю ваш вопрос), но решение @MadProgrammer является предпочтительным способом.

public static int indexInParentForPath(JTree aTree, TreePath path) { 
    Object p = null; 
    Object parent = null; 
    for (int i = 0; i < path.getPathCount(); i++) { 
     if (path.getPathComponent(i).toString().contains("Polygon")) { 
      p = path.getPathComponent(i); 
      parent = i > 0 ? path.getPathComponent(i - 1) : null; 
      break; 
     } 
    } 
    if (p != null) { 
     return parent == null ? 0 : aTree.getModel().getIndexOfChild(parent, p); 
    } 
    return -1; 
}