Display.asyncExec vs Display.timerExec - swt

I was hoping that Display.timerExec(int,Runnable) was much the same as Display.asyncExec(Runnable) but with the specified delay. However it appears that Display.timerExec can only be executed on the GUI thread, as its 1st line is a call to checkDevice(). This throws an exception if you're not running in a GUI thread.
Can anyone suggest a means to using Display.asyncExec() but with a delay preceding execution?

You can first switch to the GUI thread with asyncExec, then schedule a timer action with timerExec. These two methods are similar in that they both execute some action, but asyncExec only switches thread, timeExec only schedules an action for the GUI thread.
display.asyncExec(() -> display.timerExec(100, () -> doThings()));
This uses lambda expressions, which where introduced in Java 8.
With Java 7 or earlier one has to write it with anonymous classes like this:
display.asyncExec(new Runnable() {
public void run() {
display.timerExec(100, new Runnable() {
public void run() {
doThings();
}
});
}
});

Related

how to stop firing unrelated event of event bus

My problem is with how to stop firing unrelated event of event bus. as I got this solution for Dialog box.
but it does not work in case of where one instance already initialize and try to create new instance of same class.
Just example: A below scroll panel has handler initialized. it used for document preview.
class TestScroll extends ScrollPanel
{
public TestScroll(){
}
implemented onload()
{
// eventBus.addHandler code here.
//here some preview related code
}
unload() method
{
//eventBus remove handler code
}
}
This preview has some data which contains some links that open different preview but with same class and different data structure,
Now The problem is like onUnload ( which contains code of remove handler) event does not load , because other panel opened. that does not mean previous panel unload.
So in that case, twice event handler registered. when one event fired then other event also fired.
Due to that, Preview 1 data shows properly, but after that Preview2 opened and when I close it, I find Preview1=Preview2.
so how can I handle such situation?
As per no of instance created each event fired. but I have to check some unique document id with if condition in event itself.
is there any other ways to stop unrelated event firing?
Edit:
public class Gwteventbus implements EntryPoint {
int i=0;
#Override
public void onModuleLoad() {
TestApp panel=new TestApp();
Button button=new Button("Test Event");
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
TestApp panel=new TestApp();
int j=i;
new AppUtils().EVENT_BUS.fireEventFromSource(new AuthenticationEvent(),""+(j));
i++;
}
});
panel.add(button);
RootPanel.get().add(panel);
}
}
public class AppUtils {
public static EventBus EVENT_BUS = GWT.create(SimpleEventBus.class);
}
public class TestApp extends VerticalPanel{
String testString="";
public TestApp( ) {
AppUtils.EVENT_BUS.addHandler(AuthenticationEvent.TYPE, new AuthenticationEventHandler() {
#Override
public void onAuthenticationChanged(AuthenticationEvent authenticationEvent) {
System.out.println("helloworld"+authenticationEvent.getSource());
}
});
}
}
These are wild guesses as it's difficult to really answer it without code and a clear description.
I'm guessing you have one eventbus for all the panels. So when you register a handler it is registered with that one eventbus. In case you fire an event from one of the panels to the eventbus all panels will receive the event.
To fix this you can either create a new eventbus per panel or check who fired the event with event.getSource().
If this doesn't make sense you probably are reusing a variable or use a static variable which actually should be a new instance or none static variable.
You can use the GwtEventService-Library to fire specific events over a unique domain and every receiver that is registered at this domain receives that events then. You can handle as many different events/domains as you want.
In order to remove a handler attached to the EventBus, you must first store a reference to the HandlerRegistration returned by the addHandler method:
HandlerRegistration hr = eventBus.addHandler(new ClickHandler(){...});
Then you can remove the handler with the removeHandler method:
hr.removeHandler();
A final note worth mentioning is that when using singleton views, like is typical with MVP and GWT Activities and Places, it is best practice to make use of a ResettableEventBus. The eventBus passed to an activity's start() is just such a bus. When the ActivityManager stops the activity, it automatically removes all handlers attached to the ResettableEventBus.
I would strongly recommend reading the GWT Project's documentation on:
Activities and Places
Large scale application development and MVP

GWT Timer.scheduleRepeating keeps firing after call to cancel()

The GWT timer I use in my application doesn't seem to respond to a call to cancel().
I see new server calls being fired, even after cancel() is reached.
com.google.gwt.user.client.Timer t = new com.google.gwt.user.client.Timer() {
#Override
public void run() {
myService.poll(result.getKey(), new HappyAsyncCallback<JobResult>() {
#Override
public void onSuccess(JobResult result) {
if (result.getUuid() != null && !result.getUuid().isEmpty()) {
Window.alert("Done! Cancelling...");
cancel();
}
}
});
}
};
t.scheduleRepeating(5000);
I read these similar issues, but haven't been able to use these issues to my advantage unfortunately.
GWT Timer cancel not working
Can't cancel repeat timer in GWT
I have been fooled by my own application here. We are doing a really lengthy batch process on the server and during this process the Timer will fire multiple calls to poll(). When the cancel() method is reached, these calls are still returning from the server :) Thanks for your suggestions, Manolo.

SWT - Tweaking my ProgressMonitorDialog

I have a working ProgressMonitorDialog, but I want to make sure that I am setting it up correctly.
First the Code:
Method to create Dialog
public void startProgressBar() {
try {
new ProgressMonitorDialog(getShell()).run(true, true,
new ProgressBarThread());
}
catch (InvocationTargetException e) {
MessageDialog.openError(getShell(), "Error", e.getMessage());
}
catch (InterruptedException e) {
MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage());
}
}
Class File
class ProgressBarThread implements IRunnableWithProgress {
private static final int TOTAL_TIME = 1000;
public ProgressBarThread() {
}
public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException {
monitor.beginTask("Creating PDF File(s): Please wait.....", IProgressMonitor.UNKNOWN);
for (int total = 0; total < TOTAL_TIME ; total++) {
Thread.sleep(total);
monitor.worked(total);
if (total == TOTAL_TIME / 2) monitor.subTask("Please be patient... Operation should finish soon.");
}
monitor.done();
}
}
Method that calls the ProgressBar and runs a Pdf file creation Operation
private void startSavePdfOperation() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
startProgressBar();
}
});
saveOp = new AplotSaveOperation(appReg.getString("aplot.message.SAVETOPDF"), "PDF", session);
saveOp.addOperationListener(new MyOperationListener(this) {
public void endOperationImpl() {
java.io.File zipFile = null;
try {
AplotSaveResultsParser.SaveResult saveResults = saveOp.getSaveResults();
if (saveResults != null) {
ETC..... ETC......
Questions:
Being the ProgressMonitorDialog is a GUI, it needs to be executed in a
Display.getDefault().asyncExec?
If the ProgressMonitorDialog is running in a separate thread, how does it know to close when the operation is finsihed?
Is there any relationship between the progressbar and the operation?
I am correct in assuming that the for loop in the ProgressBarThread class is basically the timer that keeps the monitor open?
Is there a way to increase the speed of the ProgressMonitorDialog's indicator, also can you remove the cancel button?
This is what I am thinking is happening currently.
I am starting the progress bar just before I start the PDF Operation Listener
See startSavePdfOperation() Above
The progress bar is running as unknown, but using a for loop to keep the progress bar dialog open, while the operation is running on a thread in the background.
See Class ProgressBarThread above
When the PDF operation completes the listener operation class closes the base GUI dialog.
public void endOperation() {
try {
endOperationImpl();
}
finally {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW));
w.recursiveSetEnabled(getShell(), true);
w.getShell().setEnabled(!getShell().getEnabled());
w.close();
}
});
}
}
I am not sure what is happening to the ProgressBarThread monitor?
Is this Possible?
When the PDF Operation starts, the ProgressMonitorDialog opens and starts the indicator. OK with keeping it unknown.
When the PDF Operation completes, the monitor closes, then the base Dialog
I am just wanting to open progress bar dialog that will inform the user that their request is working in the background.
As stated the above code works, but I am afraid by letting the closing of Base GUI, destroy my Progress Thread and Monitor is not good practice.
First of all, in your ProgressBarThread#run() you should use monitor.worked(1). You don't need to set the total worked but increment it by the amount of work done, since the last time it was called.
Q1. Yes it needs to be executed in the display thread
Q2. Normally the work that needs to be done is actually performed in the runnable that is passed to the progress monitor dialog so that you can accurately report the amount of progress made. So your operation (if it is a synchronous call) should be called from within ProgressBarThread#run() so that you call monitor.worked(1) only when one file processing is complete.
Q3. What kind of operation are you running, perhaps it already supports showing progress bar, and you just need to invoke the right API. Is it an IUndoableOperation?
Q4. As I said this approach is problematic because you can never accurately report the progress and close the dialog only when the operation is completed. But if this is the only choice you have, then you can just save the monitor reference somewhere so that it is accessible to the other thread. Once monitor.done() is called, your ProgressBarThread#run() should return, the dialog will close.
Q5. You can remove the cancel button by passing the correct parameter to ProgressMonitorDialog#run(..):
new ProgressMonitorDialog(getShell()).run(true, false, new ProgressBarThread());
For the rest of the questions I can better answer if I know what kind of operation (what API) you are using.

Can't hit breakpoints for user generated actions when debugging jython code with PyDev in Eclipse

I'm implementing a GUI application in Jython, using Eclipse and PyDev plugin.
The problem is that I have a hard time using the builtin debugger. When I start a debug session it just stops. Of course this should be expected as the program just creates a JFrame and then it's finished.
So any breakpoints I put for different events .e.g. pressing a button, will never happen as the debug session is already terminated.
What should I do ? I'm growing tired of using prints for all my debugging.
For instance, when I tried debugging this small Java example. I have no problem to hit
the breakpoint I had set in the windowClosing-method
import java.awt.event.*;
import javax.swing.*;
public class Test1 {
public static void main(String s[]) {
JFrame frame = new JFrame("JFrame Source Demo");
// Add a window listner for close button
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
}
}
And then I tried this somewhat more or less similiar example in jython
from javax.swing import JFrame;
import java.awt.event.WindowListener as WindowListener
class Test1 (JFrame, WindowListener):
def __init__(self):
super(JFrame, self).__init__('Some name goes here', defaultCloseOperation = JFrame.EXIT_ON_CLOSE, size = (800, 800))
self.addWindowListener(self)
self.setVisible(True)
def windowClosing(self, windowEvent):
print 'window closing'
pass # want to hit this breakpoint
someFrame = Test1()
pass #breakpoint here maybe
If I tried to run the jython example in the debugger and it just terminates. Ok then I added a breakpoint after I created someFrame and a breakpoint in the windowClosing method. Still no luck, It doesn't get hit when I close the window but I see it executed as I see the printout.
Can anyone tell me what I'm doing wrong ? I'm sure I forgot something very simple.
Put a breakpoint in the first line of your main method that initiates the application.
If you want to debug certain actions like pressing a button add an action listener to a button and inside the handling method add the breakpoint. For example:
JButton button = new JButton("OK");
button.addActionListener(new ActionListener()
{
#Override
public void action(ActionEvent e)
{
System.out.println("button OK has been pressed"; // add breakpoint here
// call to some code that handles the event
}
});
I had the same problem
btnCompilar = new JButton("Compilar");
btnCompilar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
compile(); //can't hit breakpoint here
}
});
I couldn't hit breakpoints inside actionPerformed, so I just made a method and used breakpoints in it.
void compile(){
//can hit breakpoint here
}

When do asyncExec events begin?

I'm attempting to create a bare bones app for use in developing a plugin. I don't need a workbench.
Below the title1 dialog will show, but the title2 never does.
What needs to be done in order for the 2nd one to be shown?
public class BareBonesApp extends AbstractApplication
{
public Object start(IApplicationContext context) throws Exception
{
Display display = PlatformUI.createDisplay();
MessageDialog.openWarning(null, "title1", "message1");
display.asyncExec(new Runnable()
{
public void run()
{
MessageDialog.openWarning(null, "title2", "message2");
}
});
return null;
}
}
Display has different queues for runnables that should run sync, async or in a specifc time (Display.timerExec). When Display.readAndDispatch has dispatched all events, first the runnables in the sync-queue are executed, then the async-queue is emptied and after that the due timerExec runnables are executed.
The only difference between Display.syncExec and Display.asyncExec is that the syncExec method waits for the runnable to be executed by the Display thread. Display.asyncExec simply queues the runnable and goes on.
So if "title2" never appears, I asume your application does not run the Display loop:
Display display = new Display(); // this thread should be the only one that creates a display instance
while (someCondition) {
if (!display.readAndDispatch())
display.sleep();
}