Search code examples
javaswingjframejdialog

How to pass inputted data from JDialog to parent JFrame when user clicks button in JDialog?


How do I pass user-inputted date from a JDialog to the parent JFrame when the user clicks a certain button in the JDialog?

Here's how I want the program to work: When the user clicks a button in the JFrame, a JDialog pops up. The user then enters some data of various types (string and integer). If the user clicks an "Add Task" button, the data is passed back to the original JFrame, which will display the data, and the JDialog closes. If the user clicks the "Cancel" button, the data is discarded and the JDialog closes.

I thought about using JOptionPane, but I don't think it allows for data of various types. I thought about creating a method in the JFrame and calling it from the JDialog, but I don't know how to reference the JFrame. I thought about creating a variable in the JDialog, but I don't know to stop the JDialog from immediately passing an empty variable to the JFrame.

Any help?

Code for JFrame:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Dialog.ModalityType;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.JDialog;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class MainInterface extends JFrame {

    private JPanel contentPane;

    public MainInterface() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 400, 800);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        
        JButton addTask = new JButton("Add");
        addTask.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                NewTask newTask = new NewTask();
                newTask.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                // Set window title
                newTask.setTitle("Add Task");
                newTask.setVisible(true);
            }
        });
        addTask.setBounds(0, 728, 97, 25);
        contentPane.add(addTask);
        
        JButton modifyTask = new JButton("Modify");
        modifyTask.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                
            }
        });
        modifyTask.setBounds(95, 728, 97, 25);
        contentPane.add(modifyTask);
        
        JButton deleteTask = new JButton("Delete");
        deleteTask.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                
            }
        });
        deleteTask.setBounds(190, 728, 97, 25);
        contentPane.add(deleteTask);
        
        JButton settingMenu = new JButton("Settings");
        settingMenu.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Setting settings = new Setting();
                settings.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                settings.setVisible(true);
                settings.setTitle("Settings");
            }
        });
        settingMenu.setBounds(285, 728, 97, 25);
        contentPane.add(settingMenu);
    }

}

The JFrame is launched by another class, so it doesn't have a main method.

Code for JDialog:

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import org.omg.CORBA.PUBLIC_MEMBER;

import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.JTextField;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.JSpinner;
import java.awt.event.ActionListener;
import java.util.jar.Attributes.Name;
import java.awt.event.ActionEvent;

public class NewTask extends JDialog {

    private final JPanel contentPanel = new JPanel();
    private JTextField taskName;

    public NewTask() {
        setBounds(100, 100, 450, 600);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(null);
        {
            JLabel lblNewLabel = new JLabel("Name:");
            lblNewLabel.setBounds(24, 13, 38, 16);
            contentPanel.add(lblNewLabel);
        }
        {
            taskName = new JTextField();
            taskName.setBounds(79, 10, 304, 22);
            contentPanel.add(taskName);
            taskName.setColumns(10);
        }
        
        JLabel lblNewLabel_1 = new JLabel("Time Required:");
        lblNewLabel_1.setBounds(24, 58, 97, 16);
        contentPanel.add(lblNewLabel_1);
        
        JSpinner hourSpinner = new JSpinner();
        hourSpinner.setBounds(125, 55, 44, 22);
        contentPanel.add(hourSpinner);
        
        JLabel lblNewLabel_2 = new JLabel("hours");
        lblNewLabel_2.setBounds(175, 58, 44, 16);
        contentPanel.add(lblNewLabel_2);
        
        // Set maximum value for minutes to 59
        int min = 0;
        int max = 59;
        int step = 1;
        int i = 1;
        SpinnerModel value = new SpinnerNumberModel(i, min, max, step);
        JSpinner minuteSpinner = new JSpinner(value);
        minuteSpinner.setBounds(225, 55, 44, 22);
        contentPanel.add(minuteSpinner);
        
        JLabel lblNewLabel_3 = new JLabel("minutes");
        lblNewLabel_3.setBounds(281, 58, 56, 16);
        contentPanel.add(lblNewLabel_3);
        
        JLabel lblNewLabel_4 = new JLabel("Deadline:");
        lblNewLabel_4.setBounds(24, 108, 56, 16);
        contentPanel.add(lblNewLabel_4);
        {
            JPanel buttonPane = new JPanel();
            buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
            getContentPane().add(buttonPane, BorderLayout.SOUTH);
            {
                JButton addButton = new JButton("Add Task");
                addButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        dispose();
                    }
                });
                addButton.setActionCommand("OK");
                buttonPane.add(addButton);
                getRootPane().setDefaultButton(addButton);
            }
            {
                JButton cancelButton = new JButton("Cancel");
                cancelButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        // Close dialog window
                        dispose();
                    }
                });
                cancelButton.setActionCommand("Cancel");
                buttonPane.add(cancelButton);
            }
        }
    }
    
}

Solution

  • I thought about creating a method in the JFrame and calling it from the JDialog, but I don't know how to reference the JFrame.

    Even though this could be a nice solution, referencing the object who called the method is very discouraged. See why (first answer): How to find the object that called a method in Java

    One possible approach would be to create a method in the JFrame and adding a JFrame as a parameter for your newTask() function. Then, when invoking newTask() you pass this as an argument: newTask(this); .

    Inside the modified newTask(JFrame frame) method, you just use the argument passed to reference the method in the parent JFrame.

    This might seem the same as referencing the object who called the method, but it's not. Here you are passing as an argument the parent JFrame, which may not always be the object which invoked the method.

    I hope I was clear enough, have a nice day!