showBack() from Form to InteractionDialog

85 views
Skip to first unread message

P5music

unread,
Jan 11, 2021, 1:53:01 PM1/11/21
to CodenameOne Discussions
In my CodenameOne app it can happens that a InteractionDialog is displayed and from there a form is called with text inside, arranged in three areas. 
The dialog is a subclass of InteractionDialog in fact (CommandDialog), that avoids showing a form for itself.
When the second form is called from the CommandDialog it works but when the showBack command is invoked the dialog disappears.
I say "disappears" because when the form disposes itself the previous form is displayed in its previous state, including the BrowserComponent content and the CommandDialog, then the dialog disappears.
So it seems that the disappearing could be avoided.

I can open another InteractionDialog, but I would like to know what's happening, and if there is the possibility to call a form and then coming back to the CommandDialog.
Thanks in advance

Shai Almog

unread,
Jan 11, 2021, 9:41:51 PM1/11/21
to CodenameOne Discussions
You can re-show the dialog with animation disabled after the on show event. You can store state in client properties to track whether a form has a currently showing dialog.

P5music

unread,
Jan 12, 2021, 4:25:03 AM1/12/21
to CodenameOne Discussions
I think it is better for my app to create a further InteractionDialog.
When I do so I have to manage the back command on toolbar.

The user experience is to start from the main form, then call a second form and there the first dialog is displayed.

This is the code portion at the beginning of the method that shows the second dialog from the first dialog:

Toolbar toolbar=form.getToolbar();
InteractionDialog dialog=new InteractionDialog();
Command oldBackCommand=form.getBackCommand(); //no method toolbar.getBackCommand()
Command backCommand=new Command("Back") {
@Override
public void actionPerformed(ActionEvent evt) {
toolbar.setBackCommand(oldBackCommand);
form.setBackCommand(oldBackCommand);
dialog.dispose();
}
};

form.setBackCommand(backCommand);
//or
//form.setBackCommand(null);    same behaviour

toolbar.setBackCommand(backCommand);
....
....

What I get is that when the second dialog is displayed (full screen) and I would click the back button, it is the same I would click the back button on the form, so the previous form is shown back while I want to stay on the current form with the first dialog displayed.
I just wanted to dispose the second dialog to go back to the previous dialog, not the previous form.

What's wrong?

Shai Almog

unread,
Jan 12, 2021, 10:19:49 PM1/12/21
to CodenameOne Discussions
It's hard for me to tell without a debugger. Try stepping over the code to understand the flow.

P5music

unread,
Jan 13, 2021, 4:23:32 AM1/13/21
to CodenameOne Discussions
I did some debugging and it seems that the old toolbar cannot be overidden.
The last resort is to change the user experience, avoid using the toolbar but I cannot get rid of it. I used
form.getToolbar().setEnabled(false);
but the toolbar is there.



Shai Almog

unread,
Jan 13, 2021, 9:59:56 PM1/13/21
to CodenameOne Discussions
Try hideToolbar()

P5music

unread,
Jan 14, 2021, 5:04:21 AM1/14/21
to CodenameOne Discussions
So I tried hideToobar() but it does not work, the toolbar still is there.
What can be done?
Regards

Shai Almog

unread,
Jan 15, 2021, 12:31:45 AM1/15/21
to CodenameOne Discussions
try setVisible(false) and setHidden(true)

P5music

unread,
Jan 15, 2021, 4:34:38 AM1/15/21
to CodenameOne Discussions
Those instructions did not succed in hiding the toolbar.
Also, if I click the "back" button in the second dialog (InteractionDialog or CommandDialog, does not make any difference) it is disposed, but I do not see the first dialog anymore (CommandDialog).
Regards

Shai Almog

unread,
Jan 16, 2021, 1:37:20 AM1/16/21
to CodenameOne Discussions
Can you provide a screenshot and the way in which you used these APIs?

P5music

unread,
Jan 16, 2021, 11:30:13 AM1/16/21
to CodenameOne Discussions
-In regard to the dialog being disposed 
It seems that showing an InteractionDialog on top of a CommandDialog makes the await() of the latch stop,
because the CommandDialog has a transparent background InteractionDialog that consumes the mouse events, that is, it's like the mouse was clicked outside when the user interacts with the second dialog.
-In regard to hiding the toolbar it just does not happen.

Regards

Shai Almog

unread,
Jan 16, 2021, 9:41:57 PM1/16/21
to CodenameOne Discussions
Can you isolate a test case of the toolbar not hiding?

P5music

unread,
Jan 17, 2021, 7:11:37 AM1/17/21
to CodenameOne Discussions
I have to say that a subtle reference mistake made debug not reliable.
Now I fixed the reference to the form, and restored the preferred user experience (the back button on the toolbar is assigned to dispose the further InteractionDialog: the old back command of the form is replaced and after the disposal it is restored).

(the user experience is like: a form opens a second form that in turn opens a CommandDialog, that opens a further InteractionDialog when the user clicks a certain button)
I think I understand what happens:
When the CommandDialog opens a further InteractionDialog, that causes the latch in the CommandDialog to be released.
This causes the CommandDialog to dispose
and
the old back command of the form is restored so this is why using the back button on the toolbar when the InteractionDialog is on screen causes the second form to close and go back to the first form. (Indeed the old back command was already restored by the unseen disposal of the CommandDialog).

Said that now the question is
why showing the further InteractionDialog causes the latch to release?
It is not mouse events fault, indeed I see that the ActionListener is not called. (I remind you that there is a giant transparent button as background of the CommandDialog to intercept the mouse events outside the dialog)

Do you know why the latch could be released? 

P5music

unread,
Jan 18, 2021, 6:47:38 AM1/18/21
to CodenameOne Discussions
If nothing can be done for the strange releasing of the CommandDialog's latch 
[but something strange is happening because I cannot debug that point (there with a long delay)]

I think the workaround I devised is acceptable:
The method that opens the CommandDialogs will not restore the back command if the show method returns early, that is, after the further InteractionDialog has been opened (here's the latch release).
So there is no concurrent setting of the backCommand.


Then the CommandDialog is called again from inside the disposing InteractionDialog after its back command is called (now assigned to the toolbar and the form).
(the old back command was passed as a parameter to the method that opens the InteractionDialog and swiftly restored)

But
I realized that the right way is to use both

form.setBackCommand(backCommand);
and
form.getToolbar().setBackCommand(backCommand);
to set

and

form.setBackCommand(oldBackCommand);
and
form.getToolbar().setBackCommand(oldBackCommand);
to restore.

Now I see three back buttons on the toolbar.
I have to avoid this.

How do I remove the old button, or change directly its command, instead of the toolbar's one?
Thanks

P5music

unread,
Jan 18, 2021, 6:23:54 PM1/18/21
to CodenameOne Discussions
Elegant solution:

I created the class BackCommand that extends Command.
BackCommand has a member that is a runnable that will be run from the @Override actionPerformed() method.
A single instance of BackCommand is assigned to the form (and the toolbar), it does not change.
The various dialogs that can be called even one on top of the other just reference that single instance of BackCommand
and in turn change/restore only the runnable.

When a CommandDialog instance is created it performs the change/restore by its own. It is very useful around the app in many places.
But I know that opening another InteractionDialog on top of it causes the CommandDialog to release, and its show() method to return.
So when used in this special case the CommandDialog can retain from the change/restore process and delegates the restore process to the method that creates the InteractionDialog, passing the suitable runnable.

Regards
Reply all
Reply to author
Forward
0 new messages