How can I return a value from a JDialog box to the parent JFrame?

I have created a modal JDialog box with a custom drawing on it and a JButton. When I click the JButton, the JDialog box should close and a value should be returned.

I have created a function in the parent JFrame called setModalPiece, which receives a value and sets it to a local JFrame variable.

The problem is that this function is not visible from the JDialog box (even though the JDialog box has a reference to the parent JFrame).

Two questions: 1) Is there a better way to return a value from a JDialog box to its parent JFrame?

2) Why can't the reference to the JFrame passed to the JDialog be used to access my JFrame function setModalPiece?


Solution 1:

I generally do it like this:

Dialog dlg = new Dialog(this, ...);
Value result = dlg.showDialog();

The Dialog.showDialog() function looks like this:

ReturnValue showDialog() {
    setVisible(true);
    return result;
}

Since setting visibility to true on a JDialog is a modal operation, the OK button can set an instance variable (result) to the chosen result of the dialog (or null if canceled). After processing in the OK/Cancel button method, do this:

setVisible(false);
dispose();

to return control to the showDialog() function.

Solution 2:

You should do the opposite by adding a custom method getValue() to your custom JDialog.

In this way you can ask the value of the dialog from the JFrame instead that setting it by invoking something on the JFrame itself.

If you take a look at Oracle tutorial about dialogs here it states

If you're designing a custom dialog, you need to design your dialog's API so that you can query the dialog about what the user chose. For example, CustomDialog has a getValidatedText method that returns the text the user entered.

(you can find source of CustomDialog to see how they suppose that you will design your custom dialog)

Solution 3:

I don't know if I can explain my method in a cool way... Let's say I need productPrice and amount from a JDialog whos going to get that info from user, I need to call that from the JFrame.

declare productPrice and ammount as public non-static global variables inside the JDialog.

public float productPrice;
public int amount;

* this goes inside the dialog's class global scope.

add these lines in the JDialog constructor to ensure modality

super((java.awt.Frame) null, true);
setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL);

* this goes within the dialog's class constructor

let's say your JDialog's class name is 'MyJDialog' when calling do something like this

MyJDialog question = new MyJDialog();
MyJDialog.setVisible(true); 
// Application thread will stop here until MyJDialog calls dispose();
// this is an effect of modality
//
// When question calls for dispose(), it will leave the screen,
// but its global values will still be accessible.
float myTotalCostVar = question.productPrice * question.ammount;
// this is acceptable.
// You can also create public getter function inside the JDialog class,
// its safer and its a good practice.

* this goes in any function within your JFrame and will call JDialog to get infos.