showandwait changing variable value - variables

I'm having a problem with a variable I'm using to track the status of a user activity. In a GUI I have a button that, on clicking the button launches a second GUI. In that GUI, the user can either complete the activity started in the first GUI or not.
If the user cancels the second GUI, then the idea is to go back to the first GUI, leaving all variables and lists with their current values. If the second GUI completes the activity of the first GUI, then all variables and lists should be reset.
To track this, I have a variable (Boolean complete) initially set to FALSE. In the second GUI, when the "OK" button is clicked (rather than the "Cancel" button), the second GUI calls a method in the first GUI, changing the value of "complete" to TRUE.
To see what the heck is going on, I have System.out.println at several points allowing me to see the value of "complete" along the way. What I see is this:
Launching first GUI - complete = FALSE
Launching second GUI - complete = FALSE
Clicking "OK" in second GUI - complete = TRUE
Second GUI closes itself, returning to complete first GUI activity
First GUI finishes activity with complete = FALSE
I'm assuming it is because I am launching the second GUI with a showandwait, and when the method containing the showandwait begins, the value of "complete" = FALSE. The value changes in the WAIT part of show and wait, then the method continues and that is where I get the value still being FALSE, though it was changed to TRUE.
Here is a summary of the code in question (if you need exact code, it's longer, but I can post on request):
completeButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
try {
System.out.println("b4 calc = " + complete); // complete = FALSE
// all the code to create the calcStage
calcStage.showAndWait(); // second GUI, which calls a method in THIS
// class that changes complete to TRUE. That method
// (in THIS file) also has a println that shows the change.
getComplete(); // tried adding this method to check the value of
// "complete" after the change made by the calcStage
// (which calls a method in this same file)
System.out.println("Complete? " + complete);
// this shows complete = FALSE,
// though in the calcStage it was changed to TRUE
if (salecomplete) {
// code that should reset all variables and lists if the activity was completed
}
}
}
}
The question here is why does the second GUI successfully change the value of "complete", but when I return to the first GUI it still sees complete as FALSE? And how can I get around this?

Try having the controller of the second GUI calling a method in the first GUI's controller to modify that complete variable
For example:
// Code to handle the OK button being pressed
#Override
public void handle(ActionEvent t) {
// Do validation and work
//reference to the first controller object
firstController.setComplete(true);
}

Related

chromeless- Clicking on an element in the next page is not working

On one of my tests I log in and move to the next page.
In the next page when I try to click on the profile element with .click nothing seems to be happening.
When I use the .exists function it returns false.
Why can't chromeless recognize element after changing the DOM?
async func(){
try {
this.chromeless
.goto(this.url)
.click(this.switchToLogIn)
.type(this.email, this.emaillAddressInput)
.type(this.password, this.passwordInput)
.click(this.logInButton )
.click(this.myProfile)
.screenshot()
}
catch(err) {
console.log(err)
}
Anything that was not already available in the DOM tree when the previous action in the chain was performed (with the exception of goto() and possibly some other methods) has to be waited for using the wait() method.
So, assuming that this.myProfile is a CSS selector string for an element to be clicked:
// Unchanged code omitted
.click(this.logInButton)
// Since the previous click loads a new page and/or shows new content, we need to wait
.wait(this.myProfile)
.click(this.myProfile)
Alternatively, the implicitWait Chromeless constructor option could be set to true, as long as that does not affect anything else negatively.

Cannot enable a Ribbon button programmatically

I developed a VSTO 4 add-in for Excel. It works perfect, however, I have a button placed in the custom tab of its Ribbon control that is initially disabled.
After clicked other ribbon button in my custom tab, I need to enable the initially disabled button.
I tried with:
btnCancelar.Visible = true;
In the Click event of a button, but button is not shown. The strange thing is that when debugging, it still does not appear, but if a MessageBox is shown, the button get visible at last.
I don't understand this behaviour. How can I enable or disable a ribbon button dynamically by code?
I'm not sure what your language is used in your project, but I guess you can tranform it to your own language used. I'll show the example here in C#:
First you need to implement a so called Callback function in the RibbonXML definition:
<button id="buttonSomething" label="Content" size="large" getVisible="EnableControl"/>
then the next step is to implement the Callback function:
public bool EnableControl(IRibbonControl control)
{
return true; // visible ... false = invisible
}
VSTO will trigger the getVisible Callback and depending on the return value enable or disable the visible state (don't forget to remove any Visible property from the RibbonXML, otherwise the Callback is not triggered)
In case of the Ribbon Designer you need to make sure your Click signature is correct, the easies way to do that is by double clicking the button on the ribbon designer. This will create the Click method for you, for instance:
I created a Ribbon with the Ribbon designer and added two buttons. Double clicked the first button to get an empty method like below, and added the code.
private void button1_Click(object sender, RibbonControlEventArgs e)
{
// Toggle button visibility and make sure the button is enabled
// Visible (obviously) makes it visible, while Enabled is grayed if
// false. You don't need this it is Enabled by default, so just for
// demo purposes
button2.Visible = !button2.Visible;
button2.Enabled = button2.Visible;
// Force Ribbon Invalidate ...
this.RibbonUI.Invalidate();
// Long running proces
}
This worked perfectly for me, so if it doesn't work for you please provide more details of your coding.
I have created a workaround to this.
It was simple. Just started the long running process in different thread. That way, cancel button is shown when it should and then hidden after the process ends.
I used this code to launch the process in the Ribbon.cs code:
btnCancelar.Visible = true;
Action action = () => {
Formatter.GenerateNewSheet(Formatter.TargetType.ImpresionEtiquetas, frm.CustomerID, workbook, btnCancelar);
};
System.Threading.Tasks.Task.Factory.StartNew(action);
And inside the process method I have this code:
public static bool GenerateNewSheet(TargetType type, string customerID, Excel.Workbook workbook, Microsoft.Office.Tools.Ribbon.RibbonButton btnCancelar)
{
try
{
_cancelled = false;
InfoLog.ClearLog();
switch (type)
{
case TargetType.ImpresionEtiquetas:
return GenerateTagPrinting(customerID, workbook);
}
return false;
}
finally
{
btnCancelar.Visible = false;
}
}
The interesting thing here I have discovered is that Excel is thread safe, so it was not necessary to add a synchronization mechanism neither when adding rows in the new sheet nor when setting Visible property to false again.
Regards
Jaime

how to see mouseReleased() event outside canvas using processing.js

I have an object I want to drag around the screen with the mouse in Processing. I set acquired to true on mouse down over the object, and to false on mouse up, thus:
void mousePressed() {
if (overThing()) {
acquired = true;
}
}
void mouseReleased() {
acquired = false;
}
I then query acquired in my update(), and drag the object if it is true.
void update() {
\\ other stuff...
if (acquired) {
\\ drag thing code ...
}
}
This all works fine in Processing. mouseReleased() gets called whether I release the mouse inside or outside the active window.
However, when I move the code to Chrome, using processing.js (v1.4.8), mouseReleased() is not called if I release the mouse outside the canvas (whether the mouse is still over the web page, or outside the browser window). So when I return the (now unclicked) mouse to the canvas, the object is still getting dragged around.
I tried including a test of mousePressed in update(), but that also returns true in these circumstances.
Any help on what I need to do to make mouse state changes outside the canvas visible with processing.js?
I don't know about Processing specifically, but releasing mouse buttons outside a widget is a common issue in GUI development.
I suspect that you have no way of knowing the precise time when the mouse is released outside the widget, but you do have two options:
Set acquired = false in mouseOut(), as #Kevin suggests.
I assume there is some type of mouseEntered() method in Processing, and also some way of knowing if the mouse button is currently pressed (either a global variable, or an event object passed to mouseEntered()). You can catch the mouse entered event, check if the mouse has been released, and set acquired = false then.
Like so:
void mouseEntered() {
if (mouse button is pressed) {
acquired = false;
}
}
Edit: From your comments, #Susan, it seems like there is a bug in processing.js, where mousePressed is not set to false if the mouse button is released outside the canvas. One thing pointing to this being a bug is that the mouse movement example on the processing website also shows this behaviour.
Depending upon how much control you have over the website this is going on, and how much effort you want to go to, you could fix the bug yourself by writing some javascript (separate from your processing code):
Define a mouseUp() event on the page <body>, to catch all mouse release events on the page.
In the mouseUp() event, check if the event comes from your Processing control. (There is probably an event object passed to the mouseUp() function, and you might have to give your Processing control an ID to identify it)
If the event doesn't come from your Processing control, then fire a mouseUp event yourself, on the Processing control. This should (hopefully!) trigger a mouse event inside your Processing code.
I'm not sure what Processing will make of the mouse (x,y) position being outside its control when it handles the event you send it. You might want to set a flag on the event object (assuming you can add extra data to the event object) to say "don't use the (x,y) position of this event - it's outside the control".
Edit2: It was easier than I thought! Here is the JavaScript code to detect the mouse being released outside of the Processing canvas and send the mouseReleased event to the canvas. I've tested it on the mouse movement example from the Processing website, and it fixes the bug.
It uses jQuery (although it could be re-written to not use jQuery), and it assumes your Processing canvas has the ID "processingCanvas":
$(':not(processingCanvas)').mouseup(function(){
Processing.getInstanceById('processingCanvas').mouseReleased();
});
To use this code, include it anywhere in your page (in a JavaScript file or in <script> tags) and make sure you have the jQuery library included before this code.
The Processing object allows JavaScript to call any functions defined in your Processing code. Here I've used it to call Processing's built in mouseReleased() function, but if you wanted to call a custom function to handle the mouse-released-outside state differently, then you could.
You should use the mouseOut() function to detect when the mouse leaves the sketch:
void mouseOut() {
acquired = false;
}
More info in the reference here.

MessageBox.Show in App Closing/Deactivated events

I have a MessageBox being shown in Application Closing/Deactivated methods in Windows Phone 7/8 application. It is used to warn the user for active timer being disabled because app is closing. The App Closing/Deactivated events are perfect for this, because putting logic in all application pages would be a killer - too many pages and paths for navigation. This works just fine - message box displays OK in WP7.
I also know for breaking changes in the API of WP8. There it is clearly stated that MessageBox.Show in Activated and Launching will cause exception.
The problem is that in WP8 the message box does not get shown on app closing. Code is executed without exception, but no message appears.
P.S. I've asked this on MS WP Dev forum but obviously no one knew.
Move the msgBox code from the app closing events and into your main page codebehind. Override the on back key press event and place your code there. This is how it was done on 7.x:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if (MessageBox.Show("Do you want to exit XXXXX?", "Application Closing", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
{
// Cancel default navigation
e.Cancel = true;
}
}
FYI - On WP8 it looks like you have to dispatch the MsgBox Show to a new thread.
This prompts the user before the app ever actually starts to close in the event model. If the user accepts the back key press is allowed to happen, otherwise its canceled. You are not allowed to override the home button press, it must always go immediately to the home screen. You should look into background agents to persist your timer code through suspend / resume.
Register BackKeyPress event on RootFrame.
RootFrame.BackKeyPress += BackKeyPressed;
private void BackKeyPressed(object sender, CancelEventArgs e)
{
var result = (MessageBox.Show("Do you want to exit XXXXX?", "Application Closing", MessageBoxButton.OKCancel));
if (result == MessageBoxResult.Cancel)
{
// Cancel default navigation
e.Cancel = true;
}
}

Using of RaiseCanExecuteChanged

I make two methodes like this:
private void Next(string argument)
{
Current = Clients[Clients.IndexOf(Current) + 1];
((DelegateCommand)NextCommand).RaiseCanExecuteChanged();
}
private void Previous(string argument)
{
Current = Clients[Clients.IndexOf(Current) - 1];
((DelegateCommand)PreviousCommand).RaiseCanExecuteChanged();
}
and bind to the xaml:
Every thing work fine. And the next button becomes inactive/grey out when it hits the last post.
The problem is it (the Next button) still inactive when I click the Previous button. The Next button becomes inactive all the time.
My question is how I could make the Next button active again? Thank for all help.
I assume you are talking about a WPF Application.
There are several reasons your button could become / stay inactive:
Your CanExecute implementation is faulty and returns false even if it should return true
You didnt implement CanExecute or didnt hook it up correctly
The CommandManager didn't realize it's time to requery the commands
You've got a problem with the Focus on your Window / Control
You need to show more of the code so it gives us a broader picture of what you are trying to do.