在 newtwork request/bind Maskerpane 到 Http 请求之前显示 Controlfx MaskerPane

Show Controlfx MaskerPane before newtwork request/bind Maskerpane to Http request

我希望在请求进行时显示 ControlFx MaskerPane。我在按钮操作上有此代码以发出网络请求。

if(mp==null){
        mp=new MaskerPane();
        stackPane.getChildren().add(mp);
        mp.setVisible(false);
    }
    try {

        mp.setVisible(true);            
        JSONObject verifyKey = new Network().verifyKey(pinF.getText(), phoneF.getText(), mp);
        if (verifyKey != null) {
            String string = verifyKey.getString("ans");
            mp.setVisible(false);
            if (string.equals("1")) {
                // Thanks for buying

            } else {
                error.setText("Key already used");
                error.setVisible(true);
            }
        }
    } catch (JSONException ex) {
        mp.setVisible(false);
        Logger.getLogger(Buy.class.getName()).log(Level.SEVERE, null, ex);
    }

但是我的网络 class 中的验证方法看起来像

public JSONObject verifyKey(String key, String phone, MaskerPane mp){
    this.mp=mp;
    String url = "http://theUrl";

    String httpcall = httpcall(url, "func","verify","key",key,"phone",phone,"type","eDesk");
    try {
        return new JSONObject(httpcall);

    } catch (JSONException ex) {
        Logger.getLogger(Network.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

public String httpcall(String url,String ...args) {
    try {

       // String charset = "UTF-8";  // Or in Java 7 and later, use the constant: java.nio.charset.StandardCharsets.UTF_8.name()
        String charset = java.nio.charset.StandardCharsets.UTF_8.name();
        String formatin = "";
        Object values[] = new String[args.length/2];
        int valCount =0;
        for (int i = 0; i < args.length; i+=2) {
            formatin+=args[i]+"=%s&";
            values[valCount]=URLEncoder.encode(args[i+1], charset);
            valCount++;
        }

        String query = String.format(formatin,values);
        query=query.substring(0, query.length()-1);

        //Remember to remove proxy lines before production
        //SocketAddress addr = new InetSocketAddress("127.0.0.1", 8080);
        //Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);

        URLConnection connection = new URL(url).openConnection(proxy);
        connection.setDoOutput(true); // Triggers POST.
        connection.setRequestProperty("Accept-Charset", charset);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);

        try (OutputStream output = connection.getOutputStream()) {
            output.write(query.getBytes(charset));
        }

        InputStream response = connection.getInputStream();
        //return getStringFromInputStream(response);

    } catch (UnsupportedEncodingException ex) {
        if(mp!=null)mp.setVisible(false);
        Logger.getLogger(Buy.class.getName()).log(Level.SEVERE, null, ex);
    }catch (MalformedURLException ex) {
        if(mp!=null)mp.setVisible(false);
        Logger.getLogger(Buy.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        //if(mp!=null)mp.setVisible(false);
        Logger.getLogger(Buy.class.getName()).log(Level.SEVERE, null, ex);
        //return "{\"ans\":\"1\"}";//xpectd on success
        //return "{\"ans\":\"0\",\"err\":\"1\"}";//xpectd on failure
    }
    return null;
}

问题是在调用网络请求完成之前,maskerpane 不会显示。

我发现我需要在另一个线程中执行网络操作。可以使用 Executor 服务。这些可以在 javafx concurrency package

中找到
if (mp == null) {
    mp = new MaskerPane();
    stackPane.getChildren().add(mp);
    mp.setVisible(false);
}
mp.setVisible(true);
Runnable task = () -> {
    try {

        JSONObject verifyKey = new Network().verifyKey(pinF.getText(), phoneF.getText(), mp);
        if (verifyKey != null) {
            String string = verifyKey.getString("ans");

//Updating ui from another thread need you to use Platform.runLatter... So wrapping the below with runLatter to avoid exceptions
            mp.setVisible(false);
            if (string.equals("1")) {
                // Thanks for buying

            } else {
                error.setText("Key already used");
                error.setVisible(true);
            }
        }

        Thread back = new Thread(task);
        back.setPriority(Thread.MAX_PRIORITY);
        back.setDaemon(true);
        back.start();

    } catch (JSONException ex) {
        mp.setVisible(false);
        Logger.getLogger(Buy.class.getName()).log(Level.SEVERE, null, ex);
    }

}
        // Run the task in a background thread
Thread back = new Thread(task);
back.setPriority(Thread.MAX_PRIORITY);
back.setDaemon(true);
back.start();

https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm