2017-04-11 176 views
0

好吧,我明白,我不應該有這樣的循環JFrame的GUI凍結+幻影

while (pidInfo.contains(<processname>)){ 
    pidInfo =""; 
    check<processname> =Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"tasklist.exe"); 
    input = new BufferedReader(new InputStreamReader(check<processname>.getInputStream())); 

    while ((line = input.readLine()) != null) { 
     pidInfo+=line; 
    } 

    input.close(); 

    if (pidInfo.contains(<processname>)){ 
     System.out.println("<processname> RUNNING"); 
    } 
    else if (closeReason == 2){ 
     System.out.println("<processname> STOPPED VIA PROG & USER"); 
     status = "Not Running"; 
     int ll = JOptionPane.showOptionDialog(null, "<processname>", "Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, null); 
     if (ll == JOptionPane.OK_OPTION){ 
      //frame.setAlwaysOnTop(true); 
      frame.dispose(); 
     } 
    } 
    // TODO: Other exit 
} 

基於其他問題

我不明白爲什麼當我推出這個框架(這是第二個)從第一個它凍結,但如果我分別啓動第二個框架它顯示。

我希望從這個問題外賣兩件事情

1:如何編寫代碼的東西(?threadworker),其在後臺運行的循環。

2:爲什麼當我從第一幀啓動它不會凍結(見下文)

預先感謝您&這裏是第一幀代碼

if(pidInfo.contains(<processname>)) { 
    frame.setAlwaysOnTop(false); 
    status = "Running - In Game"; 

    System.out.println("<processname>1st RUNNING"); 
    int a = JOptionPane.showOptionDialog(null, "SUCCESS!", "Success", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null); 
    if (a == JOptionPane.OK_OPTION) { 
     frame.dispose(); 
     new 2ndFrameRunning(); 
    } 
} 

的2ndFrameRunning是第二個框架,它已改變它的實際名稱,所以這就是爲什麼它是打破了Java語法規則。

沒有錯誤,以及只是「幻影」凍結。

示例代碼

幀1:命名爲 「menu.java」

/* Stack Overflow 
* By Rabbitmcv 
*/ 
package main; 
// Imports 
import java.awt.event.*; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.awt.*; 
import javax.swing.*; 

public class Menu implements ActionListener{ 
    // Func 
    // Creates the JFrame 
    JFrame frame = new JFrame(); 
    // Public Vars 
    boolean isGameRunning = false; 
    String status = "Not Running - In Main Menu"; 
    // All code goes here 
     public Menu(){ 
      // Vars 
      // Frame Vars 
      frame.setResizable(false); 
      frame.setSize(800, 600); 
      frame.setLocationRelativeTo(null); 
      frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); 
      frame.setAlwaysOnTop(true); 
      // JPanels 
      JPanel defaultPanel = new JPanel(); 
      // DefaultPanel J... 
      JLabel title = new JLabel("FirstLabel"); 
      JLabel risk = new JLabel("SecondLabel"); 
      JLabel titleSub = new JLabel("StackOverflow"); 
      JButton start2frame = new JButton("start2frame"); 
      // DefaultPanel Button Code 
      start2frame.addActionListener(new ActionListener(){ 
       @Override 
       public void actionPerformed(ActionEvent arg0){ 
        System.out.println("start2frame button pressed"); 
        try{ 
         String line; 
         String pidInfo =""; 

         Process checkcs =Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"tasklist.exe"); 

         BufferedReader input = new BufferedReader(new InputStreamReader(checkcs.getInputStream())); 

         while ((line = input.readLine()) != null) { 
          pidInfo+=line; 
         } 

         input.close(); 

         if(pidInfo.contains("explorer.exe")) // The process name here has been changed from the real process for StackOverflow. 
         { 
          frame.setAlwaysOnTop(false); 
          status = "Running - In Game"; 
          frame.setTitle("StackOverflow - "+status); 
          System.out.println("1st Game RUNNING"); 
          // TODO: hackRunning 
          int a = JOptionPane.showOptionDialog(null, "SUCCESS", "Success", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null); 
          if (a == JOptionPane.OK_OPTION){ 
           frame.dispose(); 
           new second(); 
          } 
         } 
         else{ 
          isGameRunning = false; 
          status = "Not Running - ERROR: Game NOT RUNNING"; 
          frame.setTitle("StackOverflow - "+status); 
          System.out.println("game NOT RUNNING"); 
          frame.setAlwaysOnTop(false); 
          int a = JOptionPane.showOptionDialog(null, "Game is not running", "Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, null); 
            if (a == JOptionPane.OK_OPTION){ 
             frame.setAlwaysOnTop(true); 
            } 
         } 
        } 
        catch(Exception e){ 
         System.out.println("Failed to check process"); 
         e.printStackTrace(); 
        } 
       } 
      }); 
      // Set Layouts 
      defaultPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 
      defaultPanel.setLayout(new GridLayout(0, 1)); 
      // Adds the J... to a Jpanel (IN ORDER FROM TOP TO BOTTOM) 
      defaultPanel.add(title); 
      defaultPanel.add(risk); 
      defaultPanel.add(titleSub); 
      defaultPanel.add(start2frame); 
      // Center Labels 
      title.setHorizontalAlignment(JLabel.CENTER); 
      risk.setHorizontalAlignment(JLabel.CENTER); 
      titleSub.setHorizontalAlignment(JLabel.CENTER); 
      // Add the JPanel to the JFrame 
      frame.add(defaultPanel); 
      // Vis 
      frame.revalidate(); 
      frame.setTitle("StackOverflow - "+status); 
      frame.setVisible(true); 
    } 

     public static void main (String args[]){ 
      new Menu(); 
     } 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     // AUTO: Because of actionlistener 

    } 

} 

FRAME 2名爲 「second.java」

/* StackOverflow - 2nd 
* By Rabbitmcv 
* If one runs this one sans the first program it shows non-frozen... but if you run it from menu.java it will freeze... probably something with threads. 
*/ 
package main; 

// Import 
import java.awt.event.*; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.awt.*; 
import javax.swing.*; 
// This file has been renamed to 2.java 
public class second implements ActionListener{ 
    // Frame 
    JFrame frame= new JFrame(); 
    // Panel 
    JPanel panel = new JPanel(); 
    // Int 
    // closeReason: 0 = user, 1 = program, 2 = user init via prog (non-error) 
    int closeReason = 0; 
    // String 
    String status = "Running"; 
    public second(){ 
     // Set Settings 
     frame.setResizable(false); 
     frame.setSize(800, 600); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); 
     frame.setAlwaysOnTop(true); 
     // Crap 

     frame.setTitle("StackOverflow- Running"); 
     // Settings 
     // Add J... 
     JLabel label = new JLabel("Game "+status); 
     JButton closeGameButton = new JButton("Click here to close game"); 
     // Adds the J... to a Jpanel (IN ORDER FROM TOP TO BOTTOM) 
     panel.add(label); 
     panel.add(closeGameButton); 
     // Button Func. 
     closeGameButton.addActionListener(new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent arg0){ 
       try { 
        System.out.println("CloseGameButton Pressed"); 
        Process killGame = Runtime.getRuntime().exec("taskkill /F /IM explorer.exe"); // My process has been changed to explorer.exe !!!! THIS WILL STOP WINDOWS EXPLORER. Feel free to change it to another process 
        closeReason = 2; 
        int exitCode = killGame.waitFor(); 
        if (exitCode != 0){ 
         throw new IOException("Failed to kill game; game not running"); 
        } 
        frame.setTitle("StackOverflow - Not Running - Closed by user"); 
        frame.setAlwaysOnTop(false); 
        int a = JOptionPane.showOptionDialog(null, "game has been closed", "game Closed", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null); 
        if (a == JOptionPane.OK_OPTION){ 
         frame.setAlwaysOnTop(true); 
         frame.setTitle("StackOverflow - Not Running - Closed by user"); 
        } 
       } catch (Exception e) { 
        frame.setAlwaysOnTop(false); 
        System.out.println("Failed to kill game"); 
        int a = JOptionPane.showOptionDialog(null, "game is not running", "Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, null); 
        if (a == JOptionPane.OK_OPTION){ 
         frame.setAlwaysOnTop(true); 
        } 
        e.printStackTrace(); 
       } 
      } 
     }); 
     // END BUTTON FUNC 
     // Set layouts 
     panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 30, 10)); 
     panel.setLayout(new GridLayout(0, 1)); 
     // Center Labels 
     label.setHorizontalAlignment(JLabel.CENTER); 
     // Add the JPanel to the JFrame 
     frame.add(panel); 
     // end 
     frame.revalidate(); 
     System.out.println("far"); 
     frame.setVisible(true); 

     try{ 
      String line; 
      String pidInfo =""; 

      Process checkcs =Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"tasklist.exe"); 

      BufferedReader input = new BufferedReader(new InputStreamReader(checkcs.getInputStream())); 

      while ((line = input.readLine()) != null) { 
       pidInfo+=line; 
      } 

      input.close(); 

      if (pidInfo.contains("explorer.exe")){ // Changed to explorer.exe 
       System.out.println("game running - pid"); 
       status = "Running"; 
       while (pidInfo.contains("explorer.exe")){ // Changed to explorer.exe 
        pidInfo =""; 
        checkcs =Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"tasklist.exe"); 
        input = new BufferedReader(new InputStreamReader(checkcs.getInputStream())); 

        while ((line = input.readLine()) != null) { 
         pidInfo+=line; 
        } 

        input.close(); 

        if (pidInfo.contains("explorer.exe")){ // This checks if the process is still going on... changed to explorer.exe 
         System.out.println("game RUNNING"); 
        } 
        else if (closeReason == 2){ 
         System.out.println("game STOPPED VIA PROG & USER"); 
         status = "Not Running"; 
         int ll = JOptionPane.showOptionDialog(null, "game has stopped running", "Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, null); 
         if (ll == JOptionPane.OK_OPTION){ 
          //frame.setAlwaysOnTop(true); 
          frame.dispose(); 
         } 
        } 
        // TODO: Other exit 
       } 
      } 
     } 
     catch(Exception e){ 
      System.out.println("Failed to check process"); 
      e.printStackTrace(); 
     } 
    } 
    public static void main (String args[]){ 
     new second(); //StackOverflow 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // TODO Auto-generated method stub 

    } 
} 

如果不要」 t就像你可以下載.zip w /所有文件

https://drive.google.com/open?id=0BzuCgrBgpuD1V3dKLUFfQU12UWc

+0

如果沒有某種可以運行的例子來說明你的問題,那麼你就不可能提供任何類型的答案。我的猜測是,當你獨立地啓動第二幀時,循環是在「主」線程中創建的,而不是在EDT中創建的,當你從第一個啓動它時,它已經在EDT – MadProgrammer

+0

我會盡快添加一些內容。 – Rabbitmcv

+0

我現在不馬上發佈整個代碼,但我會很快發佈一個pastebin。請記住,有些事情已被重新命名。您可能必須將其重命名爲通用名稱才能運行。 – Rabbitmcv

回答

1

正如我說我的意見,當...

public static void main (String args[]){ 
    new second(); //StackOverflow 
} 

被稱爲(由JVM即,因爲你已經執行的命令行類),它正在運行在JVM的「主」線程中。

這意味着構造函數中的代碼不會在事件派發線程的上下文中執行,因此不會阻塞UI。

當您調用frame.setVisible時,底層API將創建事件分派線程,並且所有基於UI的代碼將在單獨的線程上執行,而您在構造函數中啓動的內容將在「主」線程的上下文中執行。

如果調用closeGameButtonActionListener,那麼將阻塞事件調度線程,直到killGame完成,而不管您是如何啓動代碼的。

您可以second採取同樣的方式,通過改變

public static void main (String args[]){ 
    new second(); //StackOverflow 
} 

public static void main (String args[]){ 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      new second(); //StackOverflow 
     } 
    }); 
} 

這是你應該如何啓動所有的Swing應用程序

我會建議你採取啓動看看Concurrency in SwingWorker Threads and SwingWorker

+0

很酷。我會嘗試一下代碼,並閱讀有關worker/concurrency的內容。謝謝您的幫助! – Rabbitmcv