在新网络请求之前显示Controlfx MaskerPane/将MaskerPane绑定到Http请求



我希望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("one_answers");
            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);
    }

然而,我的网络类中的验证方法看起来像

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;
}

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

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

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("one_answers");
//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

最新更新