1

I've read a couple of similar questions on here but none have addressed, specifically, the problem I've been having. As an idea this seems like it should be remarkably simple, in practice I have found it to be utterly impossible.

What I want to do is have a form, let's call it form A, create another form, let's call it form B, and wait for input on form B before continuing. So, you'd have your main window, press a button and another window comes up prompting you for some value, the main window then waits for the input to be entered and processed and for the input window to close, then it uses that entered value to do something else.

I know this can be accomplished because JOptionPane does exactly that, but I'm going to be using mostly numerical values and I don't want to go through the extra step of converting it. Also, it just seems like a good idea to know how to do something like this since it sounds so basic yet is proving quite difficult.

Edit: It was suggested that this may be similar to some sort of "modal" something, but I read through that and it didn't even seem at all related to what I'm asking.

Edit 2: There is a response with code that does exactly what I need, but whenever I attempt to modify it in almost any way, it ceases to function, this is what my class looks like, or at least this is the part that I'm testing, the rest of it is mostly empty methods that aren't being called yet:

public Gather(GraphWindow parent, int type)
{
    super(parent);
    parentWindow=parent;
    this.info=new String[0];
    constructType(type);
}
private void constructType(int type)
{
    msgLab=new JLabel();
    if(type==TEXT)
    {
        goText();
    }       
}

private void goText()
{
    final JTextField jtf = new JTextField();
    JButton done = new JButton("Done");

    if(info.length==0)
    {
        setTitle(TEXT_T);
        msgLab.setText(TEXT_M);
    }
    else
    {
        if(info[0].length()==0)
        {
            setTitle(TEXT_T);
            msgLab.setText(info[1]);
        }
        else if(info[1].length()==0)
        {
            setTitle(info[1]);
            msgLab.setText(TEXT_M);
        }
        else
        {
            setTitle(info[0]);
            msgLab.setText(info[1]);
        }
    }
    done.addActionListener(new ActionListener()
    {
        @Override public void actionPerformed(ActionEvent e) 
        {
            parentWindow.setText(jtf.getText());
            Gather.this.dispose();
        }

    });
    this.setLayout(new GridLayout(3,1));
    this.setSize(250, 150);

    this.add(msgLab);
    this.add(jtf);
    this.add(done);

    this.setVisible(true);
}
  • 1
    possible duplicate of [How to make a JFrame Modal in Swing java](http://stackoverflow.com/questions/1481405/how-to-make-a-jframe-modal-in-swing-java) – Mephy Jul 05 '15 at 03:19
  • 1
    [How to Make Dialogs](http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html) – MadProgrammer Jul 05 '15 at 06:11
  • More generally, see [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) – Andrew Thompson Jul 05 '15 at 11:28

1 Answers1

0

It's JDialog you need!

When you create an instance of JDialog, and make it visible, the execution of the MainWindow thread will be paused there til you close the dialog. See and run the sample code below:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class Test {
    public static void main(String[] args) {
        MainWindow mainWindow = new MainWindow();
        mainWindow.setVisible(true);
    }
}

class MainWindow extends JFrame{

    private static final long serialVersionUID = 679207429168581441L;
    //
    private static final int FRAME_WIDTH = 800;
    private static final int FRAME_HEIGHT = 600;
    private String nameFromModal;
    //
    private ModalDialog dialog;

    public MainWindow() {
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(dim.width/2-FRAME_WIDTH/2, dim.height/2-FRAME_HEIGHT/2, FRAME_WIDTH, FRAME_HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //
        JButton clickMe = new JButton("Open Modal Dialog!");
        clickMe.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dialog = new ModalDialog(MainWindow.this);
                dialog.setVisible(true);
                JOptionPane.showMessageDialog(MainWindow.this, "Name From Modal Dialog: "+MainWindow.this.getNameFromModal());
            }
        });
        //
        JPanel p = new JPanel(new FlowLayout());
        p.add(clickMe);
        MainWindow.this.add(p, BorderLayout.NORTH);
    }

    public void setValuesOfModalDialog(String name){
        this.nameFromModal = name;
    }

    public String getNameFromModal() {
        return nameFromModal;
    }
}

class ModalDialog extends JDialog{
    private static final int FRAME_WIDTH = 300;
    private static final int FRAME_HEIGHT = 300;
    private MainWindow parentWindow;
    private JTextField nameField;

    public ModalDialog(MainWindow parentWindow) {
        super(parentWindow);
        this.parentWindow = parentWindow;
        //
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(dim.width/2-FRAME_WIDTH/2, dim.height/2-FRAME_HEIGHT/2, FRAME_WIDTH, FRAME_HEIGHT);
        setModal(true);
        //
        setLayout(new FlowLayout());
        //
        JLabel nameLabel = new JLabel("Name: ");
        add(nameLabel);
        nameField = new JTextField();
        nameField.setPreferredSize(new Dimension(100, 25));
        add(nameField);
        //
        JButton submit = new JButton("Submit!");
        submit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                parentWindow.setValuesOfModalDialog(nameField.getText());
                ModalDialog.this.dispose();
            }
        });
        //
        add(submit);
    }
}

Good Luck.

STaefi
  • 4,297
  • 1
  • 25
  • 43
  • I feel obligated to point out there was one tiny mistake that is super easy to fix, but aside from that THANK YOU SO MUCH! This is a problem that's been driving me nuts for weeks and I've been going about it in entirely the wrong way, so I seriously cannot thank you enough for helping me! Thank you, thank you, thank you! – Elizabeth Enns Jul 05 '15 at 20:28
  • So no matter what I try I can't seem to replicate or modify this code in any way and still have it work. – Elizabeth Enns Jul 06 '15 at 01:19
  • @Christopher Thomas: Your Welcome, actually there is a way! ;-) Typically when an answer helps, you can accept it as an answer by checking that check mark besides the answer and vote it up if you like it. – STaefi Jul 06 '15 at 04:23
  • It won't let me upvote until I have a higher reputation apparently. I'm still having some trouble modifying the code you provided – Elizabeth Enns Jul 06 '15 at 04:39
  • It's ok. What troubles do you have? Please be more specific! – STaefi Jul 06 '15 at 06:00
  • I edited my original post with some more information, but basically when I run that code I posted, Gather is a class that extends JDialog, instead of waiting for the value the form that creates the dialog tries to use the uninitialized variable that I"m storing the information in and it come sup as "null" every time. – Elizabeth Enns Jul 06 '15 at 08:22
  • Would you please post your Full Code here, because I can not run your class based on my guesses. Don't worry we will get this to work together. – STaefi Jul 06 '15 at 11:13
  • I've uploaded both files in their simplest forms to my google drive, this is essentially what I'm trying to do but even in this form it does not work. Dialog: https://drive.google.com/file/d/0B_QDtVLpBVFyWVF5Mk1PRUdybWs/view?usp=sharing Frame: https://drive.google.com/file/d/0B_QDtVLpBVFyWWxsY0RQU2F0Uzg/view?usp=sharing – Elizabeth Enns Jul 06 '15 at 20:38
  • If you're done helping me that's cool, thanks for everything so far. If you're not, could you just let me know you're still there? – Elizabeth Enns Jul 08 '15 at 06:56
  • No Christopher, i'm not done with you. Unfortunately I'm on an emergency trip and I'll be back tomorrow. I'll never quit before I do my best for you. – STaefi Jul 08 '15 at 16:56
  • @ChristopherThomas: Do the following: 1. in the constructor of the Gather dialog add the statement setModal(true); 2. remove the statement setVisible(true); from the Gather constructor and move it to your SomeOtherFrame class in the JButton dialog's actionListener anonymous class in this way: gath.setVisible(true); The waiting feature of JDialog is depend on the fact that: in which thread you are make the dialog visible. But the Main reason your code didn't paused with opening the Gather dialog is you didn't make it Modal. Good Luck. – STaefi Jul 09 '15 at 05:47
  • BOMBSHELL! WHAT!? As if I was 1 line of code away from success! You, sir or madam, are truly amazing, thank you SO SO SO SO SO much! – Elizabeth Enns Jul 09 '15 at 06:20
  • it was nothing. Good Luck. – STaefi Jul 09 '15 at 12:27