I have Eclipse RCP based application, with Eclipse ProgressView for tracking JOBs.
I have implemented RepeatingJob according to:
http://wiki.eclipse.org/FAQ_How_do_I_create_a_repeating_background_task%3F
1st time of running my repeating JOB I can see progressMonitor working in ProgressView. Problem is when next time this repeating job is started then I see no ProgressMonitor.
In the beginning of operation I start monitor.beginTask("Blabla..whatever..."), I do not stop IProgressMonitor in my operation after its finished.
I dont know where could be problem.
If you put a breakpoint in the 'run' method of your job class, you'll see, that it is actually running, but display is not refreshed. Try to put your thread sleep for a while:
protected IStatus run(IProgressMonitor monitor) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
monitor.beginTask("repeating...", 1);
schedule(3000);
monitor.done();
return Status.OK_STATUS;
}
Related
I have 5 pictures in the image properties in simulation window. I would like the images to be changing every 5 seconds. In Image properties advanced section i can change the picture manually using image index. Can I use while loop to do such operation in simulation window?
If yes How can I implement it?
In the simulation window you can do this on the initial experiment setup java action:
new Thread(new Runnable() {
public void run() {
while(true){
image.setIndex(image.getIndex()==image.getImageCount()-1 ? 0 : image.getIndex()+1);
try{
TimeUnit.SECONDS.sleep(5);
}catch(Exception e){
}
}
}
}).start();
This will require to add in the advanced section, on the imports section: import java.util.concurrent.TimeUnit;
The following strategy was suggested, in order to allow some time for a big system to finish all the loading, etc...
So, the idea is to make sure I have waited for long enough for everything to be loaded, and then do my own command. Let's call it CMD() for now.
void Start()
{
StartCoroutine( TakeYourTime() );
}
IEnumerator TakeYourTime()
{
yield return new WaitForNewFrame();
yield return new WaitForNewFrame();
yield return new WaitForNewFrame();
yield return new WaitForNewFrame();
CMD();
}
But of course, Unity3D does not recognize WaitForNewFrame()!
After googling, I realized there is only WaitForEndOfFrame() available, so I replaced it in the above, thinking that it would achieve the same, but my CMD() does not take effect.
So, I am wondering if this existing command is not the same as the originally-suggested one, or if I am not waiting long enough?
yield return null;
is the command that will get the method to return on next frame and continue.
But this is no good practice as you cannot know if one , two or more frames are required.
You should have some kind of control over the flow of your program. If some actions are long and spread over several frames, provide a callback to the coroutine:
void Awake()
{
StartCoroutine(Loading(CMD));
}
private void CMD(){ //Other actions }
private IEnumerator Loading (Action action)
{
// Many long action with yield
if(action != null) { action(); }
}
If CMD() is also an IEnumerator function, you have to do another StartCoroutine() function on it, or it will not work. Based on the information available that's the only issue I can think of to explain why CMD() would not start.
If you have additional logic after that requires to wait on the completion of CMD(), you can yield return the StartCoroutine() call to pause TakeYourTime() from continuing until CMD() is completed.
void Start()
{
StartCoroutine( TakeYourTime() );
}
IEnumerator TakeYourTime()
{
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return StartCoroutine(CMD());
//Do the rest.
}
IEnumerator CMD()
{
//Do whatever.
}
If CMD() is not an IEnumerator function, then I apologize for this incorrect answer. You can troubleshoot further using Debug.Log() calls to determine where the application is getting stuck. I would put them before, after, and on the first line of CMD()
From your comments, though, I would recommend you do something else.
You mention that when you wait longer, it works. That means you're just waiting on something to complete, and there's no issue with methods firing.
You should do something like this instead:
IEnumerator TakeYourTime()
{
while(!otherThingIsFinished())
{
yield return new WaitForEndOfFrame();
}
CMD();
}
otherThingIsFinished() should be a call to check to see if the stuff you're waiting for has completed whatever it's doing. You can have a public method that you can call that checks some private boolean that gets set when it's completed.
You can also just have the other stuff call this method directly, although that may not be the best option either. It all depends on what exactly you're trying to do.
I have an Applet (AWT technology) running in Java Web Start. If the Web Start window closes, I need to perform some cleanup before the applet shuts down. Neither the overridden stop() nor the destroy() methods are executed. Any ideas how to force cleanup when Web Start is closed?
Implement the methods for the java.awt.event.WindowListener Interface and perform the cleanup somewhere in the windowClosing / windowClosed events. Leave those methods empty that you don't need.
Then find the top frame using something like
public Frame getFrame()
{
Container c = this;
while(c != null)
{
c = c.getParent();
if (c instanceof Frame)
{
appletFrame = (Frame)c;
break;
}
}
return appletFrame;
}
and add your window listener by appletFrame.addWindowListener(. . .);
I wish to Show progress of a long running operation(process) in UI, so that the user can understand the status of the background job. This is the way I have implemented and I feel like the code is absurd. Below is my code
dialog.run(true,false, new IRunnableWithProgress() {
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.beginTask("Main process", 10);
for (int i = 0; i < 10; i++) {
if (monitor.isCanceled()) return;
monitor.subTask("Status message");
sleep(1000);
// worked increases the monitor, the values are added to the existing ones
monitor.worked(1);
if(i == 3) {
sleep(3000);
callMe();//calling a long running function
}
if(i == 9) {
monitor.subTask("finishing setup..... please wait ");
sleep(2000);
}
}
monitor.done();
}
});
Note: There is a sleep method somewhere in the code
here at i == 3 an operation/function is called that takes a minimum of 5 minutes, post execution of the function the progress continues.
I don't want the progress to be stopped while executing the function(long running operation) rather progress must be shown even while executing it.
can someone show the correct programming practices in showing progress
The reason your code feels absurd is that wrapping the long-running method in a IRunnableWithProgress.run() really does not add much in itself, there is no magic.
To make the ProgressMonitorDialog (or e.g. the related Job API) work for you, you need to change "callMe()" so it takes "IProgressMonitor monitor" as a parameter, and use that to listen for cancel-requests, and use it also for reporting progress.
To say the same again, using different wording: You need to recursively add "IProgressMonitor monitor" as a parameter to all long-running method calls. All long-running operations must be build with this (IProgressMonitor) in mind if any progress is to be reported and/or you want it to be cancelable.
How can i capture all user raised events in my application, is there any specific event which is parrent for all of user based(raised) events ?
eg :
mouse click,
key press,
etc.,
these all events are raised by user can i able to capture it under one method???
In one single method: yes.
You have to implement the DefWindowProc function, which handles all events and messages. Unfortunately, not just user generated events but all. But you should be able to filter those out easily.
Use the SetWindowsHookEx API to set up a thread-local WH_CALLWNDPROC hook. See the MSDN documentation for full details.
That will call a single function in your application for every message you receive from Windows.
If you're using Windows forms .NET, add the following to your main application form:
protected override void OnControlAdded(ControlEventArgs e)
{
e.Control.Click += new EventHandler(Control_Click);
e.Control.KeyDown += new KeyEventHandler(Control_KeyDown);
base.OnControlAdded(e);
}
void Control_KeyDown(object sender, KeyEventArgs e)
{
// Hande all keydown events, sender is the control
Debug.WriteLine( sender.ToString() + " - KeyDown");
}
void Control_Click(object sender, EventArgs e)
{
// Hande all click events, sender is the control
Debug.WriteLine(sender.ToString() + " - Click");
}
protected override void OnControlRemoved(ControlEventArgs e)
{
e.Control.KeyDown -= Control_KeyDown;
e.Control.Click -= Control_Click;
base.OnControlRemoved(e);
}
Just add any extra events you require (such as KeyPress, MouseEnter, MouseDown etc) in a similar manner. This is a bit cleaner and simpler then delving into the Windows API.