I want a particular desired behavior for my Nattable tree structure. In the following diagram, contents of Row no 36, 37 are children of content in Row 20.
Row 21, 23, 23 … 34 are in turn children of Row 20.
Row 22 is a child of Row 21. (you could say it is grandchild of 20)
I want Row 36, 37 to be shown first ie. In place of Row 21 and so on, that is I want to change the order in which it is shown as a child of Row 20.
I am currently using a treelist implementation to render my data in the Nattable.
My current nattable:
private List<ISectionInfo> getFlatList(List<ISectionInfo> inputList)
{
List<ISectionInfo> flatList = new ArrayList<ISectionInfo>();
for (ISectionInfo node : inputList)
{
if (node instanceof SectionInfo)
{
SectionInfo secNode = (SectionInfo) node;
if (!hasChildren(secNode))
{
flatList.add(secNode);
flatList.addAll(secNode.getModuleInfoList());
}
if (hasChildren(secNode))
{
flatList.addAll(secNode.getModuleInfoList());
flatList.add(secNode);
for (ISectionInfo iternode : secNode.getChildren())
{
flatList.addAll(((SectionInfo) iternode).getModuleInfoList());
flatList.add(iternode);
}
}
}
}
return flatList;
}
Related
I have a collection for which i want to make queries with pagination by sorting it with dateCreated field as decending to get latest documents.
Am holding lastKnownCommentId(Object id) for performance purpose. Having lastKnownCommentId would avoid loading documents from starting again during next paginations, if not then applying limit on query will cause performance issue.
Query<Comment> query = datastore.createQuery(Comment.class)
.field(POST_ID).equal(postId);
if (lastKnownCommentId != null) {
query.field(FieldConstants.OBJECT_ID).greaterThan(new ObjectId(lastKnownCommentId));
}
query.order(Sort.descending(FieldConstants.DATE_CREATED));
return query.asList(new FindOptions().limit(10));
Now i have 12 documents in this collection which matches to one postId. When this query is excecuted for first pagination with lastKnownCommentId=null it gives me 10 documents sorted by date, 2 documents are still not in pagination picture.
For second pagination with lastKnownCommentId=someId (someId is object id of last document obtained from first pagination), it gives me again 9 documents as result instead of 2 documents which remained in first pagination.
Things are working fine if i dont do sorting by date, i can completely skip this sorting and do sorting on array list instead. Am not understanding why this happening with sorting in query.
I tried to cross check with aggregation and results same ouput.
db.comment.aggregate(
// Pipeline
[
// Stage 1
{
$match: {
"postId":{"$eq":"5fb2090fe4d37312a4c3ce59"}
}
},
// Stage 2
{
$sort: {
"dateCreated":-1
}
},
// Stage 3
{
$match: {
"_id":{"$gt":ObjectId("5fb0e53392ad724f9026d2f7")}
}
},
// Stage 4
{
$limit: // positive integer
10
},
],
// Options
{
cursor: {
batchSize: 50
}
}
);
What does query look like just before you return it? (print out the value, or do a for loop if it's an object so you can see what the values are).
I have a data in tabular format like below:
Activity | ActivityID | ParentID
a1 | 1 |
a2 | 2 | 1
a3 | 3 |
a4 | 4 | 3
a5 | 5 | 2
a6 | 6 | 3
a7 | 7 | 1
I want to represent it like below in java:
a1 -> a2 -> a5
-> a7
a3 -> a4
-> a6
Basically, a List of tree objects where a1 and a3 are roots of the tree having 2 children (a2, a7 and a4, a6 respectively) and a2 has one child (a5). The tree might no necessarily be binary and the data set can be big where one parent can have 50-100 children.
What would be the most effective way in Java ?
For a list of the tree, you can store your data in a structure like this:
final class Node{
final int id;
final string name;
final List<Node> children;
}
So, the final structure is: List<Node>
The data structure you search for is called N-ary tree data structure (you can refer to wikipedia and nist).
If you are familiar with the binary tree (only two childs) , it will be easy for you to change fo n-ary tree (n childs).
In your case you have a forest of the n-ary tree (a list of the n-ary tree) , or you can consider it as one big tree with a common root, where all your effective tree begin at the level one.
The simplest way is to create a Node{info, listChildren} with a field info and a list (arrayList maybe) that will contain children, and a NTreeClasse that contain methods as addChild...generally we use a recursive function that check a certain condition to choose the right path where to insert a new node.
An example of implementing N-ary tree source code and binary tree source code example
If you want to improve your implementation or you seek optimisation, you have to consider some others points like:
The type of the list of children in each node, which is related to the possible number of children, if the number is small we can use a simple array, if the number is big we can use hash table ... etc
Is your tree change or not (dynamic with insert and delete)
The traversal of the tree
Avoid recursion: replace the recursive method by an iterative.
Consider the construction steps, the normal way is for each element, we begin from the root, and we find the right path til we arrive to the leaf where we should insert the node (new child), you can maybe insert the children directly in the right place, its depend on your data and how you want to organize your tree.
you can consider using array to store the tree, also depend strongly on your data.
Hope this helps a little bit to begin and to dig further.
I am providing you a short and straight forward algorithm. It's the dirty version. You can rewrite it as you wish(by which, i mean a better version):
I am assuming, there is a table array such that table[i].activityID would give me ith activity's id and table[i].parentID would give me the activity's parent id ans so on...
[Note: one more point here, I'm also assuming if there is no parent of an element then, its parent id is -1, i.e. in the given example of yours a1's and a3's parent id would be -1. This way we can understand which activity does not have any parent. If you have a better idea, you can use that].
Let us first define the class Activity
class Activity implements Comparable<Activity> {
int id;
String name;
List<Activity> children;
Activity(int id, String name) {
this.id = id;
this.name = name;
this.children = new ArrayList<>();
}
#Override
public int compareTo(Activity activity) {
return this.id - activity.id;
}
}
As the activity class is defined, we'll be creating activity's now and put them in a TreeMap(just to keep track of them).
Notice, which activity's parent id is -1, those will be roots of trees [and according to your example, there could be several trees formed from your table]. We'll keep track of roots while creating activity's.
// to keep track of all acticities
TreeMap<int, Activity> activities = new TreeMap<>();
for(int i=0; i<table.length; i++) {
Activity a = new Activity(table[i].activityID, table[i].activityName);
activities.add(a);
}
// to keep track of root activities
List<Activity> roots = new ArrayList<>();
for(int i=0; i<table.length; i++) {
// check if there is a parent of this Activity
Activity activity = activities.get(table[i].activityID);
// now, if activity has a parent
// then, add activity in the parent's children list
if(table[i].parentID != -1) {
Activity parent = activities.get(table[i].parentID);
// this is very bad way of writing code
// just do it for now
// later rewrite it
parent.children.add(activity);
} else {
// and activity does not have a parent
// then, it is a root
roots.add(activity);
}
}
Now, we're going to create a traverse method, which will help to traverse the tree node in order.
void traverse(Activity u) {
System.out.println(u.name);
for(Activity v: u.children) {
traverse(v);
}
}
Now, you can call this function using the root activities:
for(Activity rootActivity: roots) {
traverse(rootActivity);
}
That's it...
A bit new to xml parsing in java, so I am trying to update certain elements within xml document but I am having some issues updating the correct ones.
<Transactions>
<Transaction>
<id>222</id>
<time>...</time>
<date>...</date>
</Transaction>
<Transaction>
<id>333</id>
<time>...</time>
<date>...</date>
</Transaction>
</Transactions>
Given above xml, let's say I want to modify for each transaction. I want to update id, time and date with some other values. Each transaction I will update with different data.
So I've been trying something like below:
NodeList transactions = doc.getElementsByTagName("Transaction");
for(int i = 0; i < transactions.getLength(); i++){
NodeList id = doc.getElementsByTagName("id");
//some method to update
modifyId(id)//this works but it is doing it for all IDs in Document
}
Above modify method does work and it does update after I do some Transforming and all, but it is updating all the transactions with same id,time,date values. I want to iterate through each "Transaction" and update its child nodes (id, time, date) separately, so they each will be different. How can this be done?
Well, since you apply the getElementsByTagName method to doc - the whole document - it gives you all the elements whose name is id in the entire document.
There are several solutions to this problem.
One is, when you traverse the transaction node list, use the getChildNodes() method to get its children. You can then use getNodeName() on each of them. Once you know the name of the element, you can do whatever you wanted with it.
for(int i = 0; i < transactions.getLength(); i++) {
Node transaction = transactions.item(i);
NodeList transactionChildren = transaction.getChildNodes();
for ( int j = 0; j < transactionChildren.getLength(); j++ ) {
Node elem = transactionChildren.item(j);
switch ( elem.getNodeName() ) {
case "id":
// Whatever processing you want for id
break;
case "time":
// Whatever processing you want for time
break;
case "date":
// Whatever processing you want for date
break;
}
}
}
Another way is, when you traverse the transaction node list, to cast each node to an Element (the cast is supposed to succeed but you can always use instanceof to prevent the compiler from complaining). Then you can use the getElementsByTagName(...) method of this particular element. It should return a node list of only one item. Then you can do whatever you want with it.
for(int i = 0; i < transactions.getLength(); i++) {
Node transactionNode = transactions.item(i);
if ( transactionNode instanceof Element ) {
transactionElem = (Element)transactionNode;
NodeList elemList = transactionElem.getElementsByTagName("id");
if ( elemList.getLength() >= 1 ) {
Node idNode = elemList.item(0);
// Do whatever you want with the id node
}
elemList = transactionElem.getElementsByTagName("date");
if ( elemList.getLength() >= 1 ) {
Node dateNode = elemList.item(0);
// Do whatever you want with the date node
}
elemList = transactionElem.getElementsByTagName("time");
if ( elemList.getLength() >= 1 ) {
Node timeNode = elemList.item(0);
// Do whatever you want with the time node
}
}
}
I've been fighting with this for some time, and finally figured I needed some help.
I am trying to create a table where each cell displays a particular color. This is dynamically created based on a user selected image.
I got it to work with a TilePane, but because of the size of the table, it was running extremely slow.
Currently, I am trying to make it work using a TableView. The TableView is being created, but not populated. My code to create the TableView, and my custom TableCell class, is below.
My main question is this: Is this the best way to go about this? If so, what am I doing wrong?
Thank you in advance for the awesome assistance I always see here.
Code to create TableView:
private ObservableList<ObservableList<Stitch>> stitchList;
private TableView<Stitch> pattern;
#Override
protected TableView<Stitch> call() throws Exception {
for (int i=0; i< stitchList.size(); i++) {
TableColumn<Stitch, Color> column = new TableColumn<>();
column.setCellValueFactory(new Callback<CellDataFeatures<Stitch, Color>, ObservableValue<Color>>() {
public ObservableValue<Color> call(CellDataFeatures<Stitch, Color> stitch) {
return stitch.getValue().getDisplayColorProperty();
}
});
column.setCellFactory(new Callback<TableColumn<Stitch, Color>, TableCell<Stitch, Color>>() {
#Override public TableCell<Stitch, Color> call(TableColumn<Stitch, Color> list) {
return new StitchCell();
}
});
//Set column sizes
column.setMinWidth(10);
column.setMaxWidth(10);
pattern.getColumns().add(column);
}
return pattern;
} // End Call
Code for custom cell class
public class StitchCell extends TableCell<Stitch, Color> {
#Override
protected void updateItem(Color color, boolean empty) {
super.updateItem(color, empty);
if (empty || color == null) {
this.setStyle("-fx-background-color: white");
} else {
this.setStyle("-fx-background-color: #" + Integer.toHexString(color.hashCode()));
}
}
}
When you create a TableView<S>, S is the type of the object displayed in each row of the table. The items property of the table, which is an ObservableList<S> contains the collection of items, each one of which is displayed in a table row.
If your data is in the form ObservableList<ObservableList<Stitch>> stitchList, then you need a TableView<ObservableList<Stitch>>. (In other words, S is ObservableList<Stitch>.) Each element of stitchList, which is an ObservableList<Stitch> represents a row in the table.
TableView is not designed with ObservableList<ObservableList> as the primary use case for representing data, so you need to do a little bit of work to get the cellValueFactory to work right. If you are certain that every row has the same number of items, you can perhaps minimize this a bit, but you need something like the following:
TableView<ObservableList<Stitch>> pattern = new TableView<>();
ObservableList<ObservableList<Stitch>> stitchList = ... ;
// Set items (i.e. rows) in table:
pattern.setItems(stitchList);
// iterate through all rows:
for (ObservableList<Stitch> row : pattern) {
// if this row contains more elements than columns we have already created,
// (must be true on first row, may be true on subsequent rows if data not rectangular)
// create a new column for each additional element
for (int i = pattern.getColumns().size(); i < row.size() ; i++) {
TableColumn<ObservableList<Stitch>, Color> column = new TableColumn<>();
final int columnIndex = i ;
column.setCellValueFactory(new Callback<CellDataFeatures<ObservableList<Stitch>, Color>, ObservableValue<Color>>() {
#Override
public ObservableValue<Stitch> call(CellDataFeatures<ObservableList<Stitch>, Stitch>> stitch) {
return stitch.getValue() // the row value, i.e. an ObservableList<Stitch>
.get(columnIndex) // the Stitch for this cell
.getDisplayColorProperty();
}
});
column.setCellValueFactory(new Callback<TableColumn<ObservableList<Stitch>, Color>, TableCell<ObservableList<Stitch>, Color>>() {
#Override
public TableCell<ObservableList<Stitch>, Color> call(TableColumn<ObservableList<Stitch>, Color> col) {
return new StitchCell();
}
});
column.setMinWidth(10);
column.setMaxWidth(10);
pattern.getColumns().add(column);
}
}
If you are using Java 8, you can replace the Callbacks with lambda expressions, and get rid of the ugliest parts of the code:
for (ObservableList<Stitch> row : pattern) {
// if this row contains more elements than columns we have already created,
// (must be true on first row, may be true on subsequent rows if data not rectangular)
// create a new column for each additional element
for (int i = pattern.getColumns().size(); i < row.size() ; i++) {
TableColumn<ObservableList<Stitch>, Color> column = new TableColumn<>();
final int columnIndex = i ;
column.setCellValueFactory( rowData ->
rowData.getValue() // the row value, i.e. an ObservableList<Stitch>
.get(columnIndex) // the Stitch for this cell
.getDisplayColorProperty() );
column.setCellValueFactory(col -> new StitchCell());
column.setMinWidth(10);
column.setMaxWidth(10);
pattern.getColumns().add(column);
}
}
I am dealing with one table on the database. The columns are: id, name, parent_id
(parent_id would be an id on the table. if parent_id is null, the record is a parent.)
What would be the best way to copy and create same record through recursive loop from recursive loop so I can create same tree structure as it is:
item
item1
item 1.1
item 1.1.1
item 1.1.2
item 1.2
item 2
item 2.1
item 2.1.1
item 2.2
item3
etc and it is like nth level.
You don't need to use recursion, the code will be clearer if you don't.
First the result set needs to be ordered by id and parent_id, then you just iterate through the result set using a java.util.Map as an index, something like this:
Map<Object, Item> items = new HashMap<Object, Item>();
if (resultSet.next())
{
Item root = createItem(resultSet);
items.put(root.getId(), root);
while (resultSet.next())
{
Item item = createItem(resultSet);
items.put(item.getId(), item);
Item parent = items.get(item.getParentId());
if (parent != null)
{
parent.addChild(item);
}
else
{
...
}
}
return root;
}
else
{
...
}