I'm trying to build a simple Swing application for inserting a file path in a GUI. (I know there's JOptionPane for this, but I want to check if the inserted path exists while the user is typing.)
I built a JFrame and added a JTextField and a JButton. It's just a part of another program, so it should pause the main program while it's active.
Now when I start the program, the JFrame itself builds up normally. But it doesn't load the content, it's not closable and when I try to resize the window, the whole program hangs up and I have to forcibly stop it from the IDE.
The program doesn't throw any Exceptions. I tried to insert some logs to test if the program hangs up at any point and I even looked after the getSize()
of the components, but everything is as it should be - except that the content of the JFrame isn't visible on the screen. The strangest thing is that I have another method that's basically the same, just with other components - and it works perfectly.
I already searched for similar problems, but without success. Does anyone have an idea what I'm doing wrong?
Here's my code:
import java.awt.BorderLayout;
import java.awt.event.InputMethodEvent;
import java.awt.event.InputMethodListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Test {
public static String showFileDirInputDialog(String title, String dir) {
boolean ready = false;
String newFile = "";
Thread windowThread = new Thread(() -> {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 150);
JTextField txt = new JTextField(dir);
frame.getContentPane().add(txt, BorderLayout.CENTER);
txt.addInputMethodListener(...); // check inserted path while typing
JButton ok = new Button("OK");
frame.getContentPane().add(ok, BorderLayout.CENTER);
ok.addActionListener((e) -> {
newFile = txt.getText();
frame.dispose();
ready = true;
});
frame.setVisible(true);
}, "window thread");
windowThread.start();
while(!ready) {
System.out.print(""); // do nothing while the window is active
}
windowThread.interrupt();
return newFile;
}
}
Okay, thanks to @camickr, I've found a solution with SwingWorker
:
package test;
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(150, 70);
JButton btn = new JButton("Start");
btn.addActionListener((e) -> {
SwingWorker<String, Void> worker = new SwingWorker<>() {
@Override
protected String doInBackground() throws Exception {
return showFileInput("Insert file path");
}
@Override
protected void done() {
try {
System.out.println(get());
}
catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
finally {
System.exit(0);
}
}
};
worker.execute();
});
frame.getContentPane().add(btn);
frame.setVisible(true);
}
static String newPath = "";
static boolean ready = false;
static String showFileInput(String title) {
Thread windowThread = new Thread(() -> {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setSize(500, 70);
JTextField txt = new JTextField("");
frame.getContentPane().add(txt, BorderLayout.CENTER);
JButton okButton = new JButton("OK");
okButton.addActionListener((e) -> {
newPath = txt.getText();
frame.dispose();
ready = true;
});
frame.getContentPane().add(okButton, BorderLayout.EAST);
Timer checkInputTimer = new Timer("check input thread");
checkInputTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
File f = new File(txt.getText());
okButton.setEnabled(f.exists());
}
}, 0, 300);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
newPath = txt.getText();
frame.dispose();
ready = true;
}
});
frame.setVisible(true);
}, "window thread");
windowThread.start();
while(!ready) {
System.out.print("");
}
windowThread.interrupt();
return newPath;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.