# Schwierig: TreeNode und TreePath



## LarsKo (14. Sep 2006)

folgendes möchte ich erreichen. 
mit den folgenden Fragmenten hampel ich nun schon einige Zeit herum und probiere dies an dem aus, wenn man einen new JTree() ohne irgendetwas erzeugt. Gut wir sehen ein paar Speisen und Farben und ich will nun, dass bei der aktuellen Selektion nicht das zuletzt selektierte Element auf der Konsole ausgegeben wird, sondern das vorletzte, egal ob Blatt oder Knoten!
Wenn ich also bananas anklicke, soll ravioli ausgegeben werden, wenn ich hot dogs anklicke, soll food ausgegeben werden. wie um himmels willen kriege ich das hin.??

```
TreePath path = tree.getSelectionPath();
System.out.println(path.getLastPathComponent());
TreeNode node = ((TreeNode)path.getLastPathComponent()).getParent();		
//hmmmm			
System.out.println(node);
```


```
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;


public class JTreeTest extends JFrame  {
	JPopupMenu pop;	
	JTree tree;
	TreePath clickedPath;

	public JTreeTest()	{

	 super("JTreeSelectionTest");	 
	 JPanel firstPanel = new JPanel();	      
	 tree = new JTree();		
	 tree.addMouseListener(new PopupTrigger());
	 firstPanel.add(tree);
		
	 getContentPane().add(firstPanel, BorderLayout.CENTER);
	 pack();		
	 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	 setVisible(true);
		
	}
	
	class PopupTrigger extends MouseAdapter 	{
		public void mouseReleased(MouseEvent e)		{
			
			TreePath path = tree.getSelectionPath();
			System.out.println(path.getLastPathComponent());
			TreeNode node = ((TreeNode)path.getLastPathComponent()).getParent();		
			
			//System.out.println(node);
		}
	}
	
	
	public static void main(String[] args) 	{		
		JTreeTest test = new JTreeTest();
	}
}
```


----------



## André Uhres (15. Sep 2006)

```
class PopupTrigger extends MouseAdapter    {
        public void mouseReleased(MouseEvent e)      {
            TreeNode node = getUpperNode( (TreeNode) tree.getLastSelectedPathComponent() );
            if(node != null){
                System.out.println(node);
            }
        }
    }
    private TreeNode getUpperNode(TreeNode node){
        TreeNode upperNode = null;
        try {
            TreeNode parent = node.getParent();
            int childIndex = parent.getIndex(node);
            if(childIndex == 0) {
                upperNode = parent;
            }else{
                upperNode = parent.getChildAt(childIndex-1);
            }
        } catch (NullPointerException e) {}
        return upperNode;
    }
```


----------



## AlArenal (15. Sep 2006)

Mehrere returns sind aber auch Bad Style


----------



## André Uhres (15. Sep 2006)

AlArenal hat gesagt.:
			
		

> Mehrere returns sind aber auch Bad Style


Ist jetzt restyled.


----------



## LarsKo (15. Sep 2006)

ähhm , andre uhres ich hätte gerne privatunterricht. danke  .
wenn ich jetzt noch wüßte wie man den selectionpath auf diesen vorgänger setzt wäre ich wieder glücklich.


----------



## Leroy42 (15. Sep 2006)

AlArenal hat gesagt.:
			
		

> Mehrere returns sind aber auch Bad Style



Ist das eigentlich so?  :shock: 

Ich bemühe mich auch immer eine _Ein-Ausgang_-Methode zu schreiben;
dennoch nervt mich der u.U. nötige zusätzliche Code (boolean-Variablen, ...)


----------



## AlArenal (15. Sep 2006)

Emfpinde ich schon so, da man bei späteren Änderungen leicht mal ein return mittendrin überfährt und am Ende wundert man sich, warum da nicht rauskommt, was rauskommen soll. Im Debugger kann man auch nur schwer Variablen beobachten, die man gar nicht hat...


----------



## Illuvatar (15. Sep 2006)

Ich finde, _es kommt darauf an_ (wie immer eben) 

Sicherlich stimmt das, was AlArenal sagt, aber in gewisser Weise find ich ein return oftmals "logischer".
Ganz einfaches Beispiel:

```
public Foo getFoo(Bar bar)
{
  if (bar instanceof Foo){
    return bar;
  }
  Foobar x = //calculate something 
  return x;
}
```

Das könnte natürlich noch viel komplexer werden, außerdem kann das Nicht-return-verwenden auch manchmal zu tief verschachtelten ifs führen (und deshalb dann 20 Methoden zu extrahieren ist vielleicht auch nicht immer sinnvoll...)


----------



## André Uhres (15. Sep 2006)

LarsKo hat gesagt.:
			
		

> ..wie man den selectionpath auf diesen vorgänger setzt ..




```
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
                TreeNode[] nodes = model.getPathToRoot(node);
                if( nodes != null ){
                    tree.setSelectionPath(new TreePath(nodes));
                }
```


----------

