aspose file tools*
The moose likes Beginning Java and the fly likes app doesn't exit because of JOptionPane Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "app doesn Watch "app doesn New topic
Author

app doesn't exit because of JOptionPane

Ludo Aelbrecht
Greenhorn

Joined: Oct 30, 2006
Posts: 5
Hi all,
I'm reading head first java and tried writing the guess-the-number game myself. It's just a simple game, and it works until I use JOptionPane for a parameter, instead of hard-coding it myself. To decide how many players are guessing numbers, I can use one of these:
g.startGame(Integer.parseInt(JOptionPane.showInputDialog("How many players?")));
OR:
g.startGame(4);

The second solution works fine, the first makes the game work, but it doesn't exit -- I have to kill it myself.

Here are my classes:
headclass - GuessGame



Player class



Testing class - GameTest


What am I doing wrong?
Also, I'm *very* interested in any tips concerning my code: style, breaking down in enough methodes,... and any other thing where my logic isn't good.
One thing I wanted to was create a method initPlayers(int numberOfPlayers) in my GuessGame class, so I would just call this method from my startgame() method. However, I'd have to make my array of players available to the entire class if I understand correctly, so not do a "Player p[] = new Player[numberOfPlayers];" in a method, right? But how can I do this, since I don't know the numberOfPlayers at the start of the class...
I hope my explanation is a bit clear.

Thanks!

[ I split up some extra-long code lines that were screwing up the page formatting - Jim ]
[ October 30, 2006: Message edited by: Jim Yingst ]
David O'Meara
Rancher

Joined: Mar 06, 2001
Posts: 13459

"Ludo",
Welcome to the JavaRanch.

We're a friendly group, but we do require members to have valid display names.

Display names must be two words: your first name, a space, then your last name. Fictitious names are not allowed.

Please edit your profile and correct your display name since accounts with display names get deleted, often without warning

thanks,
Dave
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Hi anonymous


your game works perfectly, a typical output is
For debugging: random number is 1.

We have a winner!
Player 0 didn't win - (s)he guessed number 0.
Player 1 didn't win - (s)he guessed number 9.
Player 2 didn't win - (s)he guessed number 5.
Player 3 has won! The number was 1.
Player 4 didn't win - (s)he guessed number 5.
Player 5 didn't win - (s)he guessed number 9.
Player 6 didn't win - (s)he guessed number 3.


Only there is an exception when you don't enter an int.

Maybe there is something weird with your development environment?



Yours,
Bu.


For other testers: "Ludo's" Game all in one to copy/paste:




all events occur in real time
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24168
    
  30

The GUI event-handling thread will keep a program from exiting when main() returns. Using any GUI components will start it, and thereafter to make the program exit, you must call System.exit(0).


[Jess in Action][AskingGoodQuestions]
sven studde
Ranch Hand

Joined: Sep 26, 2006
Posts: 148
Originally posted by Ernest Friedman-Hill:
The GUI event-handling thread will keep a program from exiting when main() returns. Using any GUI components will start it, and thereafter to make the program exit, you must call System.exit(0).

I don't get that part about System.exit(0). Could you expain further? Where would that go in this program:

And why does Sun not mention System.exit(0) is required? That program seems to exit fine on Windows.
[ October 30, 2006: Message edited by: sven studde ]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24168
    
  30

This line:

myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Arranges for a WindowEventListener to be attached to the JFrame which calls System.exit(0) when you close the window.

The original poster's program is a sort of hybrid thing which just throws up a few dialogs; when main() returns, the program won't exit by itself because the GUI thread (which is a non-daemon thread) is still running. He could just put System.exit(0) at the end of main().
sven studde
Ranch Hand

Joined: Sep 26, 2006
Posts: 148
Thanks for the explanation.
sven studde
Ranch Hand

Joined: Sep 26, 2006
Posts: 148
One thing I wanted to was create a method initPlayers(int numberOfPlayers) in my GuessGame class, so I would just call this method from my startgame() method. However, I'd have to make my array of players available to the entire class if I understand correctly, so not do a "Player p[] = new Player[numberOfPlayers];" in a method, right?


In java, you can declare and create a new array in one line like this:

int[] nums = new int[10];

But, that is a two part operation, which can be broken up into its constituent parts:

int[] nums;
nums = new int[10];

The first line declares a variable that can refer to an int array. The second line creates an array and sets nums to refer to the array. However, you don't have to write the second line immediately after the first. In other words, you can create the variable, but not assign anything to it until later:

int[] nums;
...
...
nums = new int[5];

In your case, to make a Players array available to the whole class, you can declare a data member for your class:

private Players[] p;

and then sometime later, like in an initPlayers() method, you can create a Players array and set p to refer to it:

p = new Players[5];

(Note: you might want to set p=null in the constructor for the class, so that you at least initialze p when p is created.)

Additionally, which is something I didn't know you could do in java, you can make the size of the array a variable:

p = new Players[numPlayers];

Therefore, you can set the value of the numPlayers variable equal to the user input from the JOptionsPane.

[ October 30, 2006: Message edited by: sven studde ]
[ October 30, 2006: Message edited by: sven studde ]
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Ernest Friedman-Hill posted October 30, 2006 09:54 AM

T
he original poster's program is a sort of hybrid thing which just throws up a few dialogs; when main() returns, the program won't exit by itself because the GUI thread (which is a non-daemon thread) is still running. He could just put System.exit(0) at the end of main().


But if I have only this:

it seems, that the program exits normally. It seems to exit only a second earlier if I use the system exit at the end of the main method.

Is this JVM dependent?


Yours,
Bu.
sven studde
Ranch Hand

Joined: Sep 26, 2006
Posts: 148
Also, I'm *very* interested in any tips concerning my code: style, breaking down in enough methodes,

Well, you can go too far with that as well. For instance, I think this is a case of going too far:


To me that almost seems equivalent to using a method like this:

instead of just using:

System.out.println("some string");

directly in your code. You can always wrap every java function in a function of your own, but that just creates needless overhead.

[ October 30, 2006: Message edited by: sven studde ]

[ October 30, 2006: Message edited by: sven studde ]
[ October 30, 2006: Message edited by: sven studde ]
sven studde
Ranch Hand

Joined: Sep 26, 2006
Posts: 148
Originally posted by Burkhard Hassel:
Ernest Friedman-Hill posted October 30, 2006 09:54 AM



But if I have only this:

it seems, that the program exits normally. It seems to exit only a second earlier if I use the system exit at the end of the main method.

Is this JVM dependent?


Yours,
Bu.

Your code doesn't exit for me using jdk 1.4.2_06.
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Hi all,

Sven Studde wrote
Your code doesn't exit for me using jdk 1.4.2_06.


Must be the JRE then. It exits for me if I compile it with
java -source 1.3 Main.java (and 1.4 as well)
but running it under jre 1.5.

Seems I'd have to look for differences in swing for 1.4 and 1.5

But not now, Rio Bravo is on TV now.
thread.setPriority ...

Bu.
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
Originally posted by sven studde:

Well, you can go too far with that as well. For instance, I think this is a case of going too far:


To me that almost seems equivalent to using a method like this:

instead of just using:

System.out.println("some string");

directly in your code.
Except by wrapping the method it leaves open the possibility that a different implementation may be used. Perhaps in the future you might decide to use an implementation of a Mersenne Twister instead of java.util.Random to generate random numbers, or for testing you might want to create a mock implementation which overrides the createRandomNumber() method to return a non-random predetermined number. You then only have to change a single method implementation and leave the rest of your code untouched.


Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Not to mention that moving it to a method can easily make a more complex expression much easier to understand.
Ludo Aelbrecht
Greenhorn

Joined: Oct 30, 2006
Posts: 5
Originally posted by David O'Meara:
"Ludo",
Welcome to the JavaRanch.

We're a friendly group, but we do require members to have valid display names.

Display names must be two words: your first name, a space, then your last name. Fictitious names are not allowed.

Please edit your profile and correct your display name since accounts with display names get deleted, often without warning

thanks,
Dave

Actually, Ludo is my real name - first name. Thanks for the reply, I wasn't aware of this. I've gotta say I'm kind of reluctant to use my last name - not because I want to abuse the forums or anything, I just don't want to use it too much on the 'net. I could use a fake one, but why bother. Anyway since this forum (well, its users) seems really friendly & helpful, I guess I'll abide. I'm surprised of this rule though, never saw that on any other site.
[ April 02, 2007: Message edited by: LudoA ]
Ludo Aelbrecht
Greenhorn

Joined: Oct 30, 2006
Posts: 5
Originally posted by Ernest Friedman-Hill:
The GUI event-handling thread will keep a program from exiting when main() returns. Using any GUI components will start it, and thereafter to make the program exit, you must call System.exit(0).

System.exit(..) does work, but from searching around, this doesn't seem like a good way of doing things. Most sites say it should be used "with care".

Originally posted by Ernest Friedman-Hill:
This line:

myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Arranges for a WindowEventListener to be attached to the JFrame which calls System.exit(0) when you close the window.

The original poster's program is a sort of hybrid thing which just throws up a few dialogs; when main() returns, the program won't exit by itself because the GUI thread (which is a non-daemon thread) is still running. He could just put System.exit(0) at the end of main().

Ah, I guess that explains it. But since it seems to be VM-dependent, I'm wondering if the VM's which require it are the ones with bugs, or if it's those which don't require it?

What I noticed: if I use Sun's Java 1.5 SDK, it exits even without System.exit(). If I use GNU's GCJ, it doesn't (i.e. it needs System.exit()).
[ April 02, 2007: Message edited by: LudoA ]
Ludo Aelbrecht
Greenhorn

Joined: Oct 30, 2006
Posts: 5
Originally posted by sven studde:


In java, you can declare and create a new array in one line like this:

int[] nums = new int[10];

But, that is a two part operation, which can be broken up into its constituent parts:

int[] nums;
nums = new int[10];

The first line declares a variable that can refer to an int array. The second line creates an array and sets nums to refer to the array. However, you don't have to write the second line immediately after the first. In other words, you can create the variable, but not assign anything to it until later:

int[] nums;
...
...
nums = new int[5];

In your case, to make a Players array available to the whole class, you can declare a data member for your class:

private Players[] p;

and then sometime later, like in an initPlayers() method, you can create a Players array and set p to refer to it:

p = new Players[5];

(Note: you might want to set p=null in the constructor for the class, so that you at least initialze p when p is created.)

Great, that's exactly what I need! Thanks a lot. I've gotta say I find the new() stuff a bit confusing, though your explanation helps in understanding it.
I'm curious, why wouldn't I want to initialize p, if I'm sure I'll do it later? Just in case I change the program later, and I try to use p when it's not initialized yet, to avoid a crash? If so, won't it crash anyway since p is null?


Originally posted by sven studde:
Additionally, which is something I didn't know you could do in java, you can make the size of the array a variable:

p = new Players[numPlayers];

Therefore, you can set the value of the numPlayers variable equal to the user input from the JOptionsPane.

So when the value of numPlayers changes, the array is automatically adapted? Seems weird (though useful), will try it out. Isn't it possible in Java to create some kind of dynamic array of which the length isn't known in the beginning, and you can add elements as you want? I think I've seen that before in another language (VB I think).
Ludo Aelbrecht
Greenhorn

Joined: Oct 30, 2006
Posts: 5
Originally posted by sven studde:

Well, you can go too far with that as well. For instance, I think this is a case of going too far:

[...]

You can always wrap every java function in a function of your own, but that just creates needless overhead.

Yes I see what you mean, I kind of overdid it there

Originally posted by Garrett Rowe:
Except by wrapping the method it leaves open the possibility that a different implementation may be used. Perhaps in the future you might decide to use an implementation of a Mersenne Twister instead of java.util.Random to generate random numbers, or for testing you might want to create a mock implementation which overrides the createRandomNumber() method to return a non-random predetermined number. You then only have to change a single method implementation and leave the rest of your code untouched.

That was my line of thinking when I wrote it, or that maybe I'd want to use that random-number method somewhere else in my app.
I guess it's not always very clear when things should be broken down or not. Though in this specific case, it was kind of overkill

Thanks for the suggestions, greatly appreciated.
[ April 02, 2007: Message edited by: LudoA ]
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3169
    
  10
Originally posted by Ludo Aelbrecht:

So when the value of numPlayers changes, the array is automatically adapted? Seems weird (though useful), will try it out. Isn't it possible in Java to create some kind of dynamic array of which the length isn't known in the beginning, and you can add elements as you want? I think I've seen that before in another language (VB I think).


The size of an array, once created, is fixed.
will create an array whose size is whatever the value of numPlayers is at this point in time. If the value of numPlayers changes later in the code the size of the array will not change.
If you want something like an array that can vary it's size, use an ArrayList.


Joanne
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Ludo Aelbrecht:

Ah, I guess that explains it. But since it seems to be VM-dependent, I'm wondering if the VM's which require it are the ones with bugs, or if it's those which don't require it?

What I noticed: if I use Sun's Java 1.5 SDK, it exits even without System.exit(). If I use GNU's GCJ, it doesn't (i.e. it needs System.exit()).

[ October 31, 2006: Message edited by: Ludo Aelbrecht ]


It's not necessarily a bug in either case. AWT has had problems in terms of both the design and bugs in implementation for years. Prior to 1.4 it would never close, since 1.4 it can close when certain requirements are met. One of the requirements is that there be no displayable components. Unfortunately it's rather easy to have displayable components you don't know about, especially since implementations like JOptionPane make use of a shared frame when you neglect to pass it a parent. Then there's the whole issue of peers and native events which are by their very nature implementation and OS dependent.

If you want your application to close you better make sure you explicitly take the steps needed to do so. Don't rely on AWT to successfully clean up everything for you and let the EDT die because it's too easy to prevent and too often is.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: app doesn't exit because of JOptionPane
 
Similar Threads
Head First Java Book, Chapter 2
Exceptation in thread "main" java.lang.NoSuchMethodError: main
Compile Errors - Head First - GuessGame
Please Help with Guessing Game (Head First Java)
Head First Java Ch. 2 Compile error