Reputation: 15
Okay I understand that I should not have this loop
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
}
based on other questions BUT
I don't understand why when I launch this frame (this is the 2nd one) from the first one it freezes but if I launch the 2nd frame separately it displays.
I hope to takeaway from this question 2 things
1: How to code the thing (threadworker?) that runs the loop in the background.
2: Why it doesn't freeze when I launch it from the first frame (see below)
Thank you in advance & here is the first frame code
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();
}
}
The 2ndFrameRunning is the 2nd frame, it has been changed from its actual name so that's why it is kind of breaking the java grammar rules.
No Errors as well just the "phantom" freeze.
EXAMPLE CODE
Frame 1: Named "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 Named "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
}
}
If you don't like that you can just download the .zip w/ all the files
https://drive.google.com/open?id=0BzuCgrBgpuD1V3dKLUFfQU12UWc
Upvotes: 0
Views: 113
Reputation: 347294
As I said in my comments, when...
public static void main (String args[]){
new second(); //StackOverflow
}
is called (ie by the JVM because you've executed the class from the command line), it is running in the "main" thread of the JVM.
This means that the code in the constructor IS NOT been executed within the context of the Event Dispatching Thread and therefore does not block the UI.
When you call frame.setVisible
, the underlying API will create the Event Dispatching Thread and all UI based code will be executed on a separate thread, leaving what you started in the constructor to execute within the context of the "main" thread.
When the ActionListener
for the closeGameButton
is called, that WILL block the Event Dispatching Thread until killGame
completes regardless of how you started the code.
You can make second
act the same way by changing
public static void main (String args[]){
new second(); //StackOverflow
}
to
public static void main (String args[]){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new second(); //StackOverflow
}
});
}
Which is how you should start ALL your Swing applications
I would suggest you start by taking a look at Concurrency in Swing and Worker Threads and SwingWorker
Upvotes: 1