Multiple choice dialog

194 views
Skip to first unread message

Lukas Heidbreder

unread,
Mar 27, 2023, 7:39:19 AM3/27/23
to iDempiere
Hello everyone.
I am looking for a way to promt a user to choose between a given list of options from within a button action. The only input dialog I have found is the FDialog to return a String which sounds extremely prone to error.
Any help is greatly apprechiated!

Anozi Mada

unread,
Mar 27, 2023, 11:33:50 PM3/27/23
to iDempiere
I've never use this but I think you can start with FDialog/Dialog method askForInput that accept lookup and editorType as argument.

Regards,
Anozi Mada

Anozi Mada

unread,
Mar 27, 2023, 11:43:51 PM3/27/23
to iDempiere
For the lookup you can check WInOutGen.dynInit() and see how docActionL get initiated for reference.

Lukas Heidbreder

unread,
Apr 3, 2023, 7:22:29 AM4/3/23
to iDempiere
Hi, I'm grateful for your help. The dialog is running and showing the options I want it to.. I did, however, run into another issue.

When I call my dialog to ask for user input, the UI remains frozen (until the underlying action times out, I'm coming back to that). Considering I need the input to continue working that poses a problem.
I assume this issue stems from my Callback implementation; I tried using a CompletableFuture to wait for the result. Is there a proper way to do this or am I overlooking something completely different?

Best regards!

Anozi Mada

unread,
Apr 4, 2023, 6:47:07 AM4/4/23
to iDempiere
Can you post the source code?

Lukas Heidbreder

unread,
Apr 4, 2023, 7:50:52 AM4/4/23
to iDempiere
Oh, right, I haven't, excuse me.
The full method is down below. When the timeout (for testing, second to last line) runs out, the dialog window shows up, hence I know that the window itself looks fine and the lookup works.

private int choosePrintOptionId (HashSet<Integer> options) throws Exception {

var optArr = options.toArray(new Integer[options.size()]);

String msg = Msg.getMsg(Env.getCtx(), "sbsp_printoptiondialog");

CompletableFuture<Object> future = new CompletableFuture<>();

StringBuilder validation = new StringBuilder("sbsp_printoption.sbsp_printoption_id IN (");

if (optArr.length > 0)

validation.append(optArr[0]);

for (int i = 1; i < optArr.length; i++)

validation.append(",").append(optArr[i]);

validation.append(")");

MLookup lookup = MLookupFactory.get(

Env.getCtx(),

windowno,

1000191, /*sbsp_printoption.value*/

DisplayType.TableDir,

Env.getLanguage(Env.getCtx()),

"sbsp_printoption_ID",

19, /*table direct*/

false,

validation.toString());

FDialog.askForInput(

msg,

lookup,

DisplayType.TableDir,

(obj) -> future.complete(obj),

AEnv.getDesktop(),

windowno);

Object rtn = future.get(10, TimeUnit.SECONDS);

return rtn == null ? 0 : (Integer) rtn;

}


Anozi Mada

unread,
Apr 4, 2023, 11:57:59 PM4/4/23
to iDempiere
Can you try something like this

FDialog.askForInput( msg, lookup, DisplayType.TableDir, new Callback <Object> () { @Override public void onCallback(Object result) { m_printoption = result; } }, AEnv.getDesktop(), windowno);

so instead of returning the value of selected option, you just set the selected option to a variable.

Lukas Heidbreder

unread,
Apr 5, 2023, 5:56:38 AM4/5/23
to iDempiere
Well, I have tried that but the whole action finishes, then the dialog shows up. 
It doesn't seem to matter if I use a Future or a global variable/an attribute and whether I use an anonymous type or a lambda expression (to be expected but I tried anyway).

Is there a way to force the UI thread to show the dialog at a specific point of time? Then I could try that as well

Anozi Mada

unread,
Apr 5, 2023, 7:03:12 AM4/5/23
to iDempiere
If you want to block the thread, after calling FDialog.askForInput you can check if the variable (or you can create another flag variable) is null. While it's still null you can Thread.sleep(100), so basically it will wait until the FDialog is done before continuing execution, maybe you can also add a timeout.
Though I'm not sure if it's the best practice to that use case, maybe someone can comment.

Diego Ruiz

unread,
Apr 5, 2023, 7:13:38 AM4/5/23
to iDempiere
You can try a similar approach as the one used for Input within processes.

Copying the code from that wiki:
final StringBuffer string = new StringBuffer();
 final StringBuffer stringcaptured = new StringBuffer();
 processUI.askForInput("Please enter a String:", new Callback<String>() {
@Override
public void onCallback(String result) {
addLog("You entered: " + result);
string.append(result);
stringcaptured.append("true");
}
 });
 int timeoutInSeconds = 5;
 int sleepms = 200;
 int maxcycles = timeoutInSeconds * 1000 / sleepms;
 int cycles = 0;
 while (stringcaptured.length() == 0) {
try {
Thread.sleep(sleepms);
} catch (InterruptedException e) {}
cycles++;
if (cycles > maxcycles)
throw new AdempiereUserError("Timeout waiting for user answer");
}
 String userinput = string.toString();

Lukas Heidbreder

unread,
Apr 5, 2023, 10:01:52 AM4/5/23
to iDempiere
Excuse me, I don't think I was specific enough. Halting my own thread is not the issue because that is pretty much exactly what the Future.get() (or my Debugger for that matter) does.
When I reach the line with "askForInput" in code, the little "processing" wheel in the middle of the web ui is still going on.

The first image is at the time where my code is waiting for the dialog's response, the second image is after timing out. The dialog then works completely fine, shows exactly the options I want it to and the callback works as well.
inprogress.png
afterprogress.png

Anozi Mada

unread,
Apr 7, 2023, 9:44:53 AM4/7/23
to iDempiere
So I just tried it using this code and it seems working like expected. You can check the video I attached below.

Can you make minimum code like I did to reproduce your issue?

AskInputProcess.webm

Lukas Heidbreder

unread,
Apr 11, 2023, 3:55:35 AM4/11/23
to iDempiere
Hi, thank you.
I tried that code and it works but the issue is that I for other reasons cannot use a process, the dialog has to show up inside the custom toolbar action.

I took your code, modified it like this and bound it to my toolbar button. The problem sadly persists, the UI stays frozen while the code runs.

Heng Sin Low

unread,
Apr 11, 2023, 4:01:52 AM4/11/23
to idem...@googlegroups.com
From IAction, you should call Dialog.askForInput(int windowNo, WEditor weditor, String adMessage, String title, final Callback<Object> callback) instead.

--
You received this message because you are subscribed to the Google Groups "iDempiere" group.
To unsubscribe from this group and stop receiving emails from it, send an email to idempiere+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/idempiere/2886d2c1-62ba-45d8-acd4-e82e8a2325e2n%40googlegroups.com.
Message has been deleted
Message has been deleted

Lukas Heidbreder

unread,
Apr 12, 2023, 4:23:42 AM4/12/23
to iDempiere
I tried modifying the test code from earlier to use this other method instead but the result does not seem to change.

I came to think if the problem could stem from the iDempiere version 9.1 I am using? Was the FDialog or UI handling possibly changed in version 10?
Reply all
Reply to author
Forward
0 new messages