I develop an eclipse plugin and I added an eclipse progress view to it. There is an stop button on the progress view and I want to create some kind of listener to handle the events of the cancel button, but I don't know how I can do it. I know the monitor has an isCanceled() method, but I have to create come kind of listener to listen when user clicks the stop button, while the plugin works. Please give me some advice. Thanks
What you have to do here is check the isCanceled method often while you are on your long-running code. If isCanceled returns true, you return from your code properly.
The progress view normally monitors Job objects; you extend org.eclipse.core.runtime.jobs.Job and implement run() to define a Job. That class has a canceling() method; you can override canceling() and set a flag to true. Then in your run() method, you just loop until that flag becomes true (or the work is done), at which point you cleanup and return.
Related
I am writing an application that stays in the traybar and do some checks every some minutes.
When it performs this checks, I would like the traybar icon to be animated.
That is why I have a first wxTimer triggering checks. In its OnTimer call I tried to manage the second wxTimer to handle the animation.
The issue is that timers work in the mainloop, so the icon is not updated when the second timer updates the icon index.
Is there a way to overcome this problem?
Thank you!
Your description of the problem is unfortunately not clear at all but if you mean that you don't get timer events until you reenter the event loop, this is indeed true and, moreover, almost tautological -- you need to return to the event loop to get any events.
This is the reason why your event handlers should always execute quickly and return control to the main loop. And if they take too long, the usual solution is to use a background thread for the real work and just schedule it in your event handler, but not wait until it is done.
Basing on Ryan G's comment
It is possible to incorporate wx.Yield() into the main loop. This is usually used to temporarily release the global lock to allow the widgets to update.
It is also possible to create a separate thread to update the animation independently from the main thread.
Using wx.Yield() should be easier to implement.
I have a Eclipse plugin that uses a view which extends ViewPart. ViewPart has a saveState method which requires an IMemento.
I added my code to saveState and the corresponding init method and it works. Unfortunately, saveState is only called if the entire workspace is shutting down. My view is not of such great importance that I can expect it to be opened the entire time. Hence, it would be cool if saveState would be called on view closure.
I found a view-part listener as mean to react on view closure, but what I do not get is where the IMemento comes from. Where do I get the memento object that is used on workspace closure? Or where do I have to store my own memento object to make the view part use it in the init method if the view is (re)opened?
#Override
public void saveState(IMemento memento) {
super.saveState(memento);
memento = memento.createChild(MEMENTO_GUI_STATE);
memento.putBoolean(MEMENTO_IS_FLAT, !isHierarchicalModeActive());
memento.putBoolean(MEMENTO_IS_CATEGORY_MODE_ACTIVE, comboViewer.isVisible());
}
This is my saveState - can I tell my view somehow tell to call it every time the view closes?
Take a look at this question in the Eclipse FAQ:
Storing view state is done in two commons ways, depending on whether
you want to store settings between workbench sessions or across
invocations of your view. The first of these facilities is found
directly on IViewPart. When the workbench is shut down, the method
saveState is called on all open views.
Another mechanism for persisting view state is the JFace
IDialogSettings facility. The advantage of dialog settings over the
view save/init mechanism is that you can control when settings are
persisted. The saveState method is called only if your view is open
when the workbench shuts down, so it is not useful for storing view
state when the view is closed by the user. Dialog settings, on the
other hand, can be changed and persisted whenever you want.
Go to this other question or to the Eclipse documentation itself for the settings mechanism.
Well this could be "a bit" ugly but nothing else came to my mind: store memento variable as a field variable, initialize it in your init(IViewSite site, IMemento memento) method, override dispose() and call saveState(IMemento memento) explicitely.
You can read and write your own XMLMemento from your org.eclipse.core.runtime.Plugin.getStateLocation() at any time you want. As #BelaViser mentioned, you could write your file in your IViewPart#dispose() method and read it in your view constructor.
I always wondered what's the best way of handling a cancel button in a more OO way. In the hurry I always end up putting the ugly checking of a boolean form property if the button was canceled of not.
The thing is that way makes the code dirty, having a lot of "cancel checks" between logic that matters.
I always get to something like this:
void doLogic()
{
checkIfIsCancelled();
callOtherFunction();
checkIfIsCancelled();
callAnotherFunction();
checkIfIsCancelled();
callAnotherFunction();
checkIfIsCancelled();
callAnotherFunction();
}
I hope I was clear enough. I just want a neater way to do this :)
A proper way to handle this is the strategy pattern, where you have a default strategy where you do the normal processing and you have a Cancelled strategy.
Canceling changes the strategy to the cancelledStrategy that does nothing but some cleanup. The next call will go to the cancelledStrategy.
In this way even the cleanup is pretty straight forward because you know exactly where in the flow it was cancelled.
Another possible solution (but very dependent on your situation) would be the state pattern, but if you only need it for canceling it creates a lot of overhead.
it would REALLY help to know what GUI kit you're using here. Just from this it's impossible to know if you're taking about a windows, linux or mac machine. Add to that I can't think of a single GUI that that would function in this manner.
Most GUI's operate with a 'callback' pattern Widgets(buttons, menus, listboxes etc) are created and your code attaches a 'callback', a piece code or object&method that is executed when an action is performed on a widget.
In java for example:
Button b = JButton("Push") ;
listener = new ActionListener()_ {
public void actionPerformed(ActionEvent e) {
System.out.println("I was pushed!") ;
}
} ;
b.addActionListener(listener)
Arranges for the message "I was pushed!" to be printed when the button is pressed. Of course this thin examples omits all of the work you need to do to setup your window, populate this widget etc.
1st what comes to mind is http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern but I'm not sure, it's good here.
You can use the command pattern alongwith a stack to implement multi level undo support.
My WinForm apps needs to execute complex query with significant execution time, I have no influence (about 10mins)
When query is executing user sees 'application not responding' in task manager, which is really confusing to user, also not very professional...
I believe that query shall be executed in different thread or so. Have tried some approaches but have difficulties to make it really working (execute query, force main application wait result, return back to main app, possibility to cancel execution etc)
I wonder if you have own / good working solution for that. Code samples would be also very welcome :)
Also I believe there might exist some ready to use utilities / frameworks allowing simple execution of that.
The simplest approach here would be to do that work from a BackgroundWorker. MSDN has examples for this. This then executes on a worker thread, with events for completion/error/etc. It can also support cancel, but your operation needs to be coded to be interruptable.
Another approach is the Task API in 4.0; but if you use this you'll need to get back to the UI thread (afterwards) yourself. With BackgroundWorker this is automatic (the events are raised on the UI thread).
If ExecuteQuery if the method you want to execute, you can do:
void SomeMethod() {
var thread = new Thread(ExecuteQuery);
thread.Start();
}
void ExecuteQuery() {
//Build your query here and execute it.
}
If ExecuteQuery receives some parameters, like:
void ExecuteQuery(string query) {
//...
}
You can do:
var threadStarter = () => { ExecuteQuery("SELECT * FROM [Table]"); };
var thread = new Thread(ThreadStarter);
thread.Start();
If you want to stop the execution of the background thread, avoid calling thread.Abort() method. That will kill the thread, and you do not want this, because some incosistency could appear in your database.
Instead, you can have a bool variable visible from ExecuteQuery and from outside you can set it to True when you want to stop it. Then all you have to do is check in some parts of the code inside ExecuteQuery if that variable is still True. Otherwise, do some rollback to maintain the database stable.
Be sure you set that bool variable volatile
Edit:
If you want the UI to wait from the background thread, I usually do:
Start the background thread
Start some progress bar in the UI
Disable some controls (like buttons, etc) to avoid the user to click them while the background thread is working (eg: If you're executing the thread when a user clicks a button, then you should disable that button, otherwise multiple queries will be ocurring at the same time).
After finished the thread, you can stop progress bar and enable controls again.
How to know when the thread finished? You can use Events for that. Just create an event and fire it when it finishes, and do whatever you want inside the event handler...
Be sure you're accessing correctly to UI controls from the background thread, otherwise it will give you an error.
If you are new to threads and task is simple (as it seems), you should try to use standard background worker component.
Is there a way to update UI manually?
For example, I have a function which updates UI and execute some logic.
After the UI update, it will execute some logic that will take a long time and update of UI has to be wait until the execution of logic is finished.
Is there a way to update UI manually befor even the logic is even executed?
It seems that thread can be used in here.
But Is there a way to solve this by not using thread?
Also, using if thread can be used, what is the best practice?
Thanks!
Because the UI thread is the main thread of your app, it's generally not a good idea to process big operations on it because you froze your UI in the meantime (which is not user friendly).
The way you use thread depends on what you want to do, you can for example just use - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg or you can create your own thread and be more specific.
Don't forget to call - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait if you want to do some changes on the UI from other thread.
You'll find all you need about thread programming in this guide from iOS Reference Library.
Hope this helps !
Are you thinking about a simple progress bar? If that is the case, then you can use something using NSApp (see the section under Managing the Event Loop) and use runModalForWindow: and runModalSession: These will allow you to open a progress panel, report on status and allow a method to cancel the operation.
Because the operation is modal, other UI elements will be deactivated until the panel is dismissed.