Prompt for value in swing thread
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());
}
}
}
}
Re: Prompt for value in swing thread
Can you explain what you are trying to achieve as this seems like a hellishly complex way of getting the main thread to wait for a value to be input.