2016-01-01 31 views
0

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

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

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不会显示,直到网络请求被称为是完整的。

回答

0

我发现我需要在另一个线程中执行网络操作。可以使用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("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