微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JFrame 不显示内容

如何解决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());
                }
            },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;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。