Java FX - 无法在循环中关闭窗口

时间:2018-03-27 16:21:52

标签: file javafx directory alert

我在JavaFX中编写短程序,每隔5秒监视一次文件夹。当找到任何PDF文件时,会显示有关查找文件数的信息。一切正常,但在文件夹中是任何文件,然后我会看到窗口(这没关系),但在此之后,当我将删除文件(文件夹将为空)时,窗口仍然显示(但是不活动) 。为什么这个窗口不关闭?你知道吗? 以下是我的代码:

package testFolder;

import java.io.*;
import javafx.application.Application;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Alert;
import javafx.stage.Stage;


public class App extends Application{
    private static String searchPath;
    private File[] childrenFiles;

@Override 
public void init(){
    setPath();
}

@Override
public void start(Stage primaryStage){
    run();
}

public File[] findPDFFiles(){
    System.out.println("Find file in: " + searchPath);      
    File directory = new File(searchPath);
    File[] childrenFiles = directory.listFiles(
            (dir, name) -> {
                return name.toLowerCase().endsWith(".pdf");
            }
            );
    System.out.println("Number files: " + childrenFiles.length);        
    return childrenFiles;
}

// search folder
public void run(){              
            while (true){
                childrenFiles = findPDFFiles();                                     
                if ((childrenFiles.length > 0)){                    
                    String countFile = "Number files: " + childrenFiles.length;                                 
                    showAndWait(AlertType.INFORMATION, "FILES FOUND", countFile);  
                }

                // wait 5 seconds
                try{
                    Thread.sleep(5000); 
                }
                catch (InterruptedException iex){
                    iex.printStackTrace();
                };
            }
}

// shows window with information about number of found files
private  static void showAndWait(
        AlertType alertType,
        String title,
        String content) {
            Alert alert = new Alert(alertType);             
            alert.setTitle(title);
            alert.setHeaderText(null);
            alert.setContentText(content);
            alert.getDialogPane().setPrefWidth(800);        
            alert.showAndWait();
            }

// set folder to search files
public void setPath(){
    searchPath = "/Users/Marcin/Desktop/IN/";
    }

public static void main(final String[] args){
    launch();
}   

}

1 个答案:

答案 0 :(得分:0)

我尝试了你的代码,即使在删除所有pdf文件后它也会正常工作,它会在控制台中打印数字文件:0并且没有显示警报。 但是,我建议使用AnimationTimer而不是while(true)循环

animationTimer有一个handle方法,这是一个抽象方法,在创建AnimationTimer时必须覆盖它

内部句柄中的代码将在每一帧执行,因此它将像你的while(true)一样工作但更好

但要小心!你不能直接在AnimationTimer句柄中调用showAndWait,所以你可以通过调用Platform.runLater来完成它,这不会阻止动画计时器执行它的句柄方法

所以你可以在必须显示警报时停止animationTimer,并在警报隐藏(关闭)时重新启动它,主要是为了防止计时器在你不关闭旧警报时产生大量警报

最后一个问题是,只要没有显示javafx上下文,javafx平台就会自动关闭,所以你可以通过在start方法中将ImplicitExit设置为false来停止它!

应用了上述所有内容后,您的代码将如下所示

package testFolder;

import java.io.*;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Alert;
import javafx.stage.Stage;


public class App extends Application{
    private static String searchPath;
    private static File[] childrenFiles;
    static AnimationTimer timer;
    static long then = 0;

    @Override 
    public void init(){
        setPath();
    }

    @Override
    public void start(Stage primaryStage){
        Platform.setImplicitExit(false);
        run();
    }

    public static File[] findPDFFiles(){
        System.out.println("Find file in: " + searchPath);      
        File directory = new File(searchPath);
        File[] childrenFiles = directory.listFiles((dir, name) -> {
                return name.toLowerCase().endsWith(".pdf");
        });
        System.out.println("Number files: " + childrenFiles.length);        
        return childrenFiles;
    }

    // search folder
    public static void run(){       
        timer = new AnimationTimer() {
            long sum = 0;
            @Override
            public void handle(long now) {
                long dt = now - then;
                sum+=dt;
                if(sum/1000000 > 5000) {
                    childrenFiles = findPDFFiles();                                     
                    if ((childrenFiles.length > 0)){     
                        this.stop();
                        String countFile = "Number files: " + childrenFiles.length;                                 
                        showAndWait(AlertType.INFORMATION, "FILES FOUND", countFile);  
                    }
                    sum=0;
                }
                then = now;
            }
        };
        timer.start();
    }

    // shows window with information about number of found files
    private  static void showAndWait(AlertType alertType, String title, String content) {
        Alert alert = new Alert(alertType);             
            alert.setTitle(title);
            alert.setHeaderText(null);
            alert.setContentText(content);
            alert.getDialogPane().setPrefWidth(800);
            alert.setOnHidden(e->{
                then = System.nanoTime();
                timer.start();
            });
            Platform.runLater(alert::showAndWait);
        }

    // set folder to search files
    public void setPath(){
        searchPath = "/Users/Marcin/Desktop/IN/";
    }

    public static void main(final String[] args){
        launch(args);
    } 
}

希望这能解决你的问题