简体   繁体   中英

JFrame doesn't show content

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM