Hi

I need to control the gui from the application logic. So here is a simple example of what I need to do:

It starts a main thread, prompts for a value using a swing gui, while the main thread is waiting. The main thread needs to resume when the button is clicked.

I get an IllegalMonitorStateException when the gui thread tries to tell the main thread to resume because it is not the owner.

Thanks in advance.

Code:
package example.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TextInput implements Runnable {
    LockMechanism lm = new LockMechanism();
    String value = "";
    private final String prompt;

    /**
     * Get a value from a swing gui
     * 
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        String v = TextInput.getInput("Enter a number");
        System.out.println("You entered " + v);
    }

    /**
     * Start a swing gui in a new thread to prompt from a value
     *
     * @param prompt
     * @return
     */
    public static String getInput(String prompt) {
        TextInput ti = new TextInput(prompt);
        try {
            Thread t = new Thread(ti, "gui");
            try {
                ti.lm.procLock.lock();
                t.start();
                ti.lm.lock();
            } catch (InterruptedException ie) {
            } finally {
                ti.lm.procLock.unlock();
            }
        } catch (Exception ex) {
            System.err.println("Exception");
        }
        return ti.value;
    }

    /**
     * Constructor
     * 
     * @param prompt
     */
    public TextInput(String prompt) {
        this.lm = new LockMechanism();
        this.prompt = prompt;
    }

    /**
     *
     */
    public void run() {
        JLabel label = new JLabel(prompt, JLabel.LEFT);
        final JFrame frame = new JFrame();
        final JTextField jTextField = new JTextField(10);
        JButton button = new JButton("Submit");

        button.addActionListener(new ActionListener() {

            //button gets clicked
            public void actionPerformed(ActionEvent e) {
                //get the value from the textfield
                value = jTextField.getText();
                //resume main thread
                lm.unLock();
                //close the gui
                frame.dispose();
            }
        });

        Box box = new Box(BoxLayout.Y_AXIS);
        box.add(label);
        box.add(jTextField);
        box.add(button);

        frame.getContentPane().add(box);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    class LockMechanism {

        public Lock procLock = null;
        public Condition processing = null;
        public boolean canProcess;

        public LockMechanism() {
            this.procLock = new ReentrantLock();
            this.processing = procLock.newCondition();
            this.canProcess = false;
        }

        /**
         * Pause the current thread
         *
         * @throws InterruptedException
         */
        public void lock() throws InterruptedException {
            while (!canProcess) {
                processing.await();
            }
        }

        /**
         * Resume the the thread that is blocked by the lock
         */
        public void unLock() {
            canProcess = true;
            try {
                processing.signalAll();
            } catch (IllegalMonitorStateException imse) {
                System.err.println("IllegalMonitorStateException");
            } catch (Exception e) {
                System.err.println(e.getMessage());
            }
        }

    }
}