2012-03-13 77 views
2

我有一個使用Swing在Eclipse中編譯的Java Applet。看到這裏:http://www.test.world2build.com/Game/Play.aspxJava Applet GUI直到小程序完成下載才顯示

對於小程序的開始,我做了一個「加載...」對話框,將登錄和下載更新。這個小程序包含三類:

  • MainApplet
  • LoadingDialog
  • 連接

MainApplet.class

public class MainApplet extends JApplet { 
public MainApplet() { 
} 
public void init() { 
    // constructor 

    setSize(800,600); 
    getContentPane().setLayout(null); 

    AppSettings AppSettings = new AppSettings(); 
    AppSettings.Username = GetParameter(0); 
    AppSettings.Password = GetParameter(1); 
    AppSettings.ClientMode = GetParameter(2); 
    AppSettings.ServerIP = GetParameter(3); 

    System.out.println("Main applet loaded."); 
    System.out.println("Starting load..."); 

    LoadingDialog load = new LoadingDialog(); 
    load.setVisible(true); 
    getContentPane().add(load); 

    int panelX = (getWidth() - load.getWidth() - getInsets().left - getInsets().right)/2; 
    int panelY = ((getHeight() - load.getHeight() - getInsets().top - getInsets().bottom)/2); 
    load.setLocation(panelX, panelY); 



    load.lblNewLabel_1.setText("Connecting..."); 

    //wait(2); 

    // UPDATE PROGRESS BAR // 
    load.progressBar.setValue(15); 

    Connect connect = new Connect(); 
    String Result = null; 
    try { 
     Result = connect.Read("http://www.world2build.com/"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    if(Result == null) { 
     return; 
    } 

    // UPDATE PROGRESS BAR // 
    load.progressBar.setValue(30); 

    load.lblNewLabel_1.setText("Checking for updates..."); 

    //wait(1); 

    String UpdatesAvailable = "null"; 

    try { 
     UpdatesAvailable = connect.Read("http://test.world2build.com/Game/CheckUpdates.aspx?v=" + AppSettings.Version); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    // UPDATE PROGRESS BAR // 
    load.progressBar.setValue(60); 

    if(UpdatesAvailable.startsWith("available")) { 
     load.lblNewLabel.setText("Updating, please wait..."); 
     load.lblNewLabel_1.setText("Downloading..."); 

     URL url; 
     try { 
      url = new URL("http://www.world2build.com/Game/WorldToBuild.zip"); 

      HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
      connection.setRequestMethod("GET"); 
      InputStream in = connection.getInputStream(); 
      FileOutputStream out = new FileOutputStream(System.getenv("APPDATA") + "download.zip"); 
      copy(in, out, 1024); 
      out.close(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (ProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    else if(UpdatesAvailable.startsWith("unavailable")) { 
     load.lblNewLabel.setText("Please wait..."); 
     load.lblNewLabel_1.setText("Logging in..."); 
     String loginStatus = null; 

     try { 
      loginStatus = connect.Read(
        "http://test.world2build.com/Game/Login.ashx?u=" 
        + AppSettings.Username + "&p=" 
        + AppSettings.Password + "&sip=" 
        + AppSettings.ServerIP); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     if(loginStatus.startsWith("success")) { 
      load.lblNewLabel_1.setText("Connecting..."); 
      load.progressBar.setValue(100); 

      // Join the game. Start game now. // 


     } 
     else if(loginStatus.startsWith("failed")) { 
      load.lblNewLabel.setText("An error occured"); 
      load.lblNewLabel_1.setText("Login failed."); 
     } 
     else { 
      load.lblNewLabel.setText("An error occured"); 
      load.lblNewLabel_1.setText("Failed to connect."); 
     } 
    } 
    else { 
     load.lblNewLabel.setText("An error occured"); 
     load.lblNewLabel_1.setText("Failed to check updates."); 
    } 
} 
public static void copy(InputStream input, OutputStream output, int bufferSize) throws IOException { 
    byte[] buf = new byte[bufferSize]; 
    int n = input.read(buf); 
    while (n >= 0) { 
     output.write(buf, 0, n); 
     n = input.read(buf); 
    } 
    output.flush(); 
} 
public static void wait(int n){ 
    long t0, t1; 
    t0 = System.currentTimeMillis(); 
    do{ 
     t1 = System.currentTimeMillis(); 
    } 
    while ((t1 - t0) < (n * 1000)); 
} 
public String GetParameter(int Index) { 
    String Parameters = null; 
    String[] Stuff = null; 

    try { 
     Parameters = this.getParameter("data"); 
     Stuff = Parameters.split(" "); 

     return Stuff[Index]; 
    } catch(NullPointerException e) { 
     e.printStackTrace(); 
    } 

    // Username   Password  ServerMode  IP 
    Parameters = "Bailey 1f6311d6446e2a3fa08a1c08187129ad false 127.0.0.1:45565"; 
    Stuff = Parameters.split(" "); 

    return Stuff[Index]; 
} } 

LoadingDialog.class

public class LoadingDialog extends JApplet { 

public JPanel frame = new JPanel(); 

public JProgressBar progressBar; 
public JLabel lblNewLabel_1; 
public JLabel lblNewLabel; 
private JPanel panel; 

public LoadingDialog() { 
    getContentPane().setFocusable(false); 
    frame.setBorder(new LineBorder(new Color(0, 0, 0))); 
    setSize(350,150); 
    frame.setSize(350,150); 
    getContentPane().setLayout(null); 
    setVisible(true); 
    progressBar = new JProgressBar(); 
    progressBar.setVerifyInputWhenFocusTarget(false); 
    progressBar.setOpaque(true); 
    progressBar.setBounds(10, 51, 322, 19); 
    getContentPane().add(progressBar); 

    lblNewLabel = new JLabel("Please wait..."); 
    lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 14)); 
    lblNewLabel.setBounds(24, 11, 308, 29); 
    getContentPane().add(lblNewLabel); 

    lblNewLabel_1 = new JLabel("Checking for updates..."); 
    lblNewLabel_1.setForeground(UIManager.getColor("InternalFrame.borderDarkShadow")); 
    lblNewLabel_1.setHorizontalAlignment(SwingConstants.RIGHT); 
    lblNewLabel_1.setHorizontalTextPosition(SwingConstants.RIGHT); 
    lblNewLabel_1.setBounds(10, 76, 322, 19); 
    getContentPane().add(lblNewLabel_1); 



    int panelX = (getWidth() - frame.getWidth() - getInsets().left - getInsets().right)/2; 
    int panelY = ((getHeight() - frame.getHeight() - getInsets().top - getInsets().bottom)/2); 
    frame.setBounds(350, 150, panelX, panelY); 

    frame.setVisible(true); 
} } 

對於一些奇怪的原因,在MainApplet那裏得到使用Connect類URL的內容(見下文),該小程序不顯示LoadingDialog GUI,直到所有的完成。

Connect.class

public class Connect { 
public String Read(String theurl) throws IOException { 
    URL url = new URL(theurl); 

    // Read all the text returned by the server 
    BufferedReader in; 
    try { 
     in = new BufferedReader(new InputStreamReader(url.openStream())); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } 
    String str = in.readLine(); 
    String newstr = "..."; 

    while(newstr != null) { 
     newstr = in.readLine(); 
     if(newstr == null) { 
      break; 
     } 
     else { 
      str += newstr; 
     } 
    } 

    in.close(); 
    return str; 
} } 
+0

*「在所有操作完成後才顯示LoadingDialog GUI。」*這可能是阻塞EDT的問題。 OTOH,你應該考慮使用[Java Web Start](http://stackoverflow.com/tags/java-web-start/info)從鏈接啓動一個框架。它支持啓動畫面。 – 2012-03-13 17:56:09

回答

2

Connect類使用阻塞I/O,這是阻止完成,直到一切都被下載後init方法。至少在init方法返回之後,Applet纔會呈現。要允許init方法快速返回,可以將資源的下載卸載到後臺工作線程。

例如,請參閱SwingWorker,它是一種實用工具類,旨在幫助在Swing GUI中正確卸載此類工作線程。它是作爲Java 6標準Java的一部分引入的。如果您需要支持Java 5,則可以找到早期版本的SwingWorker for download


另外,你可以產卵自己的線程。只要確保將GUI更新推送到AWT事件分派線程上。

public class MainApplet extends JApplet { 
    public MainApplet() { 
    } 
    public void init() { 
     // constructor 

     setSize(800,600); 
     getContentPane().setLayout(null); 

     AppSettings AppSettings = new AppSettings(); 
     AppSettings.Username = GetParameter(0); 
     AppSettings.Password = GetParameter(1); 
     AppSettings.ClientMode = GetParameter(2); 
     AppSettings.ServerIP = GetParameter(3); 

     System.out.println("Main applet loaded."); 
     System.out.println("Starting load..."); 

     final LoadingDialog load = new LoadingDialog(); 
     load.setVisible(true); 
     getContentPane().add(load); 

     int panelX = (getWidth() - load.getWidth() - getInsets().left - getInsets().right)/2; 
     int panelY = ((getHeight() - load.getHeight() - getInsets().top - getInsets().bottom)/2); 
     load.setLocation(panelX, panelY); 

     load.lblNewLabel_1.setText("Connecting..."); 

     // UPDATE PROGRESS BAR // 
     load.progressBar.setValue(15); 

     Thread thread = new Thread() { 
      public void run() { 
       Connect connect = new Connect(); 
       String Result = null; 
       try { 
        Result = connect.Read("http://www.world2build.com/"); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       if(Result == null) { 
        return; 
       } 

       // UPDATE PROGRESS BAR // 
       SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         load.progressBar.setValue(30); 
         load.lblNewLabel_1.setText("Checking for updates..."); 
        } 
       }); 

       String UpdatesAvailable = "null"; 

       try { 
        UpdatesAvailable = connect.Read("http://test.world2build.com/Game/CheckUpdates.aspx?v=" + AppSettings.Version); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       // UPDATE PROGRESS BAR // 
       SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         load.progressBar.setValue(60); 
        } 
       }); 

       if(UpdatesAvailable.startsWith("available")) { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          load.lblNewLabel.setText("Updating, please wait..."); 
          load.lblNewLabel_1.setText("Downloading..."); 
         } 
        }); 

        URL url; 
        try { 
         url = new URL("http://www.world2build.com/Game/WorldToBuild.zip"); 

         HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
         connection.setRequestMethod("GET"); 
         InputStream in = connection.getInputStream(); 
         FileOutputStream out = new FileOutputStream(System.getenv("APPDATA") + "download.zip"); 
         copy(in, out, 1024); 
         out.close(); 
        } catch (MalformedURLException e) { 
         e.printStackTrace(); 
        } catch (ProtocolException e) { 
         e.printStackTrace(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
       else if(UpdatesAvailable.startsWith("unavailable")) { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          load.lblNewLabel.setText("Please wait..."); 
          load.lblNewLabel_1.setText("Logging in..."); 
         } 
        }); 
        String loginStatus = null; 

        try { 
         loginStatus = connect.Read(
           "http://test.world2build.com/Game/Login.ashx?u=" 
           + AppSettings.Username + "&p=" 
           + AppSettings.Password + "&sip=" 
           + AppSettings.ServerIP); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 

        if(loginStatus.startsWith("success")) { 
         SwingUtilities.invokeLater(new Runnable() { 
          public void run() { 
           load.lblNewLabel_1.setText("Connecting..."); 
           load.progressBar.setValue(100); 
          } 
         }); 

         // Join the game. Start game now. // 


        } 
        else if(loginStatus.startsWith("failed")) { 
         SwingUtilities.invokeLater(new Runnable() { 
          public void run() { 
           load.lblNewLabel.setText("An error occured"); 
           load.lblNewLabel_1.setText("Login failed."); 
          } 
         }); 
        } 
        else { 
         SwingUtilities.invokeLater(new Runnable() { 
          public void run() { 
           load.lblNewLabel.setText("An error occured"); 
           load.lblNewLabel_1.setText("Failed to connect."); 
          } 
         }); 
        } 
       } 
       else { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          load.lblNewLabel.setText("An error occured"); 
          load.lblNewLabel_1.setText("Failed to check updates."); 
         } 
        } 

       } 
      } 

      Connect connect = new Connect(); 
      String Result = null; 
      try { 
       Result = connect.Read("http://www.world2build.com/"); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      if(Result == null) { 
       return; 
      } 

      // UPDATE PROGRESS BAR // 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        load.progressBar.setValue(30); 
        load.lblNewLabel_1.setText("Checking for updates..."); 
       } 
      }); 

      //wait(1); 

      String UpdatesAvailable = "null"; 

      try { 
       UpdatesAvailable = connect.Read("http://test.world2build.com/Game/CheckUpdates.aspx?v=" + AppSettings.Version); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      // UPDATE PROGRESS BAR // 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        load.progressBar.setValue(60); 
       } 
      }); 

      if(UpdatesAvailable.startsWith("available")) { 
       SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         load.lblNewLabel.setText("Updating, please wait..."); 
         load.lblNewLabel_1.setText("Downloading..."); 
        } 
       }); 

       URL url; 
       try { 
        url = new URL("http://www.world2build.com/Game/WorldToBuild.zip"); 

        HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
        connection.setRequestMethod("GET"); 
        InputStream in = connection.getInputStream(); 
        FileOutputStream out = new FileOutputStream(System.getenv("APPDATA") + "download.zip"); 
        copy(in, out, 1024); 
        out.close(); 
       } catch (MalformedURLException e) { 
        e.printStackTrace(); 
       } catch (ProtocolException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      else if(UpdatesAvailable.startsWith("unavailable")) { 
       SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         load.lblNewLabel.setText("Please wait..."); 
         load.lblNewLabel_1.setText("Logging in..."); 
        } 
       }); 
       String loginStatus = null; 

       try { 
        loginStatus = connect.Read(
          "http://test.world2build.com/Game/Login.ashx?u=" 
          + AppSettings.Username + "&p=" 
          + AppSettings.Password + "&sip=" 
          + AppSettings.ServerIP); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       if(loginStatus.startsWith("success")) { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          load.lblNewLabel_1.setText("Connecting..."); 
          load.progressBar.setValue(100); 
         } 
        }); 

        // Join the game. Start game now. // 


       } 
       else if(loginStatus.startsWith("failed")) { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          load.lblNewLabel.setText("An error occured"); 
          load.lblNewLabel_1.setText("Login failed."); 
         } 
        }); 
       } 
       else { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          load.lblNewLabel.setText("An error occured"); 
          load.lblNewLabel_1.setText("Failed to connect."); 
         } 
        }); 
       } 
      } 
      else { 
       SwingUtilities.invokeLater(new Runnable() { 
        public void run() { 
         load.lblNewLabel.setText("An error occured"); 
         load.lblNewLabel_1.setText("Failed to check updates."); 
        } 
       }); 
      } 
     } 
     thread.start(); 
    } 
    // ... 
} 
+0

有沒有什麼辦法可以解決這個問題,而無需使用任何額外的工具? – Anonymous 2012-03-13 21:05:22

+0

@BaileyMcAfee是的。你可以產生一個新的線程。您只需要確保您想要從該線程內對GUI執行的任何更新都將使用例如AWT事件線程推送到AWT事件線程。 'SwingUtilities.invokeLater'(SwingUtilities是Java中內置的一個類)。請參閱我在答案中發佈的代碼示例。 – 2012-03-13 21:32:02

相關問題