java - JFrame 不显示内容
问题描述
我正在尝试构建一个简单的 Swing 应用程序,用于在 GUI 中插入文件路径。(我知道有 JOptionPane 可以解决这个问题,但我想在用户键入时检查插入的路径是否存在。)
我构建了一个 JFrame 并添加了一个 JTextField 和一个 JButton。它只是另一个程序的一部分,因此它应该在主程序处于活动状态时暂停。
现在,当我启动程序时,JFrame 本身会正常构建。但它不加载内容,它不可关闭,当我尝试调整窗口大小时,整个程序挂起,我不得不从 IDE 强行停止它。
该程序不会抛出任何异常。我试图插入一些日志来测试程序是否在任何时候挂起,我什至照顾了getSize()
的组件,但一切都应该是 - 除了 JFrame 的内容在屏幕上不可见。最奇怪的是,我还有另一种基本相同的方法,只是使用了其他组件——而且效果很好。
我已经搜索过类似的问题,但没有成功。有谁知道我做错了什么?
这是我的代码:
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;
}
}
解决方案
好的,感谢@camickr,我找到了一个解决方案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;
}
}
推荐阅读
- php - 标头中不允许您的域 gmail.com 来自
- excel - 索引匹配以获取具有第二个条件的日期之前的值
- azure - 计划在 Azure 上刷新 Power BI 仪表板
- bash - 在 Bash 脚本中将本地终端切换到 aws EC2 实例
- javascript - 查找每个国家/地区的大陆
- excel - 如何在 Office 365 Excel 的单元格中插入图像?
- angular - 使用 BehaviorSubject 在兄弟组件之间共享数据
- laravel - 插入与 USER 相关的两个不同模型
- tensorflow - 如何在 tensorflow(python)中调用 opencv 函数?
- api - 如何通过“guzzle”从嵌套数组生成 GET 请求的有效查询?