I have run into a little bit of an issue that I am not real sure on what to do.
My application will have a general application stage which will present the users with their options for work - i.e. a task list, or something like that.
When the users selects one of these options, I am to navigate to window to perform the work. They would like to have the general stage open always and open a another stage for the work to be done. I can do that with:
FXMLLoader loader = new FXMLLoader();
Parent node = loader.load(this.getClass().getResource("MyView.fxml").openStream());
Scene scene = new Scene(node);
Stage stage = new Stage();
stage.setTitle("You are working on - Blah Blah Blah....");
stage.setScene(scene);
stage.show();
This provides the desired look & feel - however it appears I am running into a threading issue when modal windows are presented.
For example - in one worker window I start a service and present a ControlsFX Progress Dialog as follows:
ProgressDialog progDiag = new ProgressDialog(service);
progDiag.setTitle("Busy");
progDiag.setHeaderText("Doing the work you asked me to do....");
service.start();
Let's assume that is a server call which is retrieving a lot of data - so while this is processing, I would like to move to the other open stage to work on it. However I can't, as the UI for the entire application is blocked by this control.
Secondly let's say an error occurs on one of the stages and we present the alert:
Alert error = new Alert(AlertType.ERROR);
error.setContentText("Something bad just happened....");
error.show();
This also blocks the entire UI rather than just the stage with the issue.
Is there a way in Java FX to open the stage in a new process/thread which won't be blocked by alerts on other stages?
I was able to solve my issue by providing a reference of the stage to the controller which will show the message. I am not crazy about this, as I will need to pass that reference around, but I didn't find another way to handle that..
ProgressDialog progDiag = new ProgressDialog(service);
progDiag.setTitle(title);
progDiag.initOwner(getPrimaryStage());
progDiag.setHeaderText(message);
progDiag.initModality(Modality.WINDOW_MODAL);
service.start();
Related
I have an issue with setting value of AutomationElement by using method ValuePattern.SetValue().
Everything works just fine until some dialog appears. When the dialog appears the code execution got stuck. No exception is thrown. After the dialog is confirmed, the code exection continues. Bellow is a sample of the code:
BasePattern basePattern = null;
ValuePattern valuePattern = null;
AutomationElement elementA = Window.GetElement(SearchCriteria.ByText(propertyName));
object patternObjectA = null;
elementA.TryGetCurrentPattern(ValuePattern.Pattern, out patternObjectA);
basePattern = (BasePattern)patternObjectA;
valuePattern = (ValuePattern)patternObjectA;
valuePattern.SetValue(optionToSet);
// Window.GetElement() is a method from TestStack.White framework
// The code execution got stuck on the last line until the dialog is confirmed
Is there any other way to set AutomationElement value?
Is somehow possible to avoid of getting stuck by dialog?
I'll by grateful for any help.
Thanks advance.
It could be that this dialog is not supporting UI Automation correctly or that you simply target the wrong element.
To verify that you may use Inspect.exe from Microsoft or similiar tools.
If it works, check if you really target the correct component with your code again.
If it does not work and:
if you are able to change the application
you can change the so called AutomationPeer of the UI component - here is a link for more infos
Or simply use another UI component that supports UI Automation correctly.
if you are not able to change the application, and also do not need to run in background, parallel, etc.. you might just focus the component (call setFocus() onto the AutomationElement, or expand it (via IsExpandCollapsePatternAvailable or simulated MouseClick onto the components coordinates)) and then use the SendKeys.SendWait("test") method.
EDIT: There is one more thing you should have a look at, and I wonder why I didn't mentioned it in the first place: Register to UI Automation Events
For example you could register a callback for the Structure change event type, and check if the dialog you talk about appeared.
If so --> click the confirmed button of the dialog.
Probably you will have to synchronize your execution, so that every further action in the UI Automation script waits until the registered callback got executed and the confirmed button got clicked.
I'm studying with AOSP, and I found ActivityStack and TaskRecord in "ActivityStack" Class. There is explanation In https://developer.android.com/guide/components/tasks-and-back-stack , Back-stack(=Activity Stack) And Task seems similar to me... What is the the difference between ActivityStack and TaskRecord?
In this https://developer.android.com/guide/components/tasks-and-back-stack,
Focus on below lines, For Task
A task is a cohesive unit that can move to the "background" when users begin a new task or go to the Home screen, via the Home button. While in the background, all the activities in the task are stopped.
For back stack
The back stack for the task remains intact—the task has simply lost focus while another task takes place. A task can then return to the "foreground" so users can pick up where they left off.
For info you can refer below links:-
What is the relationship between Task and Back stack
https://blog.mindorks.com/android-task-and-back-stack-review-5017f2c18196
https://medium.com/google-developers/tasks-and-the-back-stack-dbb7c3b0f6d4
If you think of activity back stack as two levels, it might be easier to understand the purpose of ActivityStack. Android supports launchMode and taskAffinity to put activities into different TaskRecords. But even activities are put into different TaskRecords, it keeps supporting the back button to switch back to previous activity. So when you launch activity that needs to be in new TaskRecord, then back button is pressed, it switches to top activity of previous TaskRecord. So ActivityStack is more like a TaskRecord stack, and TaskRecord is more like the activity stack inside the TaskRecord, however, general speaking, ActivityStack controls the pop up sequence, and you can say it's an indirect activity stack.
And creating ActivityStack seems to make management easier logically in multiple window environment. If you enable free form in Android, each launched window mode app has its own free form stack, and each stack has its own back stack.
My 2c.
Is it possible to disable the "Cancel" button in the progress dialog
displayed when a job is running?
I still want to maintain the functionality to show to user about progress in the job to the background. Letting the job run or
canceling it has no effect on the GUI, as it starts a task on a remote
server, which does not support cancellation/stopping the task, once started.
I cannot use setSystem(true) since I want to show the progress to the user.
There is bug reported even in Eclipse Bugzilla but there isnt any update
https://bugs.eclipse.org/bugs/show_bug.cgi?id=155479
Trying to figure out if this issue is fixed or not.
If not how do we handle such scenario.
Any help appreciated.Thank you.
That bug is still open and has not been fixed.
I think the nearest you can get is to use ProgressMonitorDialog to run an IRunnableWithProgress class. You can set the cancelable state of ProgressMonitorDialog.
Something like:
ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
dialog.setCancelable(false);
dialog.run(true, true, runnableWithProgress);
I have this code for creation of secondary tile:
var logo = new Uri( "ms-appx:///Assets/Square150x150Logo.png" );
var tile = new SecondaryTile( "TileID", "Tile Text", "ActivateChange", logo, TileSize.Default );
await tile.RequestCreateAsync();
then I have code in my App's OnLaunched(LaunchActivatedEventArgs args) for checking if App was launched with "ActivateChange" arguments:
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
if (!string.IsNullOrEmpty(args.Arguments) && args.Arguments == "ActivateChange")
{
//Doing some work
this.Exit();
return;
}
...
The problem is that when I click on secondary tile then splash screen appears, after it dissappears then it does some of my work and after that it exits the app.
What I would like for it to do is that when I click on secondary tile it will trigger some background task asociated with my App and this background task will do some of my work and then changes its state to sleeping or exits. I don't know how they work. I just know that I can have background task that is running all the time and triggers periodically on some time. But can I have background task that is somehow sleeping and can be triggered from secondary tile?
Thanks!
Live tiles are only meant for starting the app. The only difference between the primary and the secondary tile is that the secondary tile can pass an additional launch argument to the application, and you are already taking advantage of that.
In my opinion, it would be a strange experience for the user anyhow, if nothing seemed to happen when he clicked on the tile. Well, even having the application automatically quit when clicking on the secondary tile (as you are doing it now) is a strange behavior, akin to application crashing unless the user knows better.
It's difficult to suggest an appropriate alternative without knowing what you are trying to achieve. There is no way to trigger a background task by a user action from outside the application. You could use the ApplicationTrigger inside the app instead of doing the work directly which would allow you to close the app sooner. You can also look at the complete list of available triggers - it's all the classes ending in Trigger on the linked page. Maybe there's one there that would work better for you.
In the application activities are stacked like this: A - > B - > C - > D - > E.
If I receive a particular notification and click on it, Activity E is started.
If I then click back (button on phone or button on actionbar), the application exit.
How do I make the transition to Activity D in this case, and then back through C, B, and A?
My code of back button:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return true;
}
Everything is okay when starting the application normally. The problem is when Activity starts from the notification.
Android has the functionality you're after built in, and it is already well documented. To begin with you should look at the TaskStackBuilder class. It was introduced in JellyBean, but is already included in the support library, and you use it to build a synthetic TaskStack which is what you need. A summary from the documentation reads:
When crossing from one task stack to another post-Android 3.0, the application should synthesize a back stack/history for the new task so that the user may navigate out of the new task and back to the Launcher by repeated presses of the back key. Back key presses should not navigate across task stacks.
TaskStackBuilder provides a way to obey the correct conventions around cross-task navigation.
How you build it is going to depend on the relationships of the Activities in your app, but the Tasks and Back Stack developers guide is a good read to help you decide, as is the Navigating with Up and Back design guide, if this is all new to you.
You'll find some code examples in the Implementing Effective Navigation lessons, also on the Android developers site, in the training section.
Incidentally, the button on the ActionBar is referred to as Up. Even though it sometimes shares the same functionality as the back button, the two are not the same (I assume that's the one you are talking about ;-) .)
I think you can solve your problem by sending an intent from Activity E to Activity D, and so on.
Therefore you should overwrite the method
onBackPressed()
that is called when you click on the back button.