Display JTree using a single node element having full content - java

I have a single node that has all the child nodes and attributes in the following format.
node = Root[
attributes = {rootattribute1, rootattribute2,...},
value = [100,
childNode1
[
attributes = {childNode2att1,.....}
value = [1001]
]
childNode2
[
attributes = {childNode2attributes,.....}
value = [1001]
] ......... and some other childnodes like this
]
When I use Jtree tree = new Jtree(node); It is creating just a single rootelement for the tree showing all these details within a single row of a tree.
Instead I want to display the tree in the correct hierarchy with nested child nodes and atrribute values. Is there any inbuilt method to do this ?
If there is no inbuilt method to do this how do I write the code for this ?
PS: the node content displayed above is dynamic and is not static.

You can start with something like:
import javax.swing.*
import javax.swing.tree.*
class Root {
def attributes = []
def children = []
def value = 0
def String toString() {
"[${value}] attributes: ${attributes} children: ${children}"
}
}
def createTreeNode(node) {
def top = new DefaultMutableTreeNode(node.value)
for (attr in node.attributes) {
top.add(new DefaultMutableTreeNode(attr))
}
for (child in node.children) {
top.add(createTreeNode(child))
}
top
}
root = new Root(
attributes: ['rootattribute1', 'rootattribute2'],
value: 100,
children: [
new Root(
attributes: ['childNode2att1'],
value: 1001),
new Root(
attributes: ['childNode2attributes'],
value: 1002),
])
frame = new JFrame('Tree Test')
frame.setSize(300, 300)
frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
jtree = new JTree(createTreeNode(root))
frame.add(jtree)
frame.show()
JTree is a sophisticated component - please read the JTree Swing Tutorial for more details on how to customize the tree for your exact needs.

Related

Browsing OPCUA nodes only working on top level

I am using OPC UA project https://github.com/OPCFoundation/UA-Java. I was able to browse all the nodes on an OPCUA Server using UAExpert.
Now I am trying to browse all nodes using my java client. I am able to retrieve references for the nodes in the first level of the node hierarchy where
rootnameSpace = 1 and rootIdentifier = "simsre"
BrowseDescription browse = new BrowseDescription();
browse.setNodeId(new NodeId(rootnameSpace, rootIdentifier));
browse.setBrowseDirection(BrowseDirection.Forward);
browse.setIncludeSubtypes(true);
browse.setNodeClassMask(NodeClass.Object, NodeClass.Variable);
browse.setResultMask(BrowseResultMask.All );
BrowseResponse res = mySession.Browse(null, null, null, browse);
ReferenceDescription[] references = res.getResults()[0].getReferences();
When I call the code for other nodes like rootnameSpace = 31 and rootIdentifier = "/simsrede/" beneath I still get a result but no references ( so res.getResults()[0].getReferences() returns null)
- The status code of the browseResponse is something like "GOOD" -
According to specification all unicode characters are allowed in the identifiers so slashes and '|' shouldn't be the problem.
I also tried adding entries into my namespacetable and using the table to set the node id in consecutive browse requests starting at the root node with
NamespaceTable table = NamespaceTable.getDefaultInstance();
table.add(1, "urn:something:UnifiedAutomation:Uagateway");
...
//consecutive browse request starting from reference returned by first call
browse1.setNodeId(table.toNodeId(references[0].getNodeId()));
BrowseResponse res1 = mySession.Browse(null, null, null, browse);
ReferenceDescription[] references1 = res.getResults()[0].getReferences();
Anybody having an idea on why this is returning null references, or how to debug this ?
I used a Browse function
Byte[] cp;ReferenceDescriptionCollection refs; m_session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out cp, out refs)
and i get if refs collection of the nodes from first level. Foreach node I called Browse function in recursion where I add nodes to the collection of OPCTreeNode
public void GetChildNodes(Session sesja, ReferenceDescription Parametr, OPCTreeNode treeNode)
{
ReferenceDescriptionCollection nodes;
byte[] tmpbytes;
sesja.Browse(null, null, ExpandedNodeId.ToNodeId(Parametr.NodeId, sesja.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out tmpbytes, out nodes);
foreach (var tmpnode in nodes)
{
OPCTreeNode tmpNode = new OPCTreeNode($"{tmpnode.DisplayName}", $"{tmpnode.NodeId}");
treeNode.ChildTreeNodes.Add(tmpNode);
GetChildNodes(sesja, tmpnode, tmpNode);
}
}
OPCTreeNode class
public class OPCTreeNode // element struktury parametrów sesji
{
public string DiplayName { get; set; }
public string NodeId { get; set; }
public List<OPCTreeNode> ChildTreeNodes;
public OPCTreeNode()
{
ChildTreeNodes = new List<OPCTreeNode>();
}
public OPCTreeNode(string displayName, string nodeId)
{
this.DiplayName = displayName;
this.NodeId = nodeId;
ChildTreeNodes = new List<OPCTreeNode>();
}
}

Aggregate document in MongoDB from two CSV files

I am writing a Java program to insert two CSV files into a single document consisting of a subdocument but I do not know how to do it. I'll explain:
I have a SNP file containing the fields rsid, chr, has_sig and a LOCUS file containing the fields rsid, mrna_acc, gene, class, sap_id where in the LOCUS file, for each rsid can correspond more mrna_acc and therefore I will have more rows with same rsid.
I would like a Mongo document this:
{ _id: ObjectId("7264958211f41a0c647c47b1"),
rsid: rs530,
chr: 21,
has_sig: false,
locus: [
{ mrna_acc: NM_00125,
gene: ETS2,
class: utr_variant
},
{ mrna_acc: NM_00126,
gene: ETS2,
class: utr_variant
},
... ]
}
I tried to read the two CSV files with buffereader and insert them in the document like this:
Document d = new Document();
Document d1 = new Document();
FileSnp fs = new FileSnp("/Users/valentinafratini/Documents/Progetto Tesi/FactoryMethodDb/snp.csv");
fs.readFile();
long startTime = System.currentTimeMillis();
while (fs.line!=null) {
fs.line = fs.reader.readLine();
if (fs.line!=null && fs.line.length()>0) {
fs.obj = fs.line.split("\\s+");
fs.readSingleObj();
d.append("rsid", fs.rsid);
d.append("chr", fs.chr);
d.append("has_sig", fs.has_sig);
}
}
FileLocus fl = new FileLocus("/Users/valentinafratini/Documents/Progetto Tesi/FactoryMethodDb/locus.csv");
fl.readFile();
while (fl.line!=null) {
fl.line = fl.reader.readLine();
if (fl.line!=null && fl.line.length()>0) {
fl.obj = fl.line.split("\\s+");
fl.readSingleObj();
d1.append("mrna_acc", fl.mrna_acc);
d1.append("gene", fl.gene);
d1.append("class", fl.classe);
}
}
d.put("locus", d1);
list.add(d);
coll.insertMany(list);
But the result is the insertion of a single line with all the fields of both the snp file and the locus file.
Can you help me? I really do not know how to do it.
Thank you very much.
In your target document structure the locus attribute contains an array of sub documents ...
locus: [
{ mrna_acc: NM_00125,
gene: ETS2,
class: utr_variant
},
{ mrna_acc: NM_00126,
gene: ETS2,
class: utr_variant
}
]
This suggests that the FileLocus reader should produce a Document instance for each line in the locus.csv and that each of these documents should be added to a collection in the outer document: d which is created by the FileSnp reader.
If so, then you should replace the FileLocus block with the following:
// this will contain the collection of documents, one for each line in `locus.csv`
List<Document> locusDocuments = new ArrayList<>();
FileLocus fl = new FileLocus("/Users/valentinafratini/Documents/Progetto Tesi/FactoryMethodDb/locus.csv");
fl.readFile();
while (fl.line!=null) {
fl.line = fl.reader.readLine();
if (fl.line!=null && fl.line.length()>0) {
fl.obj = fl.line.split("\\s+");
fl.readSingleObj();
// create and populate a sub document for the current line
Document locusDocument = new Document();
locusDocument.append("mrna_acc", fl.mrna_acc);
locusDocument.append("gene", fl.gene);
locusDocument.append("class", fl.classe);
// assign the current sub document to the collection of locus documents
locusDocuments.add(locusDocument);
}
}
// add the collection of locus documents to the outer document
d.append("locus", locusDocuments);

Javax JCR Node getProperties and Titles

I am given a Node and I then request form it another Node.
Node nn = node.getNode("jcr:content");
From here I can do the following to get the value of
nn.getProperty("cq:lastModified")
What I am trying to do is get all the properties without asking for each one by name.
Node nn = node.getNode("jcr:content");
PropertyIterator pi = nn.getProperties();
Now I can iterate over the properties and print their values as so:
while(pi.hasNext())
{
Property p = pi.nextProperty();
String val = p.getString();
}
But how can I find the title of this Property?
I am not sure but you can try getName() method because Property interface is subinterface of Item interface. You can try like below :
while(pi.hasNext())
{
Property p = pi.nextProperty();
String name = p.getName();
String val = p.getString();
}

How do I change the "root" directories name in JTree?

I have a simple implementation of JTree:
tree1 = new JTree(LibObj.collectionToStringArray(LibObj.books));
tree1.setRootVisible(true);
scrollPane2 = new JScrollPane(tree1);
scrollPane2.setPreferredSize(new Dimension(350, 300));
panel.add(scrollPane2);
LibObj.collectionToStringArray(LibObj.books) is a method in another class that takes a collection and turns it into an array of strings
Everything is displaying as expected but the root directory is named "Root". How do I change the name? (I want it to be called Books)
Using the constructor JTree(TreeNode node) would give you the chance to create your own root node.
Just like this:
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Root node name");
for( String book : booksArray ) {
DefaultMutableTreeNode bookNode = new DefaultMutableTreeNode(book);
rootNode.add(bookNode);
}
tree1 = new JTree(rootNode);
tree1.setRootVisible(true);
[...]

JSF/ICEfaces Dynamic hierarchy tree example

i have list of departments and each department might have a parent or not,department domain object is as follows:
- departmentId
- parentDepartmentId (null if current department has no parent i,e should be under root directly, and have value if current department have parent).
.
.
.
looking at icefaces tutorial code for creating basic tree:
// create root node with its children expanded
DefaultMutableTreeNode rootTreeNode = new DefaultMutableTreeNode();
IceUserObject rootObject = new IceUserObject(rootTreeNode);
rootObject.setText("Root Node");
rootObject.setExpanded(true);
rootTreeNode.setUserObject(rootObject);
// model is accessed by by the ice:tree component via a getter method, this object is what's needed in the view to display the tree
model = new DefaultTreeModel(rootTreeNode);
// add some child nodes
for (int i = 0; i <3; i++) {
DefaultMutableTreeNode branchNode = new DefaultMutableTreeNode();
IceUserObject branchObject = new IceUserObject(branchNode);
branchObject.setText("node-" + i);
branchNode.setUserObject(branchObject);
rootTreeNode.add(branchNode);
}
it's all about constructing basic node, and adding childs.
my case is complex that child A which is under root may have child nodes B,C,D and D have for example child nodes and so on so on.
so i am thinking of a best practice about how to accomplish something like that, i need a sample code or hints if anyone can help.
You would need a recursive method to construct the tree from your model.
public void buildRecursiveTreeNode(DefaultMutableTreeNode parentTreeNode,
String treeId, String treeName, GenericTreeVo modelVo)
{
// if the database model contains more children.
// add the current nodes first and pass in this nodes tree id and name to construct the children for this parent nodes.
}
Updated answer to include recursion example.
http://www.danzig.us/java_class/recursion.html
just added a recursion link, all I am saying is when you iterate the data from the database, you would see if you have any child records, if you have child records you would call the same method by passing the DefaultMutableTreeNode and that would become the parent.
finally i was able to do it as follows:
List<Department> departmentList = getAllDepartments();
// create root node with its children expanded
DefaultMutableTreeNode rootTreeNode = new DefaultMutableTreeNode();
IceUserObject rootObject = new IceUserObject(rootTreeNode);
rootObject.setText("Root");
rootObject.setExpanded(true);
rootTreeNode.setUserObject(rootObject);
HashMap<Department, DefaultMutableTreeNode> createdNodesMap = new HashMap<Department, DefaultMutableTreeNode>(
0);
for (Department department : departmentList) {
DefaultMutableTreeNode currentNode = null;
if (createdNodesMap.get(department) == null) {
log.debug("############ CREATING NODE "
+ department.getName());
currentNode = new DefaultMutableTreeNode();
IceUserObject currentObject = new IceUserObject(currentNode);
currentObject.setText(department.getName());
currentObject.setExpanded(true);
currentNode.setUserObject(currentObject);
if (department.getParentDepartment() == null) {
rootTreeNode.add(currentNode);
log.debug("######### NODE " + department.getName()
+ " ADDED UNDER ROOT");
}
createdNodesMap.put(department, currentNode);
} else {
log.debug("############ GETTING CREATED NODE "
+ department.getName());
currentNode = createdNodesMap.get(department);
}
if (department.getChildren().size() > 0)
log.debug("############ NODE " + department.getName()
+ " HAVE " + department.getChildren().size()
+ " CHILDREN");
else
log.debug("############ NODE " + department.getName()
+ " DOES NOT HAVE CHILDREN");
for (Department department2 : department.getChildren()) {
log.debug("############ CREATING CHILD "
+ department2.getName() + " FOR PARENT "
+ department.getName());
DefaultMutableTreeNode branchNode;
if (createdNodesMap.get(department2) == null) {
branchNode = new DefaultMutableTreeNode();
IceUserObject branchObject = new IceUserObject(
branchNode);
branchObject.setText(department2.getName());
branchObject.setExpanded(true);
branchNode.setUserObject(branchObject);
} else
branchNode = createdNodesMap.get(department2);
createdNodesMap.put(department2, branchNode);
currentNode.add(branchNode);
}
}
model = new DefaultTreeModel(rootTreeNode);
Check http://click.avoka.com/click-examples/tree/checkbox-tree-page.htm
The latter is done via the Apache Click framework. Right now I'm developing a project where this data structure (hierarchy tree) is heavily used. You can set the root node or if you need to have several starting points, you can create a wildcard root node that won't affect the functionality, the subclasses, like others have commented, need to be created recursively.

Categories

Resources