wood burning stoves 2.0*
The moose likes Beginning Java and the fly likes how do i pass some time? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "how do i pass some time?" Watch "how do i pass some time?" New topic
Author

how do i pass some time?

Ryu Eda
Greenhorn

Joined: Jul 11, 2006
Posts: 6
I have a Swing GUI thing going on that is set so that it awaits input from the user [ theres an output textbox and an input textbox ]. Problem is, i had no idea how to make it sit there and wait for the user to enter one of the given text command choices. So i went did a bunch of stuff and settled for making a new thread that enters a
public String getInput{
while(true){
if (stoplooping){break;}
}
return yummyInput;
}
kind of thing. basically looping forever untill the actionevent for the textbox in the GUI thread goes off signalling that input has been entered and sticking that text into "yummyInput" and finishing by setting stoplooping to true, so that the loop breaks out.
I have no idea how effective/efficient this method is, but i did notice that it puts a strain on the cpu to have something like this running.
Another case is in the program's Main, i have it go through various steps, but at one point would like it to pause untill a previous step is finished [ that previous step is GUI related and creates its own thread by itself ] this too im using an infinite while loop to keep on hold untill the user is done dealing with the previous GUI window.
Now, im pretty much a beginner, and most of the stuff i mentioned here like the GUI and the threading, im just experimenting with and dont know much about, i thought maybe i could try putting a thread on hold with wait, but i couldnt really get it to work.

So, my question is, whats a good way to pass time in situations like this?

My goal is to make the window act sort of like a command prompt window, sitting there doing nothing untill the user types in some sort of command that it deals with and then goes back to doing nothing.

Thanks
Mike Noel
Ranch Hand

Joined: Dec 15, 2005
Posts: 108
The nice thing about GUI programming with Swing is that there is a built in event loop that does just what you want already. This event loop just sits there doing nothing until the user does specific actions. It sounds like this is what you want.

It also sounds like you are re-inventing the wheel here and creating your own little event loops (but they aren't nearly as friendly as the built-in loop).

I suggest you read up a bit on the MVC architecture. I think you will find it very helpful and inspiring. It sounds like you're already thinking about the right things and you would benifit from reading what other people have already figured out on this.

The Swing Tutorial (http://java.sun.com/docs/books/tutorial/uiswing/index.html) might do the trick for you but it looks like that assumes you already understand the concepts behind MVC. It might be worth a look though.

_M_


Mike Noel
Ryu Eda
Greenhorn

Joined: Jul 11, 2006
Posts: 6
Will do, thanks
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Another thing you should do is to look critically at applications that you use all the time. Text editors, web applications, whatever you use. They were written by programmers just like you (only with a bit more experience), and you can write applications just like them.

So in your example where you are waiting for the user to enter something in a text box, you will notice that other people handle that by having not only a text box, but also a button labelled "Submit" (or something like that). Then your program just has to react when the button is pressed. You'll find out how to do that in the tutorial.
Ryu Eda
Greenhorn

Joined: Jul 11, 2006
Posts: 6
regarding the submit button type thing, i understand but this program is trying to emulate a console type thing [ for example if you think of irc chat rooms, you can type whatever junk... or you can enter something like /join #w/e, ] a submit button, i think, should be basically the same as a JtextField firing an actionevent.

Anyway, i tried reading all that stuff on the MVC and eventthreads but i couldnt really figure out a solution to my problem from that, however i did figure out what my problem was anyway from a threading article.

For anyone who faces this problem, the answer seems to be using

try { Thread.sleep(25); }
catch (InterruptedException e) { }

using some sort of small value for sleep so that instead of trying to loop as many times as it can at every moment, thus eating some crazy cpu power, it only loops once every 25 milliseconds, which apparently is really rarely for a computer since it dropped cpu usage from 80% to 3%, and it doesnt really seem to have any noticeable effect on GUI responsiveness

thanks for the help guys
[ July 11, 2006: Message edited by: Ryu Eda ]
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
It's rarely necessary to sleep in a loop like that. I'm pretty sure we can find another solution for both of your scenarios.

For the user input, you need to get comfortable with giving control to the UI. While you're waiting for input, NO application code runs in any thread. It all just sits there waiting for something to happen. When the user hits a keystroke or a submit button the Swing component calls a listener and the listener runs some interesting response.

If you spawn another thread and need to know when it finishes you can work with Thread.join(). If you need to know when the other thread reaches a certain point without finishing it may be a simple callback or something with Object.wait() and Object.notify().

Show us a little code around one of those scenarios and we can work together to get you out of that looping mode.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Ryu Eda:
regarding the submit button type thing, i understand but this program is trying to emulate a console type thing [ for example if you think of irc chat rooms, you can type whatever junk... or you can enter something like /join #w/e, ] a submit button, i think, should be basically the same as a JtextField firing an actionevent.


For your purposes this is probably true. This is an ideal case where you could register an ActionListener, indeed even the same instance no less, with both a JButton and a JTextField. Whenever the JButton fires an ActionEvent by calling actionPerformed() on your listener you respond the same way as if the JTextField did the same thing. Consequently your application would respond in an identical manner both to clicking the button and to the user doing something like hitting enter in the JTextField.

Originally posted by Ryu Eda:

Anyway, i tried reading all that stuff on the MVC and eventthreads but i couldnt really figure out a solution to my problem from that, however i did figure out what my problem was anyway from a threading article.

For anyone who faces this problem, the answer seems to be using

try { Thread.sleep(25); }
catch (InterruptedException e) { }

using some sort of small value for sleep so that instead of trying to loop as many times as it can at every moment, thus eating some crazy cpu power, it only loops once every 25 milliseconds, which apparently is really rarely for a computer since it dropped cpu usage from 80% to 3%, and it doesnt really seem to have any noticeable effect on GUI responsiveness

thanks for the help guys

[ July 11, 2006: Message edited by: Ryu Eda ]


Unfortunately you're still ignoring the larger design issue. You shouldn't need to be doing this and the fact that you are almost certainly indicates a massive design flaw. What makes you think you need to loop to begin with? You should be responding to the action by using an ActionListener, not by using an infinite loop in a separate thread to poll it.
Ryu Eda
Greenhorn

Joined: Jul 11, 2006
Posts: 6
For the user input, you need to get comfortable with giving control to the UI. While you're waiting for input, NO application code runs in any thread. It all just sits there waiting for something to happen. When the user hits a keystroke or a submit button the Swing component calls a listener and the listener runs some interesting response.


This sounds about right but im not really sure how to do that. basically an example situation is, im trying to emulate the unix terminal feature "man" that gives a really long description about something. I have a gui with an output window, and an input textbox with a listener. the listener's action is to check if whatever typed in was random text[which it will just echo in the output] or "man orangejuice", if its "man orangejuice" it spawns a new thread that begins by starting with a description of orangejuice that fills up the output window. This is where the pause is needed, to since the orangejuice thread wants input from the user to know whether to fill up the output with the 2nd page of text, or to simply cancel out [ end the orange juice thread ]. no application code is meant to run untill the orangejuice thread is given the input at which point the orangejuice thread will want to continue doing what it was doing.

Having a while loop sitting there polling constantly probably is a bad idea but atm im not really sure how to do anything more complicated.

If you need to know when the other thread reaches a certain point without finishing it may be a simple callback or something with Object.wait() and Object.notify().


This sounds like the solution i need, but im not quite sure how it works, despite having read many different articles on threading, this stuff is still confusing me.
My current assumption is that i want the orangejuice thread to call wait on itself? and then have the textbox listener do a notify on it, when the listener recieves an event?
Assuming thats how it goes, im not quite sure how to implement it, if anyone has or has seen any examples of code that does exactly this, i would appreciate it.
Mike Noel
Ranch Hand

Joined: Dec 15, 2005
Posts: 108
Looks like you're making progress but I really do think that you're heading down the wrong path here. Keep in mind that for many of us on this list we've done things like you're talking about dozens (or even hundreds) of times so we know where the pitfalls are. Of course you're free to ignore our advice but it will likely add extra complexity to your programmer both now and on future projects.

Ok. Soapbox done... :-)

For your output window have you considered a scrollbar instead of pages? That might work better for you because you could then put all of the text on one page and just let the scroll bar do the work. That may not work for your app. I'm just throwing it out there.

Assuming that the scrollbar won't work and you really do want paged text in an output window why not add a listener to the output window? Your app would just sit there doing nothing until the user pressed a button to continue or cancel. The button could be a GUI button that they clicked with the mouse or it could be a keystroke somewhere. Your listener will know what the keystroke was and could do various things (continue or cancel) based on the value of the keystroke.

I'm not sure that I understand the need for different threads. Especially if you're just going to do a join or wait. In those cases you're defeating the parallelism that the thread model gives you. The join and wait methods have their place with thread but they are used after the thread has done it's independant, parallel work.

Now if you want the output to "timeout" so that if the user doesn't enter a keystroke or hit a button after a specified amount of time you might want to look at the Timer class. This allows you to schedule a thread to be run in the future. If the user does provide input you can cancel the timer task.

There are ways to do what you want using the event listener methodology. It might not be the obvious or intuitive way for you to look at the problem right now but you can trust us. It is a good way to approach these sorts of problems and you will be well served to bite the bullet and learn it now.
Ryu Eda
Greenhorn

Joined: Jul 11, 2006
Posts: 6
Ok. The problem is, im trying to make something that functions like a chatroom/terminal. Basically allowing you to type anything in, and have the output show that, with a set list of commands [ a large number ] that you can type in. Eventually in the long run im hoping i can make this work over a network making something like a chat program [ i may have to redo everything but this is just for learning purposes anyway, the point of this project is to see what sort of ways i can control inputting, outputting, and changing data ]

Assuming that the scrollbar won't work and you really do want paged text in an output window why not add a listener to the output window? Your app would just sit there doing nothing until the user pressed a button to continue or cancel. The button could be a GUI button that they clicked with the mouse or it could be a keystroke somewhere. Your listener will know what the keystroke was and could do various things (continue or cancel) based on the value of the keystroke.


i understand the thing with buttons, its just that, if i wanted to stick a button for every single command/feature it will end up taking a lot of space and cluttering the gui.

Im not really sure what you mean by adding a listener to the output window, atm the output is a JTextArea and im weak on the whole listeners thing, besides obvious ones like button and combobox listeners.

Your app would just sit there doing nothing until the user pressed a button to continue or cancel

how do i make it sit there doing nothing? thats what my question is, while staying relevant to its previous actions [ how do i make it pause midway during outputs, awaiting a goahead ]

'm not sure that I understand the need for different threads. Especially if you're just going to do a join or wait. In those cases you're defeating the parallelism that the thread model gives you. The join and wait methods have their place with thread but they are used after the thread has done it's independant, parallel work.

Im not sure what you mean by most of that stuff since threads im having trouble with, but so far the need has been due to the fact that my code is something like

actionlisteneretc {
etc
if ((inputtedCommand == "man orangeJuice") && (orangeJuiceThreadRunning == false)){
OJThread theOJThread = new OJThread();
theOJThread.start();
}

without using a new thread, the actions executred due to the command "man orangeJuice" would freeze the GUI [ i thought due to being called from within the actionlistener's method which is on the eventthread? which having a new thread fixed ] when it reaches a point where a pause is required.

another example might be lets say a command "get my info" that might make it ask a series of questions that need to be answered, after each question it would need a pause for the input to come in, which would freeze the gui again

Scrollbars would work, but that wouldnt let me solve the problem im trying to solve [what i mean is, i already know how to do that so theres no point ]

The last thing is, while i put command recognition code for "man orangeJuice" inside the eventlistener, i want to keep command recognition for commands solely related to occurances once orangeJuice is running, within itself. What i mean is, i dont want to have 1000 different if statements inside my event listener for 1000 different commands.


If theres a way to do this using just eventListeners without mucking around with threading or using poll loops, id rather do that, i just have no idea how
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
We usually avoid posting complete solutions to problems, but I sense you need a solid example to play with. And I don't know Swing well enough to write good hints without actually trying them first, so I made the thing anyway. In fact, Swing experts may give us some major improvements.

Anyhow, this shows how we sit back and do nothing while waiting for user gestures. The main thread runs the constructor which builds the screen and exits. We're done for the time being.

This program shows a text area and waits for user input. While the user is typing our code does absolutely nothing. (Swing and the OS are doing plenty but not us.) But when the user hits the enter key, Swing calls the Action. This action just writes to the console, but a useful action could examine the contents of the text area, run a command and show the results, type another prompt to the user and wait for more input, etc.

In this example the button closes the window. You could choose to remove the enter key mapping and make the button run the action code. I don't know if your user would like that or not. Your choice.

As far as implementing thousands of commands without a giant if-else block, scroll down to the UML, OO, etc. forum and ask about Command pattern. You are absolutely right to want to avoid that, and the solution is slick, but too much for today's conversation.
Ryu Eda
Greenhorn

Joined: Jul 11, 2006
Posts: 6
Hmm, i didnt realize you could make new listeners out of other ones like that

Thanks
Mike Noel
Ranch Hand

Joined: Dec 15, 2005
Posts: 108
Yes, those are called anonymous classes. They are used a lot to create listeners (as shown so nicely above).
 
 
subject: how do i pass some time?
 
Similar Threads
How to stop a thread until a ActionEvent happend?
Can i make a program wait?
Error message
threads for GUI and command-line
HTML/JavaScript: user defined number of textboxes help