I try to print a treetableview, and i am now landed by using lookup like bellow. The problem is although the lookup id refers to the hole of treetableview, but it prints just part of it. How can I split my treetableview in more nodes and print them over multiple pages? I have tried
printerJob.getJobSettings().setPageRanges(new PageRange(1,5));
but i did not work. In swing it happened automatically if treetable was bigger to fit on a page. I do not want to make cells smaller.
#FXML
private void doPrint(){
PrinterJob job = PrinterJob.createPrinterJob();
PrinterJob printerJob = PrinterJob.createPrinterJob();
if(printerJob.showPrintDialog(main.getPrimaryStage().getOwner()) && printerJob.printPage(main.getPrimaryStage().getScene().lookup("#treeTable")))
printerJob.endJob();
}
You currently cannot do it.
There is a feature request for this. Feel free to Vote for it.
Though, if you do not want the TreeTableView node, you can segregate the data and print it using some other node.
Related
I have this grails application and I've added a number field and a button which on click passes on the query parameters, specifically the offset value so the user can navigate to a specific page faster, since the pagination has some 2000+ pages on a max=10 basis, you can imagine navigating that. Anyway, so my problem is that I'm handing the offset with jquery and all fine but when I press enter on the number field that triggers the form which is build in combination with the controller and practically filters back to page 1. So I wonder if someone knows how would I add an extra field that will pass in an offset value as well when form with filters is submitted. Sorry no code to post but this application is a monster and I suck at Grails or Spring boot in general. Any support is appreciated.
Do you mean 2000 pages or rows.
Also i think if you share some few codes from your
Controller method
GSP (Thus the .gps file)
Javascript implementation
it will give a lot of people an insight on how to help us all solve the questions
I'll post the answer for those who might look for this.
Grails pagination uses TwitterBootstrapTagLib class, you'll find the pagination logic there. It looks for an 'offset' variable in the session params and if it doesn't find one it creates one.
Now the solution is a bit trickier than setting an 'offset' variable because when you do so you will disable the paging arrows, why? too long to explain, but trust me, you will.
To avoid having to control all the other parts of the pagination which is done perfectly well from this class you can create a new session variable, e.g. _offset, in the controller that calls the data that needs pagination.
def controllerActionX() {
...
if(params.containsKey('offset') && !params.containsKey('_offset')){
params['_offset'] = params.offset
}
...
}
You need to check first because in a second iteration you don't want to reassign offset to _offset because then you'll be stuck in one page. Also notice that offset already exists in the session, assigned by the bootstrap class.
Then you create your fields in the view:
<input type="submit" class="goto-page" id="goto-page" value="Go To Page"/>
<g:field type="number" class="topage-number" name="_offset" min="1" value="${params._offset?:1}"/>
This is self-explanatory, however, the value from the _offset field is a value entered by a human so we still need to calculate the offset based on the max records per page, i.e. in order to get page 2 on a 10 records-per-page basis, our offset has to be between 11-19, 19 preferably because it makes calculation easier.
And last step in the service layer we calculate everything like this:
def get(HttpSession session, Map params, Xclass xUser, String status) {
....
String offset = '0'
if(params.containsKey('_offset')){
if(params['_offset'] != params.offset){
params.offset = ((params._offset as int) * (max as int)) - 1
}else{
params['_offset'] = (params.offset as int) / (max as int) + 1
}
}
if (params.containsKey('offset')) offset = params.offset
...
def result = executeQuery(resultsQuery,mapping, [max: max, offset: offset])
result
That's it. Remember to cast your variables as integers when you calculate; you don't have to convert them to String after that since that is handled by the session.
By the way this is a poorly written application because the service layer should never handle any endpoint transactions, that is only a controller's job if we're following proper SOLID and MVC principles, but I found this application like this so I had to work with it.
Unable to understand how "Operations on a stream produce a result, but do not modify its underlying data source" with reference to java 8 streams.
shapes.stream()
.filter(s -> s.getColor() == BLUE)
.forEach(s -> s.setColor(RED));
As per my understanding, forEach is setting the color of object from shapes then how does the top statement hold true?
The value s isn't being altered in this example, however no deep copy is taken, and there is nothing to stop you altering the object referenced.
Are able to can alter an object via a reference in any context in Java and there isn't anything to prevent it. You can only prevent shallow values being altered.
NOTE: Just because you are able to do this doesn't mean it's a good idea. Altering an object inside a lambda is likely to be dangerous as functional programming models assume you are not altering the data being process (always creating new object instead)
If you are going to alter an object, I suggest you use a loop (non functional style) to minimise confusion.
An example of where using a lambda to alter an object has dire consequences is the following.
map.computeIfAbsent(key, k -> {
map.computeIfAbsent(key, k -> 1);
return 2;
});
The behaviour is not deterministic, can result in both key/values being added and for ConcurrentHashMap, this will never return.
As mentioned Here
Most importantly, a stream isn’t a data structure.
You can often create a stream from collections to apply a number of functions on a data structure, but a stream itself is not a data structure. That’s so important, I mentioned it twice! A stream can be composed of multiple functions that create a pipeline that data that flows through. This data cannot be mutated. That is to say the original data structure doesn’t change. However the data can be transformed and later stored in another data structure or perhaps consumed by another operation.
AND as per Java docs
This is possible only if we can prevent interference with the data
source during the execution of a stream pipeline.
And the reason is :
Modifying a stream's data source during execution of a stream pipeline
can cause exceptions, incorrect answers, or nonconformant behavior.
That's all theory, live examples are always good.
So here we go :
Assume we have a List<String> (say :names) and stream of this names.stream(). We can apply .filter(), .reduce(), .map() etc but we can never change the source. Meaning if you try to modify the source (names) you will get an java.util.ConcurrentModificationException .
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Joe");
names.add("Phoebe");
names.add("Rose");
names.stream().map((obj)->{
names.add("Monika"); //modifying the source of stream, i.e. ConcurrentModificationException
/**
* If we comment the above line, we are modifying the data(doing upper case)
* However the original list still holds the lower-case names(source of stream never changes)
*/
return obj.toUpperCase();
}).forEach(System.out::println);
}
I hope that would help!
I understood the part do not modify its underlying data source - as it will not add/remove elements to the source; I think you are safe since you alter an element, you do not remove it.
You ca read comments from Tagir and Brian Goetz here, where they do agree that this is sort of fine.
The more idiomatic way to do what you want, would be a replace all for example:
shapes.replaceAll(x -> {
if(x.getColor() == BLUE){
x.setColor(RED);
}
return x;
})
This my project code I want to save my data into database.
def save(){
List<Employee> list = Employee.findAllById(session.getAttribute("empId"))
Milestone milestone = new Milestone()
milestone.setMilestone_Date(params.milestone_Date)
milestone.setMilestone_Name(params.milestone_Name)
milestone.setMilestone_Description(params.milestone_Description)
milestone.save()
EmployeeMilestone employeeMilestone=new EmployeeMilestone()
Employee employee = list.get(0)
employeeMilestone.setEmployee(employee)
employeeMilestone.setMilestone(milestone)
employeeMilestone.save()
[employeeMilestones:employeeMilestone]
}
I am getting this error
Error 500: Internal Server Error URI /ProjectTrackerMain/milestone/save Class java.lang.IndexOutOfBoundsException Message Index: 0, Size: 0
You didn't actually ask a question, so this may be a bit vague!
An IndexOutOfBoundsException happens when you try to access something from a collection in a location where there is no "something". For example, maybe you asked for the tenth element in a list, but there are only two. In your case, you're asking for the zeroth (in plain English, "First") element on this line of code:
Employee employee = list.get(0)
and presumably the list is empty. Your error message says "Size: 0". You can't get the first element from a list that has zero elements in it, so that's an index out of bounds exception.
Why is your list 0? That's a different question. You might try printing out
session.getAttribute("empId")
to see if your employee ID is what you expected. You might also look at the data in your database to see if you actually managed to save an employee! One way or another, you're not getting the data you expected, and then you're trying to use it.
In general, using a debugger to look at your elements, or just using "println" along the way to look at values is helpful in debugging problems like this. That way, you'll find out on line 1 that your list of Employees is not what you expected, instead of several lines later when you try to use it!
I have been using parameters to query node indexes as such (using the rest api in java)-
final QueryResult<Map<String,Object>> result = engine.query("start nd=node:name_index(name={src}) return nd.age as age", MapUtil.map("src", "Susan");
However I haven't been able to get this to work for a collection of nodes/names. I have been trying something along the lines of-
final QueryResult<Map<String,Object>> result = engine.query("start nd=node:name_index(name={src}) return nd.age as age", MapUtil.map("src", Arrays.asList("Susan","Brian", "Ian"));
But it refuses to compile. I as wondering if there is something wrong in my syntax or that parameters are not designed to work in this context.
The name= syntax in the start is meant to do an index lookup on a property. It won't do an IN lookup. The way you can do this sort of lookup is like this (note it depends on Apache's StringUtils):
List<String> names = Arrays.asList("Susan","Brian", "Ian");
String luceneQuery = "name:("+StringUtils.join(names, ",")+")";
engine.query("start nd=node:name_index({luceneQuery}) return nd.age as age", MapUtil.map("luceneQuery", luceneQuery));
Just a note, this is the "legacy" index way of doing things. In 2.0 they've introduced label-based indexes, which work entirely differently.
Thanks a lot; though it would still only return a non empty answer when I added a space after the comma in line 2. I used-
String luceneQuery = "name:("+StringUtils.join(names, ", ")+")";
and it returned the age of one person. When I tried this:
String luceneQuery = "fs:(fs:"+ StringUtils.join(names, " OR fs:")+")";
it gave me all three ages. However, I am still unsure about whether this query will be able to leverage the usual advantages of parameters , i.e. will the engine be able to reuse the query and execution path the next time around (this time we may want to query for 4 names instead of 3)
The controller makes a few calls to the model, then it returns some data to the view. The view actually, sadly, (it's not my fault), contains a ton of inline queries and more calls to the Model, yeah I know. Anyways I am tasked with optimizing this really slow page and I am trying to figure out how I can tell which thing is taking the most time. I was just going to put a timer at the start and the end of each 'thing' that the page does and output them to a log with the line number or something. But not sure what the most accurate way to do this is.
//in controller
StartTimer();
var something = model.something.getsomething(someID);
StopTimerAndLog(3); //line number
<!-- in view -->
<%StartTimer();
var something = model.somethingelse.getanotherthing(someotherID);
StopTimerAndLog(2);%>
so on and so forth...
Then the question remains about what timing mechanism to use, I'm sure there must be a question about this already. But I don't know if my situation makes anything unique or not... any ideas?
If you really want to measure like this, I would use the StopWatch class:
var watch = new StopWatch();
watch.Start();
var something = model.something.getSomething(someID);
watch.Stop();
var time = watch.Elapsed;
If you want something really detailed and without writing any extra code...I would suggest the use of a Profiler. It will give you details about exactly what is taking so long and why. My personal favorite is RedGate's ANTS Performance Profiler.