Java application processing GUI input when "Done" is clicked Right now, I've got this really ugly loop in my code that waits for a boolean to be true before the method can return. It's triggered when "Done" is clicked. I'm wondering, what is the proper way for me to delay this method's return until the button is pressed? How should I refactor this code so that it follows common practices for this?

Here is the relevant code. It is part of a much bigger application. This is the only place this happens because it is the only custom dialog box in the application. Everything else is done with JOptionPane, so it doesn't have this problem.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws FileNotFoundException {
        PrintWriter out = new PrintWriter("textfile.txt");
        out.println(GUI.getUserInput());
        out.close();
    }
}

class GUI implements ActionListener {

    private static boolean pressed;

    public static String getUserInput() {
        pressed = false;

        JFrame frame = new JFrame();
        frame.setSize(400, 250);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Diary");
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout(4, 2));
        JLabel instructionLabel = new JLabel("What's on your mind?");
        panel.add(instructionLabel, BorderLayout.NORTH);
        JTextArea inputField = new JTextArea("", 7, 30);
        inputField.setLineWrap(true);
        inputField.setWrapStyleWord(true);
        panel.add(new JScrollPane(inputField), BorderLayout.CENTER);
        JButton done = new JButton("Done");
        done.addActionListener(new GUI());
        panel.add(done, BorderLayout.SOUTH);
        frame.add(panel);
        frame.setVisible(true);
        inputField.setCaretPosition(inputField.getText().length());

        while (!pressed) { // Wait for the "Done" button to be pressed
            // For some reason, there has to be something in this loop for it to work
            System.out.println();
        }

        frame.dispose();
        return inputField.getText();
    }

    public void actionPerformed(ActionEvent e) {
        pressed = true;
    }
}
1 import

I suggest you don't use the wildcard in your import statements, because 


it clutters your namespace,
the maintainer of your code does not know what classes exactly you use in your code.


2 Main class

I would rename your class Main to, say, MyFrame, and declare it as a subclass of JFrame.

Summa summarum

All in all, I had this in mind:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;


public class MyFrame extends JFrame {

    private final JPanel panel = new JPanel();
    private final JLabel instructionLabel = new JLabel("What's on your mind?");
    private final JTextArea textArea = new JTextArea(7, 30);
    private final JButton button = new JButton("Done");

    public MyFrame() {
        super("Diary"); // Sets the title to "Diary".
        this.setSize(400, 250);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.panel.setLayout(new BorderLayout(4, 2));
        this.panel.add(instructionLabel, BorderLayout.NORTH);
        this.textArea.setLineWrap(true);
        this.textArea.setWrapStyleWord(true);
        this.panel.add(new JScrollPane(textArea), BorderLayout.CENTER);
        this.button.addActionListener(new MyActionListener());
        this.panel.add(button, BorderLayout.SOUTH);
        this.getContentPane().add(panel);
        centerWindow(this);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -&gt; { new MyFrame(); });
    }

    private final class MyActionListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            try (PrintWriter writer = new PrintWriter("textfile.txt")) {
                writer.println(textArea.getText());
            } catch (final FileNotFoundException ex) {

            }

            MyFrame.this.dispatchEvent(
                    new WindowEvent(MyFrame.this, WindowEvent.WINDOW_CLOSING));
        }
    }

    private static void centerWindow(final Window window) {
        final Dimension dimension = window.getSize();
        final Dimension screen    = Toolkit.getDefaultToolkit().getScreenSize();

        window.setLocation((screen.width - dimension.width) / 2, 
                           (screen.height - dimension.height) / 2);
    }
}


Hope that helps.