How do you insert page breaks in Dynamic AX reports?
Call element.newPage(). If your report has no code on it and you want a page break before a particular section, add an executeSection method and call element.newpage() before the call to super().
public void executeSection()
{
;
element.newPage();
super();
}
Related
In Vaadin, when you scroll down or up in tables (com.vaadin.ui.Table) there is no event that will be fired to tell you that user is now scrolling.
Why would we need scroll event in table?
Let's first take a look at this example of Vaadin (Dashboard Demo) after you open the link just click sign in, and you'll be automatically redirected to the transactions page, this page shows a table of financial transactions, these transactions will show a batch after another while you are scrolling, what actually happened is that the data was loaded on UI initiation (all the transactions).
Now, let's assume that we have thousands or say millions of transactions. Is it logic to load them all together when the UI is initiated? isn't it of wisdom to load them bit by bit to prevent slowing down the UI while it waits for all transactions to load?.
The best solution to this problem is to get the first (say 100 transactions) then get more transactions while scrolling down, but this solution have only one problem, that is Vaadin does not support Scroll Event Handling in com.vaadin.ui.Table !!
According to your question you are looking for lazy loading.
If you connect your table with a container which supports lazy loading your items are loaded from it's data source lazily. This means when you scroll and get out of the buffered items the table "asks" the container for more items. The container then loads more items from it's data source.
For example the JPAContainer from Vaadin supports that feature. This container connects to a data source using JPA. More information here.
Vaadin Table's Scrolling Event
The Dashboard Demo (GitHub repo) project actually depends on Vaadin tables as you see in the code in this file in line 53, what we are going to do is to extend com.vaadin.ui.Table and implement our own behavior that will support scrolling Vaadin tables from now on.
First of all, let's create new simple interface ScrollingTableScrollListener this interface will be responsible for implementing scroll events and its code will look like this:
package com.vaadin.demo.dashboard.scrolling;
public interface ScrollingTableScrollListener {
public void doTableScroll();
}
This interface should be implemented whenever you have a table in your view and you want to add a scroll event handler for it. But wait a minute this is not applicable to any kind of tables, this is only applicable to our own table.
Now, let's create our table, our table's name is (ScrollingTable) and it extends (com.vaadin.ui.Table) this class code is:
package com.vaadin.demo.dashboard.scrolling;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.vaadin.ui.Table;
public class ScrollingTable extends Table {
private static final long serialVersionUID = 5007124121625961567L;
List listeners = new ArrayList();
private void fireSrollEvent() {
for (ScrollingTableScrollListener listener : listeners) {
listener.doTableScroll();
}
}
public void addScrollListener(ScrollingTableScrollListener listener) {
listeners.add(listener);
}
#Override
public void changeVariables(Object source, Map variables) {
super.changeVariables(source, variables);
fireSrollEvent();
}
}
Actually, this table is the same as Vaadin's one, but it has the following differences:
It overrides the method changeVariables() of the super class (Vaadin Table : com.vaadin.ui.Table), actually here lays our core business that will initiate the Scrolling Behavior. What we did here is that we invoked the changeVariables() of the super class and then we invoked the fireSrollEvent() method.
Another difference is that it has two more members:
public void addScrollListener(ScrollingTableScrollListener listener) this method will take care of adding new listeners to table's scrolling event.
private void fireSrollEvent() this method is the one that will be invoked by changeVariables() method and will invoke the method doTableScroll() on every registered listener that this table has added by invoking the method addScrollListener().
Now to make use of the new stuff that we have added, we will change the original code of the aforementioned Dashboard demo (specifically the file TransactionsView.java). In this file there are only few lines to add and modify.
First, we will modify the line 49 by adding new interface that this class will implement, which is our new interface (ScrollingTableScrollListener) and implement its single method by adding the following lines in the end of this class:
#Override
public void doTableScroll() {
// TODO Auto-generated method stub
Notification.show("You are scrolling!\nYou can add your own behavior here!");
}
Then, we will change both lines 53 and 66 to use the new inherited class (ScrollingTable) rather than the super class (Table):
//Line 53 in the original class
Table t;
//Line 55 in our class
ScrollingTable t;
....
....
....
//line 66 in the original class
t = new Table() {
//line 68 in our class
t = new ScrollingTable() {
Finally, we should add the listener to our ScrollingTable's scrolls :) , this is done by invoking the method addScrollListener on the table (t) after defining the table (line 89 of our new class):
t.addScrollListener(this);
this line means that this class (TransactionView) is listening on the ScrollingTable (t) scroll event, and it will invoke the method doTableScroll whenever the user scrolls down/up the ScrollingTable (t).
Here you go, you have now a table that will tell you whenever the user is scrolling, your task now is to do what you want when the table fires scrolling event and put your stuff between the curly brackets {} of the method that we defined in the first step:
#Override
public void doTableScroll() {
// Put your own code here ...
}
Here is the link of the new Dashboard on GitHub.
The answer on my blog
Hm, event fires on EVERY action with table (such as row select, etc.). More appropricate solution is additional checking variable changing in table state.
Here example:
public class ScrollingTable extends Table {
// ...
#Override
public void changeVariables(Object source, Map<String, Object> variables) {
super.changeVariables(source, variables);
handleScrollEvent(variables);
}
private void handleScrollEvent(Map<String, Object> variables) {
if (variables.containsKey("firstvisible")) {
for (TableScrollListener listener : listeners) {
listener.doTableScroll();
}
}
}
I'm doing a project in Vaadin 7.
In my project, I need to disable column reordering feature for particular columns in Treetable?
I'm really searching for function like this 'setColumnReorderIds()'.
Is it possible to do it in Vaadin 7.
Or else I need to write some code with 'ColumnReorderListener()'?
Update
This code is to set the first column fixed in a TreeTable. I want to disable reordering in Hierarchy column in the tree table.
public class CustomTreeTable extends TreeTable {
private static final long serialVersionUID = 1L;
private Object[] visibleColumns;
private KeyMapper<Object> columnIdMap = new KeyMapper<Object>();
#Override
public void paintContent(PaintTarget target) throws PaintException {
super.paintContent(target);
paintColumnOrder(target);
}
private void paintColumnOrder(PaintTarget target) throws PaintException {
visibleColumns = this.getVisibleColumns();
final String[] colorder = new String[visibleColumns.length];
int i = 0;
colorder[i++] = columnIdMap.key("Column 1"); // Logic to keep the first column fixed
for (Object colId : visibleColumns) {
if(!colId.equals("Column 1")) {
colorder[i++] = columnIdMap.key(colId);
}
}
target.addVariable(this, "columnorder", colorder);
}
}
Update 2
I tried what Oskar said..
In addition to
paintColumnOrder(target).
I'm calling
paintVisibleColumnOrder(target),
paintAvailableColumns(target),
paintVisibleColumns(target).
i'm able to stop reordering only for the table headers. But, the body is still reordering. Any guesses on this issue?
In the documentation there is only setColumnReorderingAllowed() which allows to control reordering of all columns. So if your case is to control particular ones it looks to me as a very custom behaviour and I would go with own implementation. Also ColumnReorderEvent is generated after processing the action itself therefore implementing own ColumnReorederListener won't help us here I think.
All actual magic which we want to change happens in private Table.paintColumnOrder() called from public Table.paintContent(), called from public TreeTable.paintContent() (see sources of Table and TreeTable). The solution would be:
extend TreeTable
override paintContent() with merged copies of Table.paintContent() and TreeTable.paintContent()
replace paintColumnOrder() call with your custom logic.
Update
Ok, now I see it's more tricky then I thought at the beginnig, since there is no easy way to access most of required fields and methods after subclassing TreeTable... Moreover, columns are reorered on the client side and only the change event status is sent to inform the server. I don't know how to handle custom reordering without creating custom gwt widget :(
We are currently facing one problem in our portlet-environment using JSF2.
The application is creating dynamic portal-pages for the actual user session...think of it as Eclipse editor-views where the user can edit entities. So for now I call the dynamic-views editors :-)
The problem we are facing now, is following. The user navigates to a editor and works on the portlet(s). The displayed views in each portlet change over time of course. Now he wants to have a look on another entity which is displayed in another editor. But when he navigates back to the first editor, the state of portlets changes back to the default views.
In the portlet-world each portlet each portlet gets the view it should display via a parameter which is stored in the PortletSession and I can easily change that parameter as well. I know that this parameter is causing the trouble because when the changes the editors, the portlets will always check this parameter to decide which view to show.
request.getPortletSession().setAttribute("com.ibm.faces.portlet.page.view", "/MyPage.xhtml");
My idea was, to somehow add a callback to each JSF-navigation which will set this parameter to the view the navigation is going to display (possibly including view-params).
Is it possible to have a standard callback? If not, would be possible to execute some kind of EL in the navigation-rule that will set this parameter?
somehow add a callback to each JSF-navigation
You could perform the job in a custom ConfigurableNavigationHandler. Here's a kickoff example:
public class MyNavigationHandler extends ConfigurableNavigationHandler {
private NavigationHandler parent;
public MyNavigationHandler(NavigationHandler parent) {
this.parent = parent;
}
#Override
public void handleNavigation(FacesContext context, String from, String outcome) {
// TODO: Do your job here.
// Keep the following line untouched. This will perform the actual navigation.
parent.handleNavigation(context, from, outcome);
}
#Override
public NavigationCase getNavigationCase(FacesContext context, String fromAction, String outcome) {
return (parent instanceof ConfigurableNavigationHandler)
? ((ConfigurableNavigationHandler) parent).getNavigationCase(context, fromAction, outcome)
: null;
}
#Override
public Map<String, Set<NavigationCase>> getNavigationCases() {
return (parent instanceof ConfigurableNavigationHandler)
? ((ConfigurableNavigationHandler) parent).getNavigationCases()
: null;
}
}
To get it to run, register it as follows in faces-config.xml:
<application>
<navigation-handler>com.example.MyNavigationHandler</navigation-handler>
</application>
I have a few utility actions that return text output via return Content("my text","text/plain").
Sometimes these methods take a few minutes to run (i.e. log parsing, database maintenance).
I would like to modify my action method so that instead of returning all of the output at once, the text is instead streamed to the client when it is ready.
Here's a contrived example:
public ActionResult SlowText()
{
var sb = new System.Text.StringBuilder();
sb.AppendLine("This happens quickly...");
sb.AppendLine("Starting a slow 10 second process...");
System.Threading.Thread.Sleep(10000);
sb.AppendLine("All done with 10 second process!");
return Content(sb.ToString(), "text/plain");
}
As written, this action will return three lines of text after 10 seconds. What I want is a way to keep the response stream open, and return the first two lines immediately, and then the third line after 10 seconds.
I remember doing this 10+ years ago in Classic ASP 3.0 using the Response object. Is there an official, MVC-friendly way to accomplish this?
--
Update: using Razor .cshtml in the app; but not using any views (just ContentResult) for these actions.
Writing directly to the Response object should work, but only in some simple cases. Many MVC features depend on output writer substitution (e.g. partial views, Razor view engine, and others) and if you write directly to the Response your result will be out of order.
However, if you don't use a view and instead write straight in the controller then you should be fine (assuming your action is not being called as a child action).
I would skip the MVC controller entirely since you are going to break encapsulation anyway. In it's place I'd use a barenaked IHttpHandler implementation, streaming directly to the aforementioned output stream.
You are exposing yourself to a browser timeout if the process takes longer than originally intended. Then you don't have a way to recover what happened / unless you implement a separate method that gives the information on the long running process.
Given that you want the other method anyway, you can start a long running process and return immediately. Have the browser check the other method that gives the latest information on the long running process. On the last time I had to do this, I kept it simple and just set the refresh header from the controller before returning the view.
As for starting a long running process, you can do something like this:
// in the controller class
delegate void MyLongProcess();
//...
// in the method that starts the action
MyLongProcess processTask = new MyLongProcess(_someInstance.TheLongRunningImplementation);
processTask.BeginInvoke(new AsyncCallback(EndMyLongProcess), processTask);
//...
public void EndMyLongProcess(IAsyncResult result)
{
try{
MyLongProcess processTask = (MyLongProcess)result.AsyncState;
processTask.EndInvoke(result);
// anything you needed at the end of the process
} catch(Exception ex) {
// an error happened, make sure to log this
// as it won't hit the global.asax error handler
}
}
As for where do you put the log of the actions that happened, it's up to you to how long lived you want it to be. It can be as simple as a static field/class where you add the info of the ongoing process, or instead saving it to a data store where it can survive an application recycle.
The above assume this is all about a long running process that goes on reporting the actions that has been done. Streaming is a different subject, but the above might still play a role in keeping the operations in your controller & only the piece responsible of streaming what becomes available to the client in the action result.
You can implement your custom ActionResult like ContentStreamingResult and use HttpContext, HttpRequest and HttpResponse in the ExecuteResult method.
public class ContentStreamingResult : ActionResult
{
private readonly TextReader _reader;
public ContentStreamingResult(TextReader reader)
{
_reader = reader;
}
public override void ExecuteResult(ControllerContext context)
{
var httpContext = context.HttpContext;
//Read text from the reader and write to the response
}
}
public class YourController : Controller
{
public ContentStreamingResult DownloadText()
{
string text = "text text text";
return new ContentStreamingResult(new System.IO.StringReader(text));
}
}
Try Response.Flush and BufferOutput to false. Note it would work with the different action results, you have to directly write into the response object. Probably you can use it with conjunction with AsyncController.
Just started doing some code porting from .Net CF to Blackberry JDE 4.6.1. But haven't found how to implement custom events.
I have a custom syncManager that raise events in .Net CF so I can update the UI (sort of the observer patron).
Any pointers or help where I can start?
I can recommend the j2me-observer project. It has a liberal license and will give you an implementation of the observer pattern which isn't included in J2ME. It can be used to allow UI changes to happen based on fired events.
you can send custom event using.
//you can use any int value for CUSTOM_EVENT
fieldChangeNotify(CUSTOM_EVENT);
and you can handle that event using
public void fieldChanged(Field field, int context) {
if(cotext == CUSTOM_EVENT){
Dialog.alert("custom event");
}
}
I can recommend the open source project javaEventing. It's available at http://code.google.com/p/javaeventing , and makes it easy to define, register for and trigger custom events, much like in C#.
An example:
Class MyEvent extends EventManager.EventObject {}
EventManager.registerEventListener(new EventManager.GenericEventListener(){
public void eventTriggered(Object sender, Event event) {
// <-- The event is triggered, do something.
}
}, new MyEvent());
EventManager.triggerEvent(this, new MyEvent()); // <-- Trigger the event
bob