I have a ContentProvider for a TreeSelectionDialog. I need to implement the getParent method in order to select the root of a tree if one of its nodes is checked. This is the code:
#SuppressWarnings("unchecked")
protected Node<T> getAdapter(Object element) {
if(element instanceof Tree)
return ((Tree<T>)element).getRootElement();
else
return (Node<T>)element;
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// TODO Auto-generated method stub
}
#Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
#Override
public Object[] getChildren(Object parentElement) {
if(parentElement instanceof org.db.normalization.Table) {
if(((org.db.normalization.Table)parentElement).getStatus() == Status.DELETED)
return new Object[0];
List<org.db.normalization.Attribute> atts = new ArrayList<org.db.normalization.Attribute>();
for(Attribute a:((org.db.normalization.Table)parentElement).getAttributes().getAttributes())
if(a.getStatus() != Status.UNMODIFIED)
atts.add(a);
for(Attribute a:((org.db.normalization.Table)parentElement).getPrimaryKey().getAttributes())
if(a.getStatus() != Status.UNMODIFIED)
atts.add(a);
return atts.toArray();
} else if (parentElement instanceof org.db.normalization.Attribute) {
return new Object[0];
} else {
#SuppressWarnings("unchecked")
List<org.db.normalization.Table> n = (ArrayList<org.db.normalization.Table>)parentElement;
if (n.size() > 0) {
return n.toArray() ;
}
}
return new Object[0];
}
#Override
public Object getParent(Object element) {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean hasChildren(Object element) {
// TODO Auto-generated method stub
return getChildren(element).length > 0;
}
I really have no idea of what to write in the getParent method, since I have no other information than the element received as a parameter, and this element alone, doesn't know its parent.
Thanks!
Most instances of a tree implementation, you do know your parent, so parents are either set by a setter method or on the constructor. You have no idea who the parent is, so you are presenting the worse case, where you basically have to get all node, and check rather the children of each node contain you.
Related
So i am building a library as project that covers not all but most of the data structures and i found myself with this problem:
package structure.tree;
import structure.Structure;
import structure.node.BinaryNodeKeyValue;
public class AVLTree<Comparable,V> extends Tree<BinaryNodeKeyValue<Comparable,V>> {
private static final long serialVersionUID = 5046115177325966348L;
public AVLTree(){
}
#Override
public int compareTo(Structure<BinaryNodeKeyValue<Comparable,V>> o) {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean containsValue(BinaryNodeKeyValue<Comparable,V> elem) {
return containsValueAux(((BinaryNodeKeyValue<Comparable,V>) super.getValue()), elem);
}
private boolean containsValueAux(BinaryNodeKeyValue<Comparable,V> root, BinaryNodeKeyValue<Comparable,V> elem){
if(root == null) return false;
else {
if(root.equals(elem)) return true;
else return containsValueAux(root.getLeft(), elem) || containsValueAux(root.getRight(), elem);
}
}
public boolean containsKey(Comparable key){
return containsKeyAux(((BinaryNodeKeyValue<Comparable,V>) super.getValue()), key);
}
private boolean containsKeyAux(BinaryNodeKeyValue<Comparable,V> root, Comparable key){
if(root == null) return false;
else {
if(root.getKey().compareTo(key) > 0) return containsKeyAux(root.getRight(), key);
else if(root.getKey().compareTo(key) < 0) return containsKeyAux(root.getLeft(), key);
else return true;
}
}
#Override
public void deleteValue(BinaryNodeKeyValue<Comparable,V> elem) {
// TODO Auto-generated method stub
}
#Override
public void insertValue(BinaryNodeKeyValue<Comparable,V> elem) {
// TODO Auto-generated method stub
}
#Override
public BinaryNodeKeyValue<Comparable,V>[] toArray() {
// TODO Auto-generated method stub
return null;
}
public BinaryNodeKeyValue<Comparable,V> get(BinaryNodeKeyValue<Comparable,V> root, Comparable key){
return getAux(root, key);
}
private BinaryNodeKeyValue<Comparable, V> getAux(BinaryNodeKeyValue<Comparable, V> root, Comparable key) {
return null;
}
}
At rows 40 and 41 (rows 3 and 4 of method containsKeyAux) it says "The method compareTo(Comparable) is undefined for the type Comparable" and this blows my mind cause the method compareTo is actually defined inside Comparable interface only.
VS Code is also showing me a warning at row 6 that says "The type parameter Comparable is hiding the type Comparable" but i am trying to make the Comparable type as generic as possible cause the key of nodes could be a String, Integer, or a different type of Object.
When you declare a generic like this AVLTree<Comparable,V> you have created a class with two generic types Comparable and V and Comparable has nothing to do with the interface Comparable, they just happen to have the same name.
You probably meant
class AVLTree<T extends Comparable, V>
My question just very short."How to use abstract method or example used in this method?"
This method is from org.zkoss.zul.TreeModel
tmtAtasan = new TreeModel<Map<String,Object>>() {
#Override
public void addTreeDataListener(TreeDataListener arg0) {
// TODO Auto-generated method stub
}
#Override
public Map<String, Object> getChild(int[] arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public Map<String, Object> getChild(Map<String, Object> arg0,
int arg1) {
// TODO Auto-generated method stub
return null;
}
#Override
public int getChildCount(Map<String, Object> arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getIndexOfChild(Map<String, Object> arg0,
Map<String, Object> arg1) {
// TODO Auto-generated method stub
return 0;
}
#Override
public int[] getPath(Map<String, Object> arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public Map<String, Object> getRoot() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean isLeaf(Map<String, Object> arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public void removeTreeDataListener(TreeDataListener arg0) {
// TODO Auto-generated method stub
}
};
I am badly stuck into this. Any help would be really appreciateable.
Thanks in advance!
Ok so from what I understand you just want to use a generic TreeModel without needing to redefine specific behaviors.
So let's imagine your model is a list of Employee beans like :
public class Employee {
private String name;
private List<Employee> listSubordinates = new ArrayList<Employee>();
public Employee(String pName) {
name = pName;
}
public void setName(String pName) {
this.name = pName;
}
public String getName() {
return name;
}
public List<Employee> getListSubordinates() {
return listSubordinates;
}
public void setListSubordinates(List<Employee> pListSubordinates) {
this.listSubordinates = pListSubordinates;
}
}
For this example, we'll imagine you have retrieved a list of employee that are sorted by hierarchy already (to simplify the example).
Employee boss1 = new Employee("Boss1");
Employee sub1 = new Employee("Sub1");
boss1.getListSubordinates().add(sub1);
Employee sub2 = new Employee("Sub2");
boss1.getListSubordinates().add(sub2);
Employee boss2 = new Employee("Boss2");
Employee sub3 = new Employee("Sub3");
boss2.getListSubordinates().add(sub3);
List<Employee> listBosses = Arrays.asList(boss1, boss2);
Again this is a simple example with just one level of hierarchy, if you had a variable level of hierarchy the following code would have to be recursive.
// Build the list of the nodes sorted by hierarchy
List<DefaultTreeNode<Employee>> firstLevelNodes = new ArrayList<DefaultTreeNode<Employee>>();
// For each employee of the highest level
for (Employee boss : listBosses) {
// Build the list of its sub employee
List<DefaultTreeNode<Employee>> listSubordinates = new ArrayList<DefaultTreeNode<Employee>>();
for (Employee subordinate : boss.getListSubordinates()) {
listSubordinates.add(new DefaultTreeNode<Employee>(subordinate));
}
// Then build the boss node with its data and its children nodes
DefaultTreeNode<Employee> bossNode = new DefaultTreeNode<Employee>(boss, listSubordinates);
// And add it to the list of first level nodes
firstLevelNodes.add(bossNode);
}
// Build the ROOT, a 'technical' node containing the nodes of the tree.
DefaultTreeNode<Employee> root = new DefaultTreeNode<Employee>(null, firstLevelNodes);
// Create the TreeModel
TreeModel treeModel = new DefaultTreeModel<Employee>(root);
And now you just have to set the TreeModel to your Tree component.
Hope this helps.
I have Created Binary Search Tree by Using a Tree Interface and Recursion (I am aware that using a Node Class I can Implement the same ) providing methods for Adding and Checking if an element is in the Binary Search Tree or not.
The Problem I am facing is in instantiating & displaying the elements of the BST.
Here is my code
Tree Interface:
package bst;
public interface Tree<D extends Comparable>{
public boolean isempty();
public int cardinality();
public boolean member(D elt);
public NonEmptyBst<D> add(D elt);
}
EmptyBst Class:
package bst;
public class EmptyBst<D extends Comparable> implements Tree<D>{
public EmptyBst(){
D data=null;
}
#Override
public boolean isempty() {
// TODO Auto-generated method stub
return true;
}
#Override
public int cardinality() {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean member(D elt) {
// TODO Auto-generated method stub
return false;
}
#Override
public NonEmptyBst<D>add(D elt) {
// TODO Auto-generated method stub
return new NonEmptyBst<D>(elt);
}
}
NonEmptyBst Class
package bst;
public class NonEmptyBst<D extends Comparable> implements Tree<D> {
D data;
D root;
Tree<D> left;
Tree <D>right;
public NonEmptyBst(D elt){
data=elt;
root=elt;
left=new EmptyBst<D>();
right=new EmptyBst<D>();
}
NonEmptyBst(){
D dataThis=this.data;
}
public NonEmptyBst(D elt,Tree<D>leftTree,Tree<D>rightTree){
data=elt;
left=leftTree;
right=rightTree;
}
#Override
public boolean isempty() {
// TODO Auto-generated method stub
return false;
}
#Override
public int cardinality() {
// TODO Auto-generated method stub
return 1+left.cardinality()+right.cardinality();
}
public boolean member(D elt) {
if (data == elt) {
return true;
} else {
if (elt.compareTo(data) < 0) {
return left.member(elt);
} else {
return right.member(elt);
}
}
}
public NonEmptyBst<D> add(D elt) {
if (data == elt) {
return this;
} else {
if (elt.compareTo(data) < 0) {
return new NonEmptyBst(data, left.add(elt), right);
} else {
return new NonEmptyBst(data, left, right.add(elt));
}
}
}
}
BinarySearchTree Class
package bst;
import bst.Tree;
import bst.EmptyBst;
import bst.NonEmptyBst;
public class BinarySearchTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
NonEmptyBst abcd=new NonEmptyBst( "abc");
NonEmptyBst ab=new NonEmptyBst(67);
abcd.add("cry me a river");
abcd.add("geeehfvmfvf");
abcd.add("I'm Sexy and i know it");
abcd.add("zzzzsd");
abcd.add("zzzzsd");
abcd.add("zzzfdsf");
abcd.add("zzfedfrsd");
abcd.add("tgrgdzsd");
abcd.add("gtrgrtgtrgtrzzzzsd");
abcd.add("zzzzsd");
abcd.add("zdddzzzsd");
abcd.add("zzzzsd");
abcd.add("zzzzsd");
}
}
**
How Can I access the data at all nodes and then Print Them out?The Particular Problem I am facing is In Getting an exception namely ClassCastException when I access the "leaf Nodes" and even if I Initalize new NonEmptyBst<D>in My NonEmptyBst<D>(D elt) constructor I end Up having a null pointer Exception
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.compareTo(Unknown Source)
at java.lang.String.compareTo(Unknown Source)
at bst.NonEmptyBst.add(NonEmptyBst.java:51)
at bst.NonEmptyBst.add(NonEmptyBst.java:54)
at bst.BinarySearchTree.main(BinarySearchTree.java:11)
I'm not really sure I see the need for EmptyBst unless you are trying to follow the design-pattern for a Null Object.
Specifically, an "empty" tree can easily be checked if data == null && left == null && right == null. Also, no need for data here, since it is a local variable and never referenced.
public EmptyBst(){
D data=null;
}
And is there a difference between D data and D root?
I think you need to adjust your add method to capture the result of the recursion.
public NonEmptyBst<D> add(D elt) {
if (data == elt) {
return this;
} else {
if (elt.compareTo(data) < 0) {
this.left = this.left.add(elt);
} else {
this.right = this.right.add(elt);
}
}
return this;
}
You need to access it recursively. As I don't have your node implementation I'll write a general example:
// Return a list with all the nodes
public List<Node> preOrder() {
List<Node> l = new ArrayList<Node>();
l.add(this.value); // Add the data of the root
if(this.left != null) // Add elements to the left
l.addAll(this.left.preOrder());
if(this.right != null) // Add elements to the right
l.addAll(this.right.preOrder());
return l;
}
Then you would simply call it:
List<Node> nodes = myTree.preOrder();
And then loop through the list to do whatever you want.
In my project I have a TableViewer which has a model, a content provider and a label provider.
Once I update my model I call tableviewer.refresh(true) and according to the documentation here:
TableViewer Methods
I'm expecting my selections to be preserved.
Unfortunately this doesn't happen. Does anybody know a solution for that?
Is it something that I miss in here or is it a bug?
EDIT:
This is my model class(counter is for testing purposes to be sure that I have the same list returned after the first refresh):
public class ItemWorkgroup {
List<Item> currentItems = new ArrayList<Item>();
static int counter = 0;
public ItemWorkgroup()
{
}
public void add(Item item)
{
currentItems.add(item);
}
public Object[] getItems()
{
return currentItems.toArray();
}
public void addList(List<Item> newItemsList)
{
System.out.println("Current items first 1: "+currentItems);
if(counter == 0)
{
currentItems = newItemsList;
counter++;
}
System.out.println("Current items first 2: "+currentItems);
}
public List<Item> getItemList()
{
return currentItems;
}
}
This is the content provider class:
public class ContentProvider implements IStructuredContentProvider{
private Mediator mediator;
private ItemWorkgroup model;
public ContentProvider(Mediator mediator, ItemWorkgroup model) {
// TODO Auto-generated constructor stub
this.mediator = mediator;
this.model = model;
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// TODO Auto-generated method stub
System.out.println("Input changed");
}
#Override
public Object[] getElements(Object inputElement) {
// TODO Auto-generated method stub
System.out.println("Getting elements");
if(inputElement instanceof ItemWorkgroup)
{
return ((ItemWorkgroup) inputElement).getItems();
}
else
return new Object[0];
}
public ItemWorkgroup getItems()
{
//Items is a list of items that I'm getting from somewhere
model.addList(items);
return model;
}
The viewer tries to maintain the selection but if your content provider returns different objects for the elements that were selected after the refresh then the tree viewer will not be able to restore the selection.
Your content provider must return the same object for things which have not changed for the selection to be preserved. (Or you can return an object where the equals and hashCode methods make it appear the same).
I am implementing TreeModel interface and have implemented all methods except for the valueForPathChanged.
In my case, the values are not going to be programatically changed.
Why TreeModel interface contains this method? Is it used by JTree in any circumstances, or I am safe to leave it unimplemented?
Code for the reference, it works. I am just concerned whether valueForPathChanged is required by the JTree:
class ParamsTreeModel implements TreeModel {
private final TreeRoot root;
private final List<TreeModelListener> listeners = new ArrayList<TreeModelListener>();
ParamsTreeModel(TreeRoot root) {
this.root = root;
}
#Override
public void addTreeModelListener(TreeModelListener l) {
listeners.add(l);
}
#Override
public Object getChild(Object parent, int index) {
if(parent instanceof Param) return null;
if(structuredMap.containsKey(parent)) {
return structuredMap.get(parent).get(index);
}
// Root
return partNames.get(index);
}
#Override
public int getChildCount(Object parent) {
if(parent instanceof Param) return 0;
if(parent instanceof TreeRoot) return partNames.size();
return structuredMap.get(parent).size();
}
#Override
public int getIndexOfChild(Object parent, Object child) {
if(parent instanceof TreeRoot) return partNames.indexOf(child);
return structuredMap.get(parent).indexOf(child);
}
#Override
public Object getRoot() {
return root;
}
#Override
public boolean isLeaf(Object node) {
return (node instanceof Param);
}
#Override
public void removeTreeModelListener(TreeModelListener l) {
listeners.remove(l);
}
#Override
public void valueForPathChanged(TreePath path, Object newValue) {
// TODO Auto-generated method stub
}
}
While you are required to implement the valueForPathChanged() method, as defined in the TreeModel interface, you are free to leave it empty. FileTreeModel, cited here, is an example. The valueForPathChanged() method is typically used to support cell editing. As a concrete example, the implementation in DefaultTreeModel, seen here, "sets the user object of the TreeNode identified by path and posts a node changed [event]."